200 تيرا بايت + مجموعة Elasticsearch

200 تيرا بايت + مجموعة Elasticsearch

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

قررنا في Odnoklassniki حل مشكلة إدارة السجل بمساعدة elasticsearch ، والآن نشارك خبرتنا مع Habr: حول الهندسة المعمارية والمزالق.

أنا بيوتر زايتسيف ، أعمل كمسؤول نظام في Odnoklassniki. قبل ذلك ، كان أيضًا مشرفًا ، وعمل مع Manticore Search و Sphinx search و Elasticsearch. ربما إذا ظهر… بحث آخر ، فمن المحتمل أن أعمل معه أيضًا. كما أنني أشارك في عدد من المشاريع مفتوحة المصدر على أساس تطوعي.

عندما جئت إلى Odnoklassniki ، قلت بتهور في المقابلة أنه يمكنني العمل مع Elasticsearch. بعد أن اعتدت على ذلك وقمت ببعض المهام البسيطة ، تم تكليفي بمهمة كبيرة لإصلاح نظام إدارة السجل الذي كان موجودًا في ذلك الوقت.

متطلبات

تمت صياغة متطلبات النظام على النحو التالي:

  • كان من المفترض استخدام Graylog كواجهة أمامية. نظرًا لأن الشركة كانت لديها بالفعل خبرة في استخدام هذا المنتج ، فقد عرفه المبرمجون والمختبرين ، فقد كان مألوفًا وملائمًا لهم.
  • حجم البيانات: في المتوسط ​​50-80 ألف رسالة في الثانية ، ولكن إذا انقطع شيء ما ، فإن حركة المرور لا تقتصر على أي شيء ، فيمكن أن تصل إلى 2-3 مليون سطر في الثانية
  • بعد أن ناقشنا مع العملاء متطلبات سرعة معالجة استعلامات البحث ، أدركنا أن النمط المعتاد لاستخدام مثل هذا النظام هو: يبحث الأشخاص عن سجلات التطبيق الخاصة بهم خلال اليومين الماضيين ولا يريدون الانتظار أكثر من ثانية لمدة نتيجة لاستعلام تمت صياغته.
  • أصر المسؤولون على أن النظام يمكن توسيعه بسهولة إذا لزم الأمر ، دون مطالبتهم بفهم عميق لكيفية عمله.
  • لذلك كانت مهمة الصيانة الوحيدة التي تحتاجها هذه الأنظمة بشكل دوري هي تغيير نوع من الأجهزة.
  • بالإضافة إلى ذلك ، تمتلك Odnoklassniki تقليدًا تقنيًا رائعًا: أي خدمة نطلقها يجب أن تتحمل عطلًا في مركز البيانات (مفاجئًا وغير مخطط له وبشكل مطلق في أي وقت).

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

الأربعاء

نحن نعمل على أربعة مراكز بيانات ، بينما يمكن تحديد موقع عقد بيانات Elasticsearch في ثلاثة فقط (لعدد من الأسباب غير الفنية).

يوجد في مراكز البيانات الأربعة هذه ما يقرب من 18 ألف مصدر مختلف للسجلات - قطع من الحديد ، وحاويات ، وآلات افتراضية.

ميزة مهمة: يتم إطلاق الكتلة في حاويات Podman ليس على الآلات المادية ، ولكن على منتج سحابة واحد خاص به. تضمن الحاويات نواتين مشابهة لـ 2 جيجا هرتز v2.0 مع القدرة على إعادة تدوير بقية النوى إذا كانت خاملة.

بعبارة أخرى:

200 تيرا بايت + مجموعة Elasticsearch

طوبولوجيا

النظرة العامة للحل رأيتها في البداية على النحو التالي:

  • يقف 3-4 VIPs خلف السجل A لنطاق Graylog ، هذا هو العنوان الذي يتم إرسال السجلات إليه.
  • كل VIP هو موازن LVS.
  • بعد ذلك ، تنتقل السجلات إلى بطارية Graylog ، ويتم نقل بعض البيانات بتنسيق GELF ، وبعضها بتنسيق سجل النظام.
  • ثم يتم كتابة كل هذا على دفعات كبيرة للبطارية من منسقي Elasticsearch.
  • وهم بدورهم يرسلون طلبات الكتابة والقراءة إلى عقد البيانات ذات الصلة.

200 تيرا بايت + مجموعة Elasticsearch

مفردات اللغة

ربما لا يفهم الجميع المصطلحات بالتفصيل ، لذلك أود أن أتناولها قليلاً.

هناك عدة أنواع من العقد في Elasticsearch - رئيسية ، منسقة ، عقدة بيانات. هناك نوعان آخران للتحويلات المختلفة للسجلات واتصال مجموعات مختلفة مع بعضها البعض ، لكننا استخدمنا فقط تلك المدرجة.

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

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

عقدة البيانات
يقوم بتخزين البيانات ، وتنفيذ استعلامات البحث والعمليات على القطع الموجودة عليها ، قادمة من الخارج.

جرايلوج
يشبه الأمر دمج Kibana مع Logstash في ELK stack. يجمع Graylog بين كل من واجهة المستخدم وخط أنابيب معالجة السجل. تحت غطاء المحرك ، يدير Graylog كل من Kafka و Zookeeper ، اللذين يوفران الاتصال بـ Graylog كمجموعة. يمكن لـ Graylog تخزين السجلات (Kafka) مؤقتًا في حالة عدم توفر Elasticsearch وتكرار طلبات القراءة والكتابة غير الناجحة وتجميع السجلات ووضع علامات عليها وفقًا لقواعد محددة. مثل Logstash ، يتمتع Graylog بوظيفة تعديل السلاسل قبل الكتابة إلى Elasticsearch.

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

بصريا يبدو كالتالي:

200 تيرا بايت + مجموعة Elasticsearch

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

مؤشرات

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

في الرسم البياني أعلاه ، هذا هو أدنى مستوى: عقد بيانات Elasticsearch.

الفهرس هو كيان افتراضي كبير يتكون من أجزاء Elasticsearch. كل جزء في حد ذاته ليس أكثر من مؤشر لوسين. ويتكون كل مؤشر Lucene بدوره من مقطع واحد أو أكثر.

200 تيرا بايت + مجموعة Elasticsearch

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

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

حددنا وقت التخزين في البداية بـ 30 يومًا.

يمكن تمثيل توزيع القطع بيانياً على النحو التالي:

200 تيرا بايت + مجموعة Elasticsearch

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

عندما نضيف جزء آخر ، فإنه ينتقل إلى مركز البيانات الثالث. وفي النهاية ، نحصل على مثل هذا الهيكل الذي يوفر إمكانية فقدان DC دون فقدان تناسق البيانات:

200 تيرا بايت + مجموعة Elasticsearch

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

يعود الفاصل الزمني لدوران الفهرس إلى الأسباب التالية:

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

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

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

نتيجة لذلك ، حصلنا على ذلك ، في المتوسط ​​، شظية تزن حوالي 20 غيغابايت ، وهناك 1 شظية لكل فهرس واحد. وفقًا لذلك ، إذا قمنا بتناوبهم كل 360 ساعة ، فسيكون لدينا 48 منهم. يحتوي كل فهرس على بيانات لمدة يومين.

مخططات لكتابة وقراءة البيانات

دعونا نرى كيف يتم تسجيل البيانات في هذا النظام.

لنفترض أن بعض الطلبات وصلت من Graylog إلى المنسق. على سبيل المثال ، نريد فهرسة 2-3 آلاف صف.

بعد أن تلقى المنسق طلبًا من Graylog ، يسأل السيد: "في طلب الفهرسة ، حددنا الفهرس على وجه التحديد ، لكن لم يتم تحديد الجزء الذي يكتب هذا فيه."

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

بعد ذلك ، يتم نسخ سجل المعاملات إلى نسخة طبق الأصل ، الموجودة بالفعل في مركز بيانات آخر.

200 تيرا بايت + مجموعة Elasticsearch

يصل طلب البحث من Graylog إلى المنسق. يعيد المنسق توجيهه حسب الفهرس ، بينما يوزع Elasticsearch الطلبات بين الأجزاء الأولية والنسخة المتماثلة وفقًا لمبدأ round-robin.

200 تيرا بايت + مجموعة Elasticsearch

تستجيب العقد التي يبلغ حجمها 180 بشكل غير متساو ، وأثناء استجابتها ، يقوم المنسق بتجميع المعلومات التي "بصقها" بالفعل في عقد البيانات الأسرع. بعد ذلك ، عندما تصل جميع المعلومات ، أو تم الوصول إلى المهلة المحددة للطلب ، فإنه يعطي كل شيء للعميل مباشرة.

يفي هذا النظام بأكمله ، في المتوسط ​​، بطلبات البحث لآخر 48 ساعة في 300-400 مللي ثانية ، باستثناء الطلبات التي تحتوي على حرف البدل الرائد.

الزهور باستخدام Elasticsearch: إعداد Java

200 تيرا بايت + مجموعة Elasticsearch

لجعل كل شيء يعمل بالطريقة التي أردناها في الأصل ، أمضينا وقتًا طويلاً جدًا في تصحيح مجموعة متنوعة من الأشياء في المجموعة.

كان الجزء الأول من المشكلات المكتشفة مرتبطًا بكيفية تكوين Java مسبقًا في Elasticsearch افتراضيًا.

مشكلة واحدة
لقد رأينا عددًا كبيرًا جدًا من التقارير التي لدينا على مستوى Lucene ، عندما تكون وظائف الخلفية قيد التشغيل ، تفشل عمليات دمج مقطع Lucene. في الوقت نفسه ، كان من الواضح في السجلات أن هذا كان خطأ OutOfMemoryError. من القياس عن بعد ، رأينا أن الورك كان حراً ، ولم يكن من الواضح سبب سقوط هذه العملية.

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

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

المشكلة الثانية
بعد 4-5 أيام من إطلاق الكتلة ، لاحظنا أن عُقد البيانات تبدأ بشكل دوري في التساقط من الكتلة وتدخلها بعد 10-20 ثانية.

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

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

كان الحل على النحو التالي: لقد حدنا من قدرة Java على استخدام الجزء الأكبر من الذاكرة خارج الكومة لهذه العمليات. لقد حددناها بـ 16 جيجا بايت (-XX: MaxDirectMemorySize = 16g) ، مما يضمن استدعاء GC الصريح في كثير من الأحيان ، والعمل بشكل أسرع ، وبالتالي التوقف عن زعزعة استقرار المجموعة.

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

عندما قمنا بتكوين العمل باستخدام الفهارس ، اخترنا mmapfs من أجل تقليل وقت البحث على شظايا جديدة ذات تجزئة عالية. كان هذا خطأ فادحًا إلى حد ما ، لأنه عند استخدام mmapfs ، يتم تعيين الملف في ذاكرة الوصول العشوائي ، ثم نعمل مع الملف المعين. لهذا السبب ، اتضح أنه عندما يحاول GC إيقاف الخيوط في التطبيق ، نذهب إلى نقطة آمنة لفترة طويلة جدًا ، وفي الطريق إليه ، يتوقف التطبيق عن الاستجابة لطلبات المعالج حول ما إذا كان على قيد الحياة . وفقًا لذلك ، يعتقد السيد أن العقدة لم تعد موجودة في مجموعتنا. بعد ذلك ، بعد 5-10 ثوانٍ ، يعمل مجمع القمامة ، تعود العقدة إلى الحياة ، وتدخل الكتلة مرة أخرى وتبدأ في تهيئة الأجزاء. كل هذا يشبه إلى حد كبير "الإنتاج الذي نستحقه" ولم يكن مناسبًا لأي شيء جاد.

للتخلص من هذا السلوك ، قمنا أولاً بالتبديل إلى niofs القياسية ، وبعد ذلك ، عندما انتقلنا من الإصدار الخامس من Elastic إلى الإصدار السادس ، جربنا hybridfs ، حيث لم يتم تكرار هذه المشكلة. يمكنك قراءة المزيد عن أنواع التخزين هنا.

المشكلة الرابعة
ثم كانت هناك مشكلة مسلية أخرى عالجناها لفترة طويلة قياسية. أمسكنا بها لمدة 2-3 أشهر ، لأن نمطها كان غير مفهوم على الإطلاق.

في بعض الأحيان ، كان منسقونا يذهبون إلى Full GC ، عادة في مكان ما في فترة ما بعد الظهر ، ولم يعدوا من هناك أبدًا. في الوقت نفسه ، عند تسجيل تأخير GC ، بدا الأمر كما يلي: كل شيء يسير على ما يرام بالنسبة لنا ، حسنًا ، حسنًا ، ثم مرة واحدة - وكل شيء سيء بشكل حاد.

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

نتيجة لذلك ، اتضح أنه في الوقت الذي يقوم فيه بعض المستخدمين بإطلاق طلب ضخم ، ويصطدم بمنسق Elasticsearch معين ، تستجيب بعض العقد لفترة أطول من غيرها.

وبينما ينتظر المنسق استجابة جميع العقد ، فإنه يجمع في نفسه النتائج المرسلة من العقد التي استجابت بالفعل. بالنسبة إلى GC ، هذا يعني أن نمط استخدام الورك لدينا يتغير بسرعة كبيرة. ولا يمكن لـ GC التي استخدمناها التعامل مع هذه المهمة.

الإصلاح الوحيد الذي وجدناه لتغيير سلوك الكتلة في هذه الحالة هو الترحيل إلى JDK13 واستخدام أداة تجميع القمامة Shenandoah. أدى هذا إلى حل المشكلة ، توقف منسقونا عن السقوط.

هذا هو المكان الذي انتهت فيه مشاكل Java وبدأت مشاكل النطاق الترددي.

"التوت" مع Elasticsearch: الإنتاجية

200 تيرا بايت + مجموعة Elasticsearch

تعني مشكلات الإنتاجية أن المجموعة الخاصة بنا مستقرة ، ولكن في ذروة عدد المستندات المفهرسة وفي وقت المناورات ، يكون الأداء غير كافٍ.

العَرَض الأول الذي واجهته: أثناء نوع من "الانفجارات" في الإنتاج ، عندما يتم إنشاء عدد كبير جدًا من السجلات بشكل مفاجئ ، غالبًا ما يومض خطأ فهرسة es_rejected_execution في Graylog.

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

بالطبع ، ذهبنا إلى تحريف هذه القيمة واكتشفنا ما يلي: على وجه التحديد ، في إعدادنا ، يتم تخزين ما يصل إلى 300 طلب بشكل جيد تمامًا ، والقيمة الأكبر محفوفة بحقيقة أننا نطير بعيدًا مرة أخرى إلى Full GC.

بالإضافة إلى ذلك ، نظرًا لأن هذه مجموعات من الرسائل تصل ضمن طلب واحد ، فقد كان من الضروري أيضًا تعديل Graylog بحيث لا يكتب كثيرًا وعلى دفعات صغيرة ، ولكن على دفعات ضخمة أو مرة كل 3 ثوانٍ إذا كانت المجموعة لا تزال غير ممتلئة . في هذه الحالة ، اتضح أن المعلومات التي نكتبها في Elasticsearch تصبح متاحة ليس بعد ثانيتين ، ولكن بعد خمس (وهو ما يناسبنا جيدًا) ، ولكن عدد عمليات الاسترداد التي يجب القيام بها لدفع حزمة كبيرة من المعلومات النقصان.

هذا مهم بشكل خاص في تلك اللحظات التي يتعطل فيها شيء ما في مكان ما ويبلغ عن ذلك بشدة ، حتى لا تتعرض لمرونة غير مرغوب فيها تمامًا ، وبعد مرور بعض الوقت - عُقد Graylog التي لا تعمل بسبب انسداد المخازن المؤقتة.

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

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

ولكن يمكن التحايل على هذا جزئيًا نظرًا لحقيقة أنه في الإصدارات السادسة من Elasticsearch ظهرت خوارزمية تسمح لك بتوزيع الطلبات بين عقد البيانات ذات الصلة وليس وفقًا لمبدأ round-robin العشوائي (الحاوية التي تفهرس وتحتفظ بالجزء الأساسي يمكن أن يكون مشغولًا جدًا ، فلن تكون هناك طريقة للاستجابة بسرعة) ، ولكن لتوجيه هذا الطلب إلى حاوية أقل تحميلًا مع نسخة متماثلة ، والتي ستستجيب بشكل أسرع. بعبارة أخرى ، انتهى بنا الأمر باستخدام use_adaptive_replica_selection: true.

تبدأ صورة القراءة بالشكل التالي:

200 تيرا بايت + مجموعة Elasticsearch

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

أخيرًا ، كانت المشكلة الرئيسية هي الإزالة غير المؤلمة لمركز البيانات.

ما أردناه من الكتلة مباشرة بعد فقدان الاتصال بواحد DC:

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

كما اتضح ، أردنا شيئًا مثل هذا:

200 تيرا بايت + مجموعة Elasticsearch

وحصلت على ما يلي:

200 تيرا بايت + مجموعة Elasticsearch

كيف حدث هذا؟

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

لماذا؟

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

في وقت سحب أحد مراكز البيانات ، اتضح أن جميع عُقد البيانات في مراكز البيانات الباقية اعتبرت أن من واجبها إبلاغ المعلم "لقد فقدنا مثل هذه القطع وكذا وكذا عقد البيانات".

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

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

لقد أجرينا القياسات ، وقبل الإصدار 6.4.0 ، حيث تم إصلاحه ، كان يكفينا أن نسحب في نفس الوقت 10 فقط من أصل 360 عقدة بيانات من أجل وضع الكتلة بالكامل.

بدا الأمر كالتالي:

200 تيرا بايت + مجموعة Elasticsearch

بعد الإصدار 6.4.0 ، حيث تم إصلاح هذا الخطأ الغريب ، توقفت عقد البيانات عن قتل السيد. لكنها لم تجعله أكثر ذكاءً. وهي: عندما نخرج 2 أو 3 أو 10 (أي عدد غير واحد) من عقد البيانات ، يتلقى المعلم بعض الرسائل الأولى التي تقول إن العقدة A قد غادرت ، ويحاول إخبار العقدة B ، والعقدة C ، والعقدة D.

وفي الوقت الحالي ، لا يمكن التعامل مع هذا إلا من خلال تحديد مهلة لمحاولات إخبار شخص ما بشيء ما ، يساوي في مكان ما حوالي 20-30 ثانية ، وبالتالي التحكم في سرعة سحب مركز البيانات من المجموعة.

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

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

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

نتيجة لذلك ، تستغرق عملية سحب مركز البيانات اليوم حوالي 5 دقائق في ساعة الذروة. لمثل هذا العملاق الكبير والخرق ، هذه نتيجة جيدة جدًا.

ونتيجة لذلك توصلنا إلى الحل التالي:

  • لدينا 360 عقدة بيانات مع أقراص 700 غيغابايت.
  • 60 منسق لتوجيه حركة المرور على نفس عقد البيانات هذه.
  • 40 معلمًا تركناه كنوع من الإرث من وقت الإصدارات قبل 6.4.0 - من أجل البقاء على قيد الحياة بعد سحب مركز البيانات ، كنا مستعدين عقليًا لفقد العديد من الأجهزة من أجل ضمان النصاب القانوني للماجستير حتى في أسوأ سيناريو
  • تستند أي محاولات لدمج الأدوار في حاوية واحدة معنا إلى حقيقة أن العقدة تعطلت عاجلاً أم آجلاً تحت الحمل.
  • تستخدم المجموعة بأكملها heap.size يساوي 31 غيغابايت: أدت جميع محاولات تقليل الحجم إلى حقيقة أن استعلامات البحث المكثفة باستخدام حرف بدل رئيسي إما قتلت بعض العقد أو قتلت قاطع الدائرة في Elasticsearch نفسها.
  • بالإضافة إلى ذلك ، لضمان أداء البحث ، حاولنا الحفاظ على عدد الكائنات في المجموعة صغيرًا قدر الإمكان من أجل معالجة أقل عدد ممكن من الأحداث في عنق الزجاجة الذي وصلنا إليه في المعالج.

آخر شيء عن المراقبة

لكي يعمل كل هذا على النحو المنشود ، نراقب ما يلي:

  • تبلغ كل عقدة بيانات إلى السحابة الخاصة بنا أنها موجودة ، وهناك أجزاء كذا وكذا عليها. عندما نطفئ شيئًا ما في مكان ما ، تبلغ الكتلة بعد 2-3 ثوانٍ أنه في المركز A قمنا بإطفاء العقدة 2 و 3 و 4 - وهذا يعني أنه في مراكز البيانات الأخرى لا يمكننا إطفاء تلك العقد مع وجود جزء واحد فقط متبقي.
  • بمعرفة سلوك السيد ، فإننا ننظر بعناية شديدة في عدد المهام المعلقة. لأنه حتى مهمة واحدة معلقة ، إذا لم تنقضي مهلتها في الوقت المناسب ، من الناحية النظرية ، في بعض حالات الطوارئ ، يمكن أن تصبح السبب ، على سبيل المثال ، في عدم نجاح الترويج لنسخة متماثلة في المرحلة الابتدائية بالنسبة لنا ، والتي ستتوقف الفهرسة.
  • نحن أيضًا نلقي نظرة فاحصة على حالات التأخير في أداة تجميع القمامة ، لأننا واجهنا بالفعل صعوبات كبيرة في هذا الأمر عند التحسين.
  • رفض الخيوط لفهم مكان "عنق الزجاجة" مقدمًا.
  • حسنًا ، المقاييس القياسية مثل الكومة وذاكرة الوصول العشوائي و I / O.

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

ما أريد أن أقوله في الختام: نجحنا! تمكنا من تزويد المبرمجين والمطورين لدينا بأداة يمكنها توفير معلومات سريعة وموثوقة حول ما يحدث في الإنتاج في أي موقف تقريبًا.

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

200 تيرا بايت + مجموعة Elasticsearch

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

إضافة تعليق