في بعض الأحيان يكون المزيد أقل. عندما يؤدي تقليل الحمل إلى زيادة الكمون

كما في معظم المشاركات، هناك مشكلة في إحدى الخدمات الموزعة، دعنا نسمي هذه الخدمة Alvin. هذه المرة لم أكتشف المشكلة بنفسي، أبلغني الرجال من جانب العميل.

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

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

منذ أن قمت بالتدوين حول هذا الموضوع، ربما تكون قد اكتشفت بالفعل أن أرقامهم كانت صحيحة. لقد اختبرت عميلي الافتراضي مرارًا وتكرارًا، وكانت النتيجة نفسها: انخفاض عدد الطلبات لا يؤدي إلى زيادة زمن الاستجابة فحسب، بل يزيد أيضًا من عدد الطلبات ذات زمن استجابة يزيد عن 10 مللي ثانية. بمعنى آخر، إذا كان عند 40 ألف QPS، تجاوز حوالي 50 طلبًا في الثانية 50 مللي ثانية، فعند 1 ألف QPS كان هناك 100 طلب أعلى من 50 مللي ثانية في كل ثانية. المفارقة!

في بعض الأحيان يكون المزيد أقل. عندما يؤدي تقليل الحمل إلى زيادة الكمون

تضييق نطاق البحث

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

في بعض الأحيان يكون المزيد أقل. عندما يؤدي تقليل الحمل إلى زيادة الكمون

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

  1. مكالمة شبكة من العميل إلى ألفين.
  2. مكالمة شبكة من Alvin إلى مخزن البيانات.
  3. البحث على القرص في مخزن البيانات.
  4. مكالمة شبكة من مستودع البيانات إلى ألفين.
  5. مكالمة شبكة من ألفين إلى العميل.

دعونا نحاول شطب بعض النقاط.

تخزين البيانات ليس له علاقة به

أول شيء فعلته هو تحويل Alvin إلى خادم ping-ping الذي لا يعالج الطلبات. عندما يتلقى طلبا، يقوم بإرجاع استجابة فارغة. إذا انخفض زمن الوصول، فهذا يعني أن الخطأ في تطبيق Alvin أو مستودع البيانات ليس شيئًا غير معروف. في التجربة الأولى نحصل على الرسم البياني التالي:

في بعض الأحيان يكون المزيد أقل. عندما يؤدي تقليل الحمل إلى زيادة الكمون

كما ترون، لا يوجد أي تحسن عند استخدام خادم ping-ping. وهذا يعني أن مستودع البيانات لا يزيد من زمن الوصول، ويتم تقليص قائمة المشتبه بهم إلى النصف:

  1. مكالمة شبكة من العميل إلى ألفين.
  2. مكالمة شبكة من ألفين إلى العميل.

عظيم! القائمة تتقلص بسرعة. اعتقدت أنني قد عرفت السبب تقريبًا.

جي آر بي سي

حان الوقت الآن لتقديم لاعب جديد: جي آر بي سي. هذه مكتبة مفتوحة المصدر من Google للاتصالات الجارية RPC. رغم أن gRPC تم تحسينه جيدًا واستخدامه على نطاق واسع، وكانت هذه هي المرة الأولى التي أستخدمه فيها على نظام بهذا الحجم، وتوقعت أن يكون تنفيذي دون المستوى الأمثل - على أقل تقدير.

توفر gRPC في المكدس أدى إلى ظهور سؤال جديد: ربما يكون تنفيذي أو نفسي gRPC تسبب مشكلة الكمون؟ إضافة مشتبه به جديد إلى القائمة:

  1. العميل يدعو المكتبة gRPC
  2. مكتبة gRPC بإجراء مكالمة شبكة إلى المكتبة على العميل gRPC على الخادم
  3. مكتبة gRPC اتصالات ألفين (لا توجد عملية في حالة خادم بينج بونج)

لإعطائك فكرة عن شكل الكود، لا يختلف تطبيق عميلي/Alvin كثيرًا عن تطبيقات خادم العميل أمثلة غير متزامنة.

ملحوظة: القائمة أعلاه مبسطة بعض الشيء لأنها gRPC يجعل من الممكن استخدام نموذج الترابط (القالب؟) الخاص بك، والذي تتشابك فيه مكدس التنفيذ gRPC وتنفيذ المستخدم. ومن أجل التبسيط، سوف نلتزم بهذا النموذج.

التنميط سوف يصلح كل شيء

وبعد شطب مخازن البيانات، اعتقدت أنني قد انتهيت تقريبًا: "الآن أصبح الأمر سهلاً! دعونا نطبق الملف الشخصي ونكتشف أين يحدث التأخير. أنا معجب كبير بالتنميط الدقيق، لأن وحدات المعالجة المركزية (CPUs) سريعة جدًا وفي أغلب الأحيان لا تشكل عنق الزجاجة. تحدث معظم حالات التأخير عندما يتعين على المعالج التوقف عن المعالجة للقيام بشيء آخر. يقوم التنميط الدقيق لوحدة المعالجة المركزية بذلك: فهو يسجل كل شيء بدقة مفاتيح السياق ويوضح مكان حدوث التأخير.

أخذت أربعة ملفات تعريف: مع QPS مرتفع (زمن انتقال منخفض) ومع خادم بينج بونج مع QPS منخفض (زمن انتقال مرتفع)، سواء على جانب العميل أو على جانب الخادم. وفي حالة حدوث ذلك، أخذت أيضًا نموذجًا لملف تعريف المعالج. عند مقارنة الملفات الشخصية، عادةً ما أبحث عن مكدس مكالمات غير طبيعي. على سبيل المثال، على الجانب السيئ مع الكمون العالي هناك العديد من مفاتيح السياق (10 مرات أو أكثر). ولكن في حالتي، كان عدد مفاتيح السياق هو نفسه تقريبًا. مما أثار رعبي أنه لم يكن هناك شيء مهم هناك.

تصحيح الأخطاء الإضافية

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

ماذا إذا

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

كالعادة، بعد فوات الأوان يبدو أن كل شيء كان واضحا. لقد وضعت العميل على نفس الجهاز الذي يستخدمه Alvin - وأرسلت طلبًا إليه localhost. وذهبت الزيادة في الكمون!

في بعض الأحيان يكون المزيد أقل. عندما يؤدي تقليل الحمل إلى زيادة الكمون

حدث خطأ ما في الشبكة.

تعلم مهارات مهندس الشبكات

يجب أن أعترف: معرفتي بتقنيات الشبكات فظيعة، خاصة بالنظر إلى حقيقة أنني أعمل معهم كل يوم. لكن الشبكة كانت المشتبه به الرئيسي، وكنت بحاجة إلى تعلم كيفية تصحيح أخطائها.

ولحسن الحظ، فإن الإنترنت يحب أولئك الذين يريدون التعلم. بدا الجمع بين ping وtracert بمثابة بداية جيدة بما يكفي لتصحيح أخطاء النقل عبر الشبكة.

أولاً، أطلقت بي إس بينج إلى منفذ TCP الخاص بألفين. لقد استخدمت الإعدادات الافتراضية - لا شيء خاص. من بين أكثر من ألف إشارة، لم يتجاوز أي منها 10 مللي ثانية، باستثناء الإشارة الأولى للإحماء. وهذا يتعارض مع الزيادة الملحوظة في زمن الوصول بمقدار 50 مللي ثانية عند النسبة المئوية 99: هناك، لكل 100 طلب، كان من المفترض أن نرى طلبًا واحدًا تقريبًا بزمن وصول قدره 50 مللي ثانية.

ثم حاولت TRACERT: قد تكون هناك مشكلة في إحدى العقد على طول الطريق بين Alvin والعميل. لكن التتبع عاد خالي الوفاض.

لذلك لم يكن الكود الخاص بي أو تطبيق gRPC أو الشبكة هو الذي تسبب في التأخير. لقد بدأت أشعر بالقلق من أنني لن أفهم هذا أبدًا.

الآن ما هو نظام التشغيل الذي نحن عليه

gRPC يستخدم على نطاق واسع على Linux، ولكنه غريب على Windows. قررت أن أجرب تجربة، ونجحت: قمت بإنشاء جهاز Linux افتراضي، وقمت بتجميع Alvin لنظام التشغيل Linux، ونشرته.

في بعض الأحيان يكون المزيد أقل. عندما يؤدي تقليل الحمل إلى زيادة الكمون

وهذا ما حدث: لم يكن لدى خادم Linux ping-pong نفس التأخيرات مثل مضيف Windows مماثل، على الرغم من أن مصدر البيانات لم يكن مختلفًا. اتضح أن المشكلة تكمن في تطبيق gRPC لنظام التشغيل Windows.

خوارزمية ناجل

طوال هذا الوقت اعتقدت أنني أفتقد العلم gRPC. الآن أفهم ما هو عليه حقا gRPC علامة Windows مفقودة. لقد وجدت مكتبة RPC داخلية كنت واثقًا من أنها ستعمل بشكل جيد مع جميع مجموعات العلامات WINSOCK. ثم أضفت كل هذه العلامات إلى gRPC ونشرت Alvin على Windows، في خادم بينج بونج يعمل بنظام Windows!

في بعض الأحيان يكون المزيد أقل. عندما يؤدي تقليل الحمل إلى زيادة الكمون

تقريبا تم: بدأت في إزالة العلامات المضافة واحدة تلو الأخرى حتى عاد الانحدار حتى أتمكن من تحديد السبب. لقد كانت سيئة السمعة TCP_NODELAY، مفتاح خوارزمية Nagle.

خوارزمية ناجل يحاول تقليل عدد الحزم المرسلة عبر الشبكة عن طريق تأخير إرسال الرسائل حتى يتجاوز حجم الحزمة عددًا معينًا من البايتات. في حين أن هذا قد يكون جيدًا بالنسبة للمستخدم العادي، إلا أنه مدمر لخوادم الوقت الفعلي حيث أن نظام التشغيل سيؤخر بعض الرسائل، مما يتسبب في حدوث تأخيرات عند انخفاض QPS. ش gRPC تم تعيين هذه العلامة في تطبيق Linux لمآخذ توصيل TCP، ولكن ليس في Windows. انا هذا تصحيح.

اختتام

كان سبب زمن الوصول العالي عند QPS المنخفض هو تحسين نظام التشغيل. في الماضي، لم يكشف التوصيف عن زمن الوصول لأنه تم إجراؤه في وضع kernel وليس في وضع kernel وضع المستخدم. لا أعرف ما إذا كان من الممكن ملاحظة خوارزمية Nagle من خلال التقاطات ETW، ولكن سيكون الأمر مثيرًا للاهتمام.

أما بالنسبة لتجربة المضيف المحلي، فمن المحتمل أنها لم تمس رمز الشبكة الفعلي ولم تعمل خوارزمية Nagle، لذا اختفت مشكلات زمن الوصول عندما وصل العميل إلى ألفين من خلال المضيف المحلي.

في المرة القادمة التي ترى فيها زيادة في زمن الاستجابة مع انخفاض عدد الطلبات في الثانية، يجب أن تكون خوارزمية Nagle ضمن قائمة المشتبه بهم!

المصدر: www.habr.com

إضافة تعليق