تسع مشايات المطاطية التي خطوت عليها

رسم أنطون جوديم


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

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

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

يجب أن تكون عقد البيانات هي نفسها


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

الإيقاف


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

[2018-07-07T14:10:26,659][WARN ][oedrRestController] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header. [2018-07-07T14:10:26,670][WARN ][oedrRestController] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header. [2018-07-07T14:10:26,671][WARN ][oedrRestController] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header. [2018-07-07T14:10:26,673][WARN ][oedrRestController] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header. [2018-07-07T14:10:26,677][WARN ][oedrRestController ] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header. 

تأتي الطلبات ، في المتوسط ​​، كل 5-10 مللي ثانية - وفي كل مرة يتم فيها إضافة سطر جديد إلى السجل. هذا يؤثر سلبا على أداء النظام الفرعي للقرص ويزيد من iowait. يمكن إيقاف تشغيل Deprecation.log ، ولكنه ليس معقولاً للغاية. لجمع السجلات المرنة فيه ، ولكن ليس للقمامة ، أقوم فقط بتعطيل السجلات من فئة oedrRestController.

للقيام بذلك ، قم بإضافة البناء التالي إلى logs4j2.properties:

 logger.restcontroller.name = org.elasticsearch.deprecation.rest.RestController logger.restcontroller.level = error 

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

.kibana


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

 { "default": { "order": 0, "template": "*", "settings": { "number_of_shards": "1", "number_of_replicas": "0" } }, "mappings": {}, "aliases": {} } 

ويتم إنشاء فهرس .kibana ، حيث يتم تخزين جميع الإعدادات ، في نسخة واحدة.

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

يتم حل كل هذا ببساطة. حتى الآن ، لم يسقط شيء:

 XPUT .kibana/_settings { "index": { "number_of_replicas": "<__>" } } 

XMX / XMS


تقول الوثائق "لا يزيد عن 32 جيجا بايت" وهو محق في ذلك. ولكن من الصحيح أيضًا أنك لست بحاجة إلى التثبيت في إعدادات الخدمة
 -Xms32g -Xmx32g 

لأنه يزيد بالفعل عن 32 غيغابايت ، وهنا نواجه فارقًا بسيطًا مثيرًا للاهتمام في Java يعمل مع الذاكرة. فوق حد معين ، تتوقف Java عن استخدام المؤشرات المضغوطة وتبدأ في استهلاك الكثير من الذاكرة بشكل غير معقول. إن التحقق مما إذا كانت المؤشرات المضغوطة تستخدم آلة Java تقوم بتشغيل Elasticsearch أمر بسيط للغاية. ننظر في سجل الخدمة:

 [2018-07-29T15:04:22,041][INFO][oeeNodeEnvironment][log-elastic-hot3] heap size [31.6gb], compressed ordinary object pointers [true] 

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

لقد قمت الآن بالتثبيت على جميع عقد البيانات المرنة:

 -Xms32766m -Xmx32766m 

يبدو أنها حقيقة مبتذلة ، والوثائق موصوفة جيدًا ، لكنني أواجه بانتظام منشآت Elasticsearch حيث فاتني هذه النقطة ، وتم ضبط Xms / Xmx على 32 جرامًا.

/ var / lib / elasticsearch


هذا هو المسار الافتراضي لتخزين البيانات في elasticsearch. yml:

 path.data: /var/lib/elasticsearch 

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

 path.data: /var/lib/elasticsearch/data1, /var/lib/elasticsearch/data2 

يتم تركيب الأقراص أو صفائف الغارات المختلفة في data1 و data2. لكن المرونة لا تتوازن ولا توزع الحمل بين هذه المسارات. أولاً ، يملأ قسمًا واحدًا ، ثم يبدأ في الكتابة في قسم آخر ، لذلك سيكون الحمل على التخزين غير متساوٍ. بمعرفة ذلك ، اتخذت قرارًا لا لبس فيه - جمعت جميع الأقراص في RAID0 / 1 وقمت بتثبيته في المسار المحدد في path.data.

المعالجات المتاحة


ولا ، أنا لا أقصد المعالجات على عقد استيعاب الآن. إذا نظرت إلى خصائص عقدة قيد التشغيل (عبر _nodes API) ، يمكنك رؤية شيء مثل هذا:

 "os". { "refresh_interval_in_millis": 1000, "name": "Linux", "arch": "amd64", "version": "4.4.0-87-generic", "available_processors": 28, "allocated_processors": 28 } 

يمكن ملاحظة أن العقدة تعمل على مضيف يحتوي على 28 نواة ، والمرونة تحدد عددها بشكل صحيح وتبدأ على الإطلاق. ولكن إذا كان هناك أكثر من 32 نواة ، يحدث ذلك في بعض الأحيان على النحو التالي:

 "os": { "refresh_interval_in_millis": 1000, "name": "Linux", "arch": "amd64", "version": "4.4.0-116-generic", "available_processors": 72, "allocated_processors": 32 } 

عليك فرض عدد المعالجات المتوفرة للخدمة - وهذا له تأثير جيد على أداء العقدة.

 processors: 72 

thread_pool.bulk.queue_size


في قسم thread_pool.bulk.rejected من المقالة الأخيرة ، كان هناك مثل هذا المقياس - عدد حالات الفشل لطلبات إضافة البيانات.

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

افتراضيًا ، تبدو إعدادات قائمة الانتظار كما يلي:

 "thread_pool": { "bulk": { "type": "fixed", "min": 28, "max": 28, "queue_size": 200 } } 

الخوارزمية هي كما يلي:

  1. نقوم بجمع إحصاءات حول متوسط ​​حجم قائمة الانتظار خلال اليوم (يتم تخزين القيمة الفورية في thread_pool.bulk.queue) ؛
  2. زيادة حجم queue_size بعناية إلى أحجام أكبر قليلاً من متوسط ​​حجم قائمة الانتظار النشطة - لأن الفشل يحدث عند تجاوزه ؛
  3. نحن نزيد حجم البركة - هذا ليس ضروريًا ، ولكنه مقبول.

للقيام بذلك ، أضف شيئًا مثل هذا إلى إعدادات المضيف (سيكون لديك بالطبع قيمك الخاصة):

 thread_pool.bulk.size: 32 thread_pool.bulk.queue_size: 500 

وبعد إعادة تشغيل العقدة ، سنراقب بالتأكيد الحمل ، I / O ، استهلاك الذاكرة. وكل ما هو ممكن للتراجع عن الإعدادات إذا لزم الأمر.

هام: هذه الإعدادات لا معنى لها إلا على العقد التي تعمل على تلقي بيانات جديدة.

إنشاء الفهرس الأولي


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

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

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

شفافية الصفحات الضخمة الأم


بمجرد أن وجدنا أن العقد المرنة التي تعمل على استقبال البيانات بدأت تتدلى تحت الحمل خلال ساعات الذروة. ومع أعراض غريبة للغاية: ينخفض ​​استخدام جميع نوى المعالج إلى الصفر ، ولكن مع ذلك ، فإن الخدمة معلقة في الذاكرة ، وتستمع بشكل صحيح إلى المنفذ ، ولا تفعل شيئًا ، ولا تستجيب للطلبات ، وبعد مرور بعض الوقت خارج المجموعة. الخدمة لا تستجيب لإعادة تشغيل systemctl. فقط قتل حسن البالغ من العمر −9 يساعد.

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

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

من السهل التحقق من تمكين صفحات ضخمة شفافة:

 cat /sys/kernel/mm/transparent_hugepage/enabled always madvise [never] 

إذا كان [دائمًا] موجودًا ، فمن المحتمل أنك في خطر.

الخلاصة


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

شكرا على الرسم التوضيحي ، أنطون جوديم - لا يزال هناك الكثير من الخير في إنستغرام .

Source: https://habr.com/ru/post/ar419041/


All Articles