نحن في X5 نعالج الكثير من البيانات في نظام ERP. من المعتقد أن لا أحد يعالجنا في SAP ERP و SAP BW في روسيا. ولكن هناك نقطة أخرى - عدد العمليات والحمل على هذا النظام يتزايد بسرعة. لمدة 3 سنوات كنا "ناضل" من أجل أداء الوزن الثقيل لتخطيط موارد المؤسسات ، وحصلنا على الكثير من المخاريط ، وما هي الطرق التي عولجوا بها ، كما نعلم تحت القص.

ERP X5
الآن X5 تدير أكثر من 13000 متجر. تمر معظم العمليات التجارية لكل منها عبر نظام ERP واحد. يمكن أن يحتوي كل متجر على ما يتراوح بين 3000 و 30،000 منتج ، مما يخلق مشاكل في التحميل على النظام ، لأنه تمر عمليات إعادة الحساب المنتظمة للأسعار وفقًا للترقيات والمتطلبات التشريعية وحساب تجديد المخزون. كل هذا أمر بالغ الأهمية ، وإذا لم يتم حسابه في الوقت الذي يتم فيه تسليم البضائع بالكمية التي سيتم تسليمها إلى المتجر غدًا أو السعر الذي يجب أن يكون على البضائع ، فلن يجد المشترون ما كانوا يبحثون عنه على الرفوف أو لن يتمكنوا من شراء البضائع بسعر العرض الحالي الأسهم. بشكل عام ، بالإضافة إلى المحاسبة عن المعاملات المالية ، فإن نظام ERP مسؤول عن الكثير في الحياة اليومية لكل متجر.
قليلا من خصائص الأداء لنظام تخطيط موارد المؤسسات. هيكلها كلاسيكي ، من ثلاثة مستويات مع عناصر موجهة نحو الخدمة: على رأسنا لدينا أكثر من 5000 عميل كثيف وتيرابايت من المعلومات تتدفق من المتاجر ومراكز التوزيع ، في طبقة التطبيق - SAP ABAP مع أكثر من 10000 عملية ، وأخيرا قاعدة بيانات أوراكل مع أكثر من 100 تيرابايت من البيانات. كل عملية ABAP عبارة عن جهاز ظاهري مشروط ينفذ منطق أعمال ABAP من خلال لهجتي DBSL و SQL الخاصة به ، والتخزين المؤقت ، وإدارة الذاكرة ، و ORM ، إلخ. كل يوم نحصل على أكثر من 15 تيرابايت من التغييرات في سجل قاعدة البيانات. مستوى التحميل 500000 طلب في الثانية.
هذه العمارة هي بيئة غير متجانسة. كل مكون من المكونات عبارة عن منصة مشتركة ، يمكننا نقلها إلى منصات مختلفة ، واختيار الأفضل منها ، إلخ.
حقيقة أن نظام تخطيط موارد المؤسسات هو تحت الحمل 24 ساعة في اليوم 365 يوما في السنة يضيف الوقود إلى النار. التوفر - 99.9 ٪ من الوقت على مدار السنة. وينقسم الحمل إلى ملامح ليلا ونهارا والحفاظ على المنزل في وقت الفراغ.
لكن هذا ليس كل شيء. يحتوي النظام على دورة إطلاق محكمة وضيقة. أنه يحمل أكثر من 2000 التغييرات دفعة سنويا. قد يكون هذا زرًا جديدًا وتغييرات جدية في منطق تطبيقات الأعمال.

ونتيجة لذلك ، إنه نظام كبير ومحمّل بدرجة كبيرة ، ولكنه في الوقت نفسه نظام مستقر وقابل للتنبؤ وجاهز للنمو يمكنه استضافة عشرات الآلاف من المتاجر. ولكن هذا لم يكن الحال دائما.
2014. نقطة التشعب
للغطس في المواد العملية تحتاج إلى العودة إلى عام 2014. ثم كانت هناك أصعب المهام لتحسين النظام. كان هناك حوالي 5000 متجر.
كان النظام في ذلك الوقت في مثل هذه الحالة حيث أن معظم العمليات الحرجة لم تكن قابلة للتطوير ولم تستجب بشكل كاف للحمل المتزايد (أي ظهور متاجر وسلع جديدة). بالإضافة إلى ذلك ، قبل عامين ، تم شراء Hi-End باهظة الثمن ، ولم تكن الترقية لبعض الوقت جزءًا من خططنا. علاوة على ذلك ، فإن العمليات في ERP كانت بالفعل على وشك انتهاك SLA. خلص البائع إلى أن الحمل على النظام غير قابل للتحجيم. لم يعرف أحد ما إذا كانت تستطيع تحمل ما لا يقل عن + 10٪ من الزيادة في الحمل. وكان من المخطط افتتاح ضعف عدد المتاجر في غضون ثلاث سنوات.
كان من المستحيل إطعام نظام ERP بالحديد الجديد ، ولن يساعد ذلك. لذلك ، أولاً وقبل كل شيء ، قررنا تضمين تقنية تحسين البرمجيات في دورة الإصدار واتباع القاعدة: نمو التحميل الخطي بما يتناسب مع نمو برامج تشغيل التحميل هو مفتاح قابلية التنبؤ وقابلية التوسع.
ما هي تقنية التحسين؟ هذه عملية دورية تنقسم إلى عدة مراحل:
- المراقبة (تحديد الاختناقات في النظام وتحديد كبار مستهلكي الموارد)
- تحليل (تحديد ملامح عمليات المستهلك ، وتحديد الهياكل ذات التأثير الأكبر وغير الخطي على الحمل)
- التنمية (تقليل تأثير الهياكل على الحمل ، وتحقيق الحمل الخطي)
- الاختبار في بيئة تقييم الجودة أو التنفيذ في بيئة إنتاجية
بعد ذلك ، تكررت الدورة.
في هذه العملية ، أدركنا أن أدوات المراقبة الحالية لا تسمح لنا بالتعرف بسرعة على كبار المستهلكين ، وتحديد الاختناقات والعمليات المتعطشة للموارد. لذلك ، من أجل الإسراع ، جربنا أدوات البحث المرنة و Grafana. للقيام بذلك ، قاموا بتطوير مجمعين قاموا ، من أدوات المراقبة القياسية في Oracle / SAP / AIX / Linux ، بنقل المقاييس إلى بحث مرن والسماح بمراقبة صحة النظام في الوقت الحقيقي. بالإضافة إلى ذلك ، قاموا بإثراء المراقبة بمقاييسها المخصصة ، على سبيل المثال ، وقت الاستجابة والإنتاجية لمكونات SAP محددة أو تخطيط ملفات تعريف التحميل للعمليات التجارية.

رمز وعملية التحسين
بادئ ذي بدء ، لضمان تأثير أقل من الاختناقات على السرعة ، ضمنت أنها توفر أكثر سلاسة من الحمل للنظام.
معظم عمليات الأعمال في نظام ERP الخاص بنا ، على سبيل المثال ، مثل التخطيط المعتاد للتسعير أو تجديد المخزون ، هي معالجة متسلسلة خطوة بخطوة لكمية كبيرة من البيانات (لجميع السلع وجميع المتاجر). لتنفيذ المعالجة في إطار هذه المهام الصعبة ، قمنا في وقت من الأوقات بتطوير جهاز إرسال المعالجة بالتوازي مع الدُفعة (يشار إليه فيما يلي باسم "جدولة التحميل"). في هذه الحالة ، في شكل حزمة ، يتم تقديم خطوة معالجة منفصلة يتم تنفيذها لمتجر منفصل.
في البداية ، كان منطق برنامج الجدولة بحيث تم أولاً تنفيذ حزم مرحلة المعالجة الأولى لجميع المتاجر ، ثم حزم المرحلة الثانية ، إلخ. أي أن النظام أجرى في وقت واحد العمليات التي خلقت نفس النوع من التحميل وتسببت في تدهور بعض الموارد (الإدخال / الإخراج إلى قاعدة البيانات أو وحدة المعالجة المركزية على خوادم التطبيقات ، وما إلى ذلك).

أعادنا كتابة منطق برنامج الجدولة بحيث تشكلت سلسلة الحزم بشكل منفصل لكل متجر ، وأولوية إطلاق حزم جديدة تم بناؤها ليس على مراحل ، ولكن من خلال المتاجر.

نظرًا لاختلاف مدة الحزم الخاصة بالمتاجر المختلفة والعدد الكبير المنظم من العمليات المنفذة في وقت واحد في إطار مهام برنامج جدولة التحميل ، فقد حققنا التنفيذ المتزامن للعمليات غير المتجانسة ، وتحميل أكثر سلاسة وإزالة بعض الاختناقات.
ثم بدأوا في تحسين التصاميم الفردية. تمت مراجعة كل حزمة فردية وتصميماتها وتجميعها التصميمات غير المثلى والنهج المطبقة لتحسينها. بعد ذلك ، تم تضمين هذه الطرق في لوائح المطور من أجل منع نمو الحمل غير المرغوب فيه أثناء تطوير النظام. البعض منهم:
- الحمل الزائد على وحدة المعالجة المركزية لخوادم التطبيقات (غالبًا ما يتم إنشاؤه بواسطة خوارزميات غير خطية في رمز البرنامج ، على سبيل المثال ، البحث الخطي القديم الجيد في حلقات أو خوارزميات البحث غير الخطية لتقاطعات مجموعات من العناصر المختلة ، إلخ ... تم معالجتها عن طريق استبدال الخوارزميات الخطية: استبدال الخطوط الخطية في الحلقات ببيانات ثنائية ؛ للبحث عن التقاطعات للمجموعات ، نستخدم خوارزميات خطية وعناصر ترتيب مسبق وما إلى ذلك)
- غالبًا ما تؤدي الاستدعاءات المتطابقة لقاعدة البيانات التي لها نفس الشروط داخل نفس العملية إلى استخدام وحدة المعالجة المركزية بشكل مفرط لقاعدة البيانات (يتم معالجتها عن طريق تخزين نتائج العينة الأولى في ذاكرة البرنامج مؤقتًا أو على مستوى خادم التطبيق واستخدام البيانات المخزنة مؤقتًا للعينات اللاحقة)
- طلبات الانضمام المتكرر (من الأفضل تنفيذها ، بالطبع ، على مستوى قاعدة البيانات ، ولكن في بعض الأحيان سمحنا لأنفسنا بتقسيمها إلى عينات بسيطة ، يتم تخزين نتائجه مؤقتًا ، ونقل منطق اللصق إلى التطبيق. )
- طلبات الانضمام الثقيلة مما أدى إلى الكثير من I / O
حول هذا الأخير بمزيد من التفاصيل. في هذه الحالة ، تم ترجمة نموذج البيانات إلى نموذج أقل طبيعية. والمثال الكلاسيكي هو مجموعة مختارة من المستندات المحاسبية لتاريخ محدد لمتجر فردي. العديد من الموظفين طلب ذلك. يخزن الجدول الرئيسي (جدول العناوين) تواريخ المستندات ، في جدول المواضع - المخزن والبضائع. الاستعلامات الأكثر شيوعًا هي اختيار جميع المستندات لمتجر معين في تاريخ محدد. مع هذا الطلب ، يعطي التصفية حسب التاريخ على جدول العناوين 500 ألف سجل ، والمرشح حسب المتجر - بنفس المقدار. في الوقت نفسه ، بعد الإلتصاق في متجر منفصل في التاريخ الصحيح ، لدينا 3 آلاف مصطلح. بغض النظر عن الجدول الذي نبدأ في تصفية البيانات واللصق منه ، نحصل دائمًا على الكثير من عمليات الإدخال / الإخراج غير المرغوب فيها.

يمكن تجنب ذلك عن طريق تقديم البيانات في شكل أقل طبيعية. في إحدى الحالات ، تم تكرار حقل التاريخ في جدول المواضع ، وتم ملؤه عند إنشاء المستندات ، وتم جمع المؤشرات للبحث السريع ، وتمت تصفيتها بالفعل وفقًا لجدول المواضع. وبالتالي ، بعد التضحية بالنفقات العامة الضئيلة لتخزين حقل جديد والفهارس ، قللنا عدد عمليات الإدخال / الإخراج الناتجة عن الاستعلامات التي تثير المشاكل عدة مرات.

2015. مشكلة خدمة واحدة
لمدة عام ونصف ، قمنا بعمل رائع لتحسين النظام ، فقد أصبح أكثر قابلية للتنبؤ. ومع ذلك ، ظلت خطط مضاعفة عدد المتاجر ذات صلة ، لذا فإن التحديات ما زالت تواجهنا.
على الطريق صادفنا العديد من الاختناقات. على سبيل المثال ، في نهاية عام 2015 ، أدركوا أنهم استقروا في أداء خدمة أساسية واحدة للمنصة. هذه خدمة قفل منطقي SAP ABAP. بسبب ذلك ، فإن النظام من الواضح أنه لن يقاوم نمو الحمل. تلوح في الأفق خسائر الأموال الكبيرة.
للتوضيح ، تتمثل مهمة الخدمة في نقل المعاملة المنطقية إلى مستوى خادم التطبيق. في ABAP ، يمكن أن تمر معاملة واحدة بعدة خطوات على سير عمل مختلف. من أجل أن تكتمل المعاملة ، هناك خدمة قفل والآليات ذات الصلة. تحدث عمليات القفل وفتح القفل بسرعة ، لكنها ذرية ، ولا يمكن فصلها. حدثت مشكلة في الإدخال / الإخراج المتزامن.
تسارعت الخدمة قليلاً بعد أن أصدر مطورو SAP تصحيحًا خاصًا ، وقمنا بتحويل الخدمة إلى جهاز آخر وعملنا على إعدادات النظام ، لكن هذا لم يكن كافياً. كان سقف خدمة جواز السفر حوالي 7 آلاف عملية في الثانية ، ولوقت طويل كنا بحاجة بالفعل إلى 10 آلاف عملية.
بعد اختبار الحمل الصناعي ، تبيّن أن الانحطاط غير خطي ، ومع ذلك فنحن على حدود أداء الخدمة أعلاه والذي يظهر فيه التدهور غير المقبول لنظام ERP بأكمله. أعطت المكالمات المتكررة للمطوّرين حكمًا مخيباً للآمال فقط - الخدمة تعمل بشكل صحيح ، نحن نطلب الكثير في بنية الحلول الحالية. حتى لو تعهدنا على الفور بإعادة تصميم بنية الحل بالكامل ، فسيتطلب الأمر منا عدة أشهر للحفاظ على قابلية تشغيل النظام الحالي.
أحد الخيارات الأولى لمحاولة إطالة عمر خدمة القفل هو تسريع الإدخال / الإخراج والكتابة إلى نظام الملفات. ماذا؟ تجارب مع بديل لـ AIX. نقل الخدمة إلى Linux على أقوى آلة تشغيل ، وفاز بالكثير من وقت الاستجابة. الخدمة مع نظام الملفات قيد التشغيل تتصرف كما هو الحال في Aix مع المعوقين. ثم قمنا بنقل هذا الرمز إلى أحد شفرات x86_64 وحصلنا على منحنى أداء منحدر بلطف أكثر من ذي قبل. بدا مضحكا.
يمكن افتراض أن المطورين على AIX و Linux قد فعلوا شيئًا مختلفًا في الاختبار الأخير ، لكن بنية المعالج كان لها أيضًا تأثير هنا.

ما كان الاستنتاج؟ تعتبر بعض الأنظمة الأساسية مناسبة بشكل مثالي لقواعد البيانات متعددة الخيوط ، مما يوفر كلاً من الأداء والتسامح مع الخطأ ، لكن المعالج على بنية مختلفة يمكنه التعامل بشكل أفضل مع مهام محددة. إذا كنت في بداية بناء حل للتخلي عن المنصات المشتركة ، يمكنك أن تخسر مساحة للمناورات في المستقبل.
ومع ذلك ، اكتشفنا هذه المشكلة وبدأت الخدمة في العمل بشكل أسرع 3-4 مرات ، وهو ما يكفي لتحقيق نمو طويل للغاية.
2016. DB DB عنق الزجاجة
بعد ستة أشهر حرفيًا ، بدأت المشكلات الغريبة تظهر في وحدة المعالجة المركزية في قاعدة البيانات. يبدو أنه من الواضح أنه مع زيادة الحمل ، يزداد استهلاك موارد المعالج. لكن نظام SysTime بدأ يستحوذ على معظمه ، وكان من الواضح أن هناك مشكلة في النواة. لقد بدأوا في فهم اختبارات الحمل الاصطناعية وأدركوا أن معدل إنتاجنا بلغ 300 ألف عملية في الثانية ، أي مليار طلب في الساعة ، ثم التدهور.
نتيجة لذلك ، توصلنا إلى أن الطلب المثالي هو طلب غير موجود. لقد وسعنا أسلوب التحسين الخاص بنا بطرق جديدة وأجرينا مراجعة لنظام ERP: بدأنا في البحث عن استفسارات ، على سبيل المثال ، بكفاءة منخفضة (100 ألف اختيار - نتيجة لـ 100 سطر أو صفر بشكل عام) - لإعادة الإعادة. إذا تعذر إزالة الطلبات "الفارغة" ، فدعهم يذهبون إلى "ذاكرة التخزين المؤقت السلبية" ، إذا كان ذلك مناسبًا. إذا تمت معالجة العديد من طلبات الحصول على نفس بيانات المنتج بشكل متوازٍ ، فدعهم يعذبون خادم التطبيق ، وليس قاعدة البيانات ، فنحن نقوم بتخزينه مؤقتًا. نقوم أيضًا "بتكبير" عدد كبير من الاستعلامات الفردية المتكررة على مفتاح ما في إطار عملية واحدة ، واستبدالها بمزيد من التحديدات النادرة في جزء من المفتاح. أو ، على سبيل المثال ، لتوزيع التحميل في سلسلة المعالجة ، يمكن تنفيذ خطوات مختلفة على خوادم تطبيقات مختلفة. هذا جيد ، لكن في المراحل المختلفة يمكنهم طلب نفس الشيء من القاعدة. ثم اترك الخطوة الأولى بعد البدء في جزء من ذاكرة التخزين المؤقت للتطبيق من الطلبات ، ويبقى هناك لإنهاء بقية السلسلة.

بمساعدة هذه الحيل ، فزنا قليلاً في كل مكان ، لكن في النهاية قمنا بتفريغ القاعدة بشكل خطير. جاء النظام إلى الحياة. وفي الوقت نفسه ، وصلنا إلى إيكس.
كشفت تجارب أخرى أن هناك سقفًا للأداء - مكالمات DataBase التي سبق ذكرها والتي تبلغ 300000 في الثانية. كان جذر المشكلة هو أداء واجهة الشبكة ، التي كان لها سقف - حوالي 300 ألف حزمة في الثانية الواحدة في اتجاه واحد. مع اقتراب السقف ، زاد وقت مكالمات النظام. كما اتضح فيما بعد ، كان أيضًا إرث مكدس شبكة kernel AIX.
بشكل عام ، لم نواجه أية مشكلات في زمن الانتقال ، كان جوهر الشبكة مثمرًا ، وتم تجميع جميع الحبال في قناة كبيرة غير قابلة للتدمير على واجهة واحدة. لقد توصلنا إلى حل بديل: قسمنا الشبكة بالكامل بين خوادم التطبيقات وقاعدة البيانات إلى مجموعات على واجهات مختلفة. نتيجة لذلك ، كل مجموعة من خوادم التطبيقات تتواصل مع قاعدة البيانات عبر واجهة منفصلة خاصة بها. تم تقليل الأداء الأقصى لكل واجهة بشكل طفيف ، لكن في المجموع قمنا برفع تردد الشبكة إلى مليون حزمة في الثانية في اتجاه واحد.
وتم إضافة مبدأ "أفضل طلب هو ذلك غير الموجود" إلى Talmud للمطورين ، بحيث يتم أخذ ذلك في الاعتبار عند كتابة التعليمات البرمجية.
2017. لايف للترقية
حسنًا ، المرحلة الأخيرة من استعادة نظامنا ، مرت في عام 2017. كل ما تبقى هو أن تعيش قليلاً حتى الترقية وكان من الضروري الاحتفاظ بجيش تحرير السودان من أجل لا شيء. تم تحسين الكود ، لكننا رأينا أنه كلما زاد الحمل على وحدة المعالجة المركزية لقاعدة البيانات ، كانت العمليات أبطأ ، على الرغم من أن هامش الاستخدام كان 10-20٪. في البداية ، تم تقدير أن 100 ٪ هو ضعف ما يصل إلى 50 ٪. وعندما يكون هناك احتياطي 10-20 ٪ ، وهذا هو 10-20 ٪. في الواقع ، عند الحمل فوق 67-80٪ ، زادت مدة المهام بشكل غير خطي ، أي قانون أمدل يعمل. كان للنظام حد موازٍ وعند تجاوزه ، وبمشاركة عدد متزايد من المعالجات في العمل ، انخفض أداء كل معالج فردي.
في ذلك الوقت ، استخدمنا 125 معالجًا فعليًا ، أو 500 معالجًا منطقيًا ، مع الأخذ في الاعتبار تعدد العمليات على مستوى AIX. ماذا تقترح؟ ترقية؟ حتى قبل انتهاء التنسيق ، كان من الضروري الصمود لعدة أشهر وعدم إسقاط جيش تحرير السودان.
في مرحلة ما ، أدركوا أن مقاييس استخدام المعالج التقليدية ليست ذات دلالة بالنسبة لنا - فهي لا تظهر البداية الفعلية للتدهور. لإجراء تقييم واقعي لصحة النظام ، بدأنا في استخدام المقياس المتكامل - نتيجة اختبار اصطناعي كمقياس لأداء معالج قاعدة البيانات. مرة واحدة في الدقيقة قاموا بإجراء اختبار اصطناعي ، وقاس مدته وعرضوا هذا المقياس على شاشاتنا. وكان رد فعلهم إذا ارتفع المتري فوق النقطة الحرجة المعلنة. لقد حملنا الحمولة لمخططي الأحمال لدينا قليلاً بحيث ظل في منطقة "أقصى عزم الدوران" في قاعدة البيانات.

ومع ذلك ، كان التحكم اليدوي غير فعال ، وكنا متعبا من الاستيقاظ في الليل. ثم أعدنا كتابة مخطط التحميل بحيث حصل على ملاحظات بشأن مقاييس الأداء الحالية. إذا تجاوزت المقاييس الحد الأصفر (انظر الصورة) ، فقد تم تجميد تخطيط الحزم ذات الأولوية المنخفضة وحصلت العمليات الحيوية فقط على الأولوية. وبالتالي ، تمكنا تلقائيًا من التحكم في شدة الحمل واستخدام الموارد بكفاءة. والشيء الأكثر إثارة للاهتمام هو أن الحفاظ على النظام في حدود 80 ٪ من الحمل ، في نفس المنطقة ذات الحد الأقصى لعزم الدوران ، حصلنا في النهاية على انخفاض في إجمالي الوقت لتنفيذ العمليات التجارية ، لأن بدأ كل موضوع للعمل بشكل أسرع.
بعض النصائح لأولئك الذين يعملون مع ERP محملة للغاية
- من المهم جدًا مراقبة أداء الأنظمة في بداية المشروع ، خاصةً بمقاييسها الخاصة.
- تأكد من زيادة خطية في الحمل بما يتناسب مع الزيادة في عدد برامج تشغيل التحميل (في حالتنا ، كانت هذه عبارة عن بضائع ومتاجر).
- إزالة الإنشاءات غير الخطية في التعليمات البرمجية ، استخدم التخزين المؤقت لإزالة استعلامات قاعدة البيانات متطابقة.
- إذا كنت بحاجة إلى نقل الحمل من وحدة المعالجة المركزية لقاعدة البيانات إلى وحدة المعالجة المركزية لخادم التطبيق ، فيمكنك اللجوء إلى تقسيم طلبات الانضمام إلى عينات بسيطة.
- بالنسبة لجميع التحسينات ، تذكر أن الطلب السريع جيد ، وأن الطلب السريع والمتكرر سيء في بعض الأحيان.
- حاول دائمًا البحث عن بيئة الحلول غير المتجانسة والاستفادة منها.
- جنبا إلى جنب مع مقاييس الأداء التقليدية ، استخدم مقياس متكامل يحدد بشكل فريد التدهور ؛ باستخدام هذا المقياس ، حدد منطقة "الحد الأقصى لعزم الدوران" في نظامك.
- توفير أدوات تخطيط الحمل مع آليات لمراقبة مقاييس الأداء الحالية وإدارة معدلات تدفق الحمل لاستخدام موارد النظام بكفاءة
نشكر منظمي Highload لإتاحة الفرصة لمشاركة هذه التجربة ليس فقط على Habré ، ولكن أيضًا على مرحلة الحدث الأكبر على الأنظمة المحملة للغاية.
ديمتري تسفيتكوف ، ألكساندر ليشوك ، خبراء SAP في # ITX5.بالمناسبة ، # ITX5 تبحث عن مستشارين في SAP.