Bioyino - مجمع مقاييس موزعة وقابلة للتطوير

لذلك تقوم بجمع المقاييس. كما نحن. نقوم أيضًا بجمع المقاييس. وبطبيعة الحال، من الضروري للأعمال التجارية. سنتحدث اليوم عن الرابط الأول لنظام المراقبة الخاص بنا - خادم تجميع متوافق مع statsd com.bioyinoولماذا كتبناها ولماذا تخلينا عن بروبيك.

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير

من مقالاتنا السابقة (1, 2) يمكنك معرفة ذلك حتى وقت ما قمنا بجمع العلامات باستخدام بروبيك. إنه مكتوب بلغة C. من وجهة نظر الكود، فهو بسيط مثل المكونات (وهذا مهم عندما تريد المساهمة)، والأهم من ذلك، أنه يتعامل مع أحجامنا البالغة 2 مليون مقياس في الثانية (MPS) في الذروة دون أي مشاكل. تنص الوثائق على دعم 4 ملايين MPS بعلامة النجمة. هذا يعني أنك ستحصل على الرقم المذكور إذا قمت بتكوين الشبكة بشكل صحيح على نظام Linux. (لا نعرف عدد MPS الذي يمكنك الحصول عليه إذا تركت الشبكة كما هي). على الرغم من هذه المزايا، كان لدينا العديد من الشكاوى الخطيرة حول بروبيك.

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

المطالبة 2. دقة الحسابات. يجمع Brubeck إجمالي 65536 قيمة للتجميع. في حالتنا، بالنسبة لبعض المقاييس، خلال فترة التجميع (30 ثانية)، قد تصل قيم أكثر بكثير (1 في الذروة). ونتيجة لهذا أخذ العينات، تظهر القيم القصوى والدنيا عديمة الفائدة. على سبيل المثال، مثل هذا:

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير
كما كان

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير
كيف كان ينبغي أن يكون

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

وأخيرا، المطالبة X. في وقت كتابة هذا التقرير، نحن على استعداد لتقديمه إلى جميع تطبيقات الإحصائيات العاملة الأربعة عشر التي تمكنا من العثور عليها. لنتخيل أن بعض البنية التحتية الفردية قد نمت كثيرًا لدرجة أن قبول 14 ملايين MPS لم يعد كافيًا. أو حتى لو لم تنمو بعد، لكن المقاييس مهمة جدًا بالنسبة لك بالفعل، لدرجة أنه حتى الانخفاضات القصيرة لمدة 4-2 دقائق في الرسوم البيانية يمكن أن تصبح بالفعل حرجة وتتسبب في نوبات من الاكتئاب الذي لا يمكن التغلب عليه بين المديرين. وبما أن علاج الاكتئاب مهمة لا تحمد عقباها، فإن هناك حاجة إلى حلول تقنية.

أولاً، التسامح مع الخطأ، بحيث لا تتسبب مشكلة مفاجئة في الخادم في حدوث كارثة نفسية في المكتب. ثانيًا، التوسع لتكون قادرًا على قبول أكثر من 4 ملايين MPS، دون التعمق في مكدس شبكة Linux والنمو بهدوء "في العرض" إلى الحجم المطلوب.

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

إذا فكرت قليلاً في المشكلة وفي نفس الوقت قمت بحفر الثلج باستخدام مجرفة، فقد تتبادر إلى ذهنك الفكرة الواضحة التالية: أنت بحاجة إلى إحصائيات يمكنها العمل في الوضع الموزع. أي أنه ينفذ المزامنة بين العقد في الوقت والمقاييس. "بالطبع، ربما يكون هذا الحل موجودًا بالفعل،" قلنا وذهبنا إلى Google…. ولم يجدوا شيئًا. بعد الاطلاع على الوثائق الخاصة بالإحصائيات المختلفة (https://github.com/etsy/statsd/wiki#server-implementations اعتبارًا من 11.12.2017 ديسمبر XNUMX)، لم نعثر على أي شيء على الإطلاق. على ما يبدو، لم يواجه مطورو هذه الحلول ولا مستخدموها الكثير من المقاييس حتى الآن، وإلا فسيتوصلون بالتأكيد إلى شيء ما.

وبعد ذلك تذكرنا إحصائيات "اللعبة" - bioyino، التي تمت كتابتها في هاكاثون Just for Fun (تم إنشاء اسم المشروع بواسطة البرنامج النصي قبل بدء الهاكاثون) وأدركنا أننا بحاجة ماسة إلى إحصائياتنا الخاصة. لماذا؟

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

ماذا أكتب عليه؟ بالطبع، في الصدأ. لماذا؟

  • لأنه كان هناك بالفعل حل أولي،
  • لأن كاتب المقال كان يعرف Rust بالفعل في ذلك الوقت وكان حريصًا على كتابة شيء ما فيه للإنتاج مع إتاحة الفرصة لوضعه في مصدر مفتوح،
  • لأن اللغات التي تحتوي على GC ليست مناسبة لنا نظرًا لطبيعة حركة المرور المستلمة (في الوقت الفعلي تقريبًا) كما أن توقف GC مؤقتًا غير مقبول عمليًا،
  • لأنك تحتاج إلى أقصى قدر من الأداء مقارنة بـ C
  • لأن Rust يزودنا بالتزامن الجريء، وإذا بدأنا في كتابته بلغة C/C++، لكنا قد جمعنا المزيد من نقاط الضعف وتجاوزات المخزن المؤقت وظروف السباق والكلمات المخيفة الأخرى أكثر من brubeck.

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

مضى الوقت...

وأخيراً، وبعد عدة محاولات فاشلة، أصبحت النسخة العاملة الأولى جاهزة. ماذا حدث؟ هذا ما حدث.

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير

تتلقى كل عقدة مجموعة المقاييس الخاصة بها وتقوم بتجميعها، ولا تقوم بتجميع المقاييس لتلك الأنواع التي تتطلب مجموعتها الكاملة للتجميع النهائي. ترتبط العقد ببعضها البعض من خلال نوع من بروتوكول القفل الموزع، والذي يسمح لك بالاختيار من بينها الوحيد (هنا بكينا) الذي يستحق إرسال المقاييس إلى Great One. يتم حاليًا حل هذه المشكلة بواسطة قنصلولكن في المستقبل تمتد طموحات المؤلف إلى ملك تطبيق الطوافة، حيث سيكون الأكثر استحقاقًا، بالطبع، هو عقدة زعيم الإجماع. بالإضافة إلى الإجماع، ترسل العقد في كثير من الأحيان (مرة واحدة في الثانية افتراضيًا) إلى جيرانها تلك الأجزاء من المقاييس المجمعة مسبقًا والتي تمكنت من جمعها في تلك الثانية. اتضح أنه يتم الحفاظ على القياس والتسامح مع الخطأ - لا تزال كل عقدة تحتوي على مجموعة كاملة من المقاييس، ولكن يتم إرسال المقاييس مجمعة بالفعل، عبر TCP وترميزها في بروتوكول ثنائي، لذلك يتم تقليل تكاليف الازدواجية بشكل كبير مقارنة بـ UDP. على الرغم من العدد الكبير إلى حد ما من المقاييس الواردة، فإن التراكم يتطلب القليل جدًا من الذاكرة وحتى وحدة معالجة مركزية أقل. بالنسبة لمقاييسنا شديدة الانضغاط، فإن هذا لا يمثل سوى بضع عشرات من الميجابايت من البيانات. كمكافأة إضافية، لا نحصل على أي إعادة كتابة للبيانات غير الضرورية في الجرافيت، كما كان الحال مع بوربيك.

حزم UDP ذات المقاييس غير متوازنة بين العقد الموجودة على معدات الشبكة من خلال Round Robin البسيط. وبطبيعة الحال، لا تقوم أجهزة الشبكة بتحليل محتويات الحزم، وبالتالي يمكنها سحب أكثر من 4 ملايين حزمة في الثانية، ناهيك عن المقاييس التي لا تعرف عنها شيئًا على الإطلاق. إذا أخذنا في الاعتبار أن المقاييس لا تأتي واحدة تلو الأخرى في كل حزمة، فإننا لا نتوقع أي مشاكل في الأداء في هذا المكان. في حالة تعطل الخادم، يكتشف جهاز الشبكة هذه الحقيقة بسرعة (في غضون 1-2 ثانية) ويزيل الخادم المعطل من التدوير. ونتيجة لذلك، يمكن تشغيل وإيقاف العقد السلبية (أي غير الرائدة) دون ملاحظة عمليات السحب على الرسوم البيانية. الحد الأقصى الذي نخسره هو جزء من المقاييس التي جاءت في الثانية الأخيرة. سيؤدي الفقد/الإيقاف/التبديل المفاجئ للقائد إلى حدوث حالة شاذة بسيطة (الفاصل الزمني 30 ثانية لا يزال غير متزامن)، ولكن إذا كان هناك اتصال بين العقد، فيمكن تقليل هذه المشكلات، على سبيل المثال، عن طريق إرسال حزم المزامنة .

قليلا عن الهيكل الداخلي. التطبيق، بطبيعة الحال، متعدد الخيوط، ولكن بنية الخيوط تختلف عن تلك المستخدمة في بروبيك. المواضيع في brubeck هي نفسها - كل واحد منهم مسؤول عن جمع المعلومات وتجميعها. في bioyino، ينقسم العمال إلى مجموعتين: المسؤولون عن الشبكة والمسؤولون عن التجميع. يتيح لك هذا التقسيم إدارة التطبيق بشكل أكثر مرونة اعتمادًا على نوع المقاييس: عندما يكون التجميع المكثف مطلوبًا، يمكنك إضافة مجمعات، حيث يوجد الكثير من حركة مرور الشبكة، يمكنك إضافة عدد تدفقات الشبكة. في الوقت الحالي، نعمل على خوادمنا في 8 شبكات و4 تدفقات تجميعية.

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

حدثت المزيد من المشكلات أثناء التطوير بسبب جزء الشبكة المسؤول عن تلقي المقاييس. كان الهدف الرئيسي لفصل تدفقات الشبكة إلى كيانات منفصلة هو الرغبة في تقليل الوقت الذي يقضيه التدفق لا لقراءة البيانات من المقبس. سرعان ما اختفت الخيارات التي تستخدم UDP غير المتزامن وrecvmsg العادي: الأول يستهلك مساحة كبيرة جدًا من وحدة المعالجة المركزية (CPU) لمعالجة الأحداث، بينما يتطلب الثاني عددًا كبيرًا جدًا من مفاتيح تبديل السياق. ولذلك يتم استخدامه الآن com.recvmmsg مع مخازن مؤقتة كبيرة (والمخازن المؤقتة، أيها السادة الضباط، لا شيء بالنسبة لكم!). يتم حجز دعم UDP العادي للحالات الخفيفة التي لا تكون فيها هناك حاجة إلى رسالة recvmmsg. في وضع الرسائل المتعددة، من الممكن تحقيق الشيء الرئيسي: في الغالبية العظمى من الوقت، يقوم مؤشر ترابط الشبكة بتجميع قائمة انتظار نظام التشغيل - يقرأ البيانات من المقبس وينقلها إلى المخزن المؤقت لمساحة المستخدم، فقط في بعض الأحيان يتحول إلى إعطاء المخزن المؤقت المملوء إلى المجمعات. لا تتراكم قائمة الانتظار في المقبس عمليا، ولا يزيد عدد الحزم المسقطة عمليا.

لاحظ

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

وأخيرا، بعض الرسوم البيانية لمحبي الرسم البياني.

إحصائيات حول عدد المقاييس الواردة لكل خادم: أكثر من 2 مليون MPS.

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير

تعطيل إحدى العقد وإعادة توزيع المقاييس الواردة.

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير

إحصائيات حول المقاييس الصادرة: يتم دائمًا إرسال عقدة واحدة فقط - زعيم الغارة.

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير

إحصائيات تشغيل كل عقدة، مع مراعاة الأخطاء في وحدات النظام المختلفة.

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير

تفاصيل المقاييس الواردة (أسماء المقاييس مخفية).

Bioyino - مجمع مقاييس موزعة وقابلة للتطوير

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

بالطبع، نرحب بالجميع للمساعدة في تطوير المشروع: إنشاء العلاقات العامة، والقضايا، وسنقوم بالرد والتحسين، إن أمكن، وما إلى ذلك.

مع ما يقال، هذا كل ما في الأمر يا رفاق، اشتروا أفيالنا!



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

إضافة تعليق