Elasticsearch cluster 200 TB+

Elasticsearch cluster 200 TB+

بسیاری از مردم با Elasticsearch مشکل دارند. اما چه اتفاقی می‌افتد وقتی می‌خواهید از آن برای ذخیره سیاهه‌ها «در حجم بسیار زیاد» استفاده کنید؟ و آیا تجربه شکست هر یک از چندین مرکز داده نیز بدون درد است؟ چه نوع معماری را باید بسازید و به چه دام هایی برخورد خواهید کرد؟

ما در Odnoklassniki تصمیم گرفتیم از elasticsearch برای حل مسئله مدیریت لاگ استفاده کنیم و اکنون تجربه خود را با Habr به اشتراک می گذاریم: هم در مورد معماری و هم در مورد مشکلات.

من پیوتر زایتسف هستم، به عنوان مدیر سیستم در Odnoklassniki کار می کنم. قبل از آن، من همچنین یک ادمین بودم، با Manticore Search، Sphinx Search، Elasticsearch کار کردم. شاید اگر ... جستجوی دیگری ظاهر شد، احتمالاً من نیز با آن کار کنم. من همچنین در تعدادی از پروژه های منبع باز به صورت داوطلبانه شرکت می کنم.

وقتی به Odnoklassniki آمدم، در مصاحبه بی پروا گفتم که می توانم با Elasticsearch کار کنم. بعد از اینکه به آن دست زدم و کارهای ساده ای را انجام دادم، وظیفه بزرگ اصلاح سیستم مدیریت لاگ که در آن زمان وجود داشت به من سپرده شد.

مقررات

سیستم مورد نیاز به صورت زیر فرموله شد:

  • Graylog قرار بود به عنوان قسمت جلویی استفاده شود. از آنجا که شرکت قبلاً تجربه استفاده از این محصول را داشت، برنامه نویسان و آزمایش کنندگان آن را می دانستند، برای آنها آشنا و راحت بود.
  • حجم داده: به طور متوسط ​​50-80 هزار پیام در ثانیه، اما اگر چیزی خراب شود، ترافیک با هیچ چیز محدود نمی شود، می تواند 2-3 میلیون خط در ثانیه باشد.
  • پس از بحث با مشتریان در مورد الزامات سرعت پردازش پرس و جوهای جستجو، متوجه شدیم که الگوی معمول استفاده از چنین سیستمی به این صورت است: مردم به دنبال گزارش های برنامه خود برای دو روز گذشته هستند و نمی خواهند بیش از یک روز منتظر بمانند. دوم برای نتیجه یک پرس و جو فرموله شده.
  • مدیران اصرار داشتند که در صورت لزوم، سیستم به راحتی مقیاس پذیر باشد، بدون اینکه نیازی به کاوش عمیق در نحوه عملکرد آن باشد.
  • به طوری که تنها وظیفه تعمیر و نگهداری که این سیستم ها به صورت دوره ای نیاز دارند، تغییر برخی سخت افزارها است.
  • علاوه بر این، Odnoklassniki یک سنت فنی عالی دارد: هر سرویسی که راه اندازی می کنیم باید از خرابی مرکز داده جان سالم به در ببرد (ناگهانی، برنامه ریزی نشده و کاملاً در هر زمانی).

آخرین نیاز در اجرای این پروژه بیشترین هزینه را برای ما داشت که در مورد آن بیشتر صحبت خواهم کرد.

چهار شنبه

ما در چهار مرکز داده کار می کنیم، در حالی که گره های داده Elasticsearch فقط می توانند در سه مرکز قرار گیرند (به دلایل غیر فنی).

این چهار مرکز داده حاوی تقریباً 18 هزار منبع گزارش مختلف هستند - سخت افزار، کانتینر، ماشین های مجازی.

ویژگی مهم: خوشه در کانتینرها شروع می شود پودمن نه بر روی ماشین های فیزیکی، بلکه در محصول ابری خود یک ابری. کانتینرها دارای ضمانت 2 هسته، مشابه 2.0 گیگاهرتز نسخه 4 هستند، با امکان بازیافت هسته های باقی مانده در صورت بیکار بودن.

به عبارت دیگر:

Elasticsearch cluster 200 TB+

توپولوژی

من در ابتدا شکل کلی راه حل را به صورت زیر دیدم:

  • 3-4 VIP پشت A-record دامنه Graylog هستند، این آدرسی است که لاگ ها به آن ارسال می شوند.
  • هر VIP یک متعادل کننده LVS است.
  • پس از آن، لاگ ها به باتری Graylog می روند، برخی از داده ها با فرمت GELF، برخی با فرمت syslog هستند.
  • سپس همه اینها در دسته های بزرگ روی باتری ای از هماهنگ کننده های Elasticsearch نوشته می شود.
  • و آنها نیز به نوبه خود درخواست های نوشتن و خواندن را به گره های داده مربوطه ارسال می کنند.

Elasticsearch cluster 200 TB+

اصطلاحات

شاید همه این اصطلاحات را با جزئیات درک نکنند، بنابراین مایلم کمی در مورد آن صحبت کنم.

Elasticsearch چندین نوع گره دارد - Master، Coordinator، Data Node. دو نوع دیگر برای تبدیل های مختلف گزارش و ارتباط بین خوشه های مختلف وجود دارد، اما ما فقط از موارد ذکر شده استفاده کردیم.

استاد
تمام گره‌های موجود در خوشه را پینگ می‌کند، یک نقشه خوشه‌ای به‌روز نگه می‌دارد و آن را بین گره‌ها توزیع می‌کند، منطق رویداد را پردازش می‌کند، و انواع مختلفی از خانه‌داری در کل خوشه را انجام می‌دهد.

تعدیل کننده
یک کار واحد را انجام می دهد: درخواست های خواندن یا نوشتن از مشتریان را می پذیرد و این ترافیک را هدایت می کند. در صورت وجود درخواست نوشتن، به احتمال زیاد، از استاد می پرسد که کدام قطعه از ایندکس مربوطه را باید در آن قرار دهد و درخواست را به ادامه مسیر هدایت می کند.

گره داده
داده‌ها را ذخیره می‌کند، درخواست‌های جستجویی را که از خارج می‌آیند انجام می‌دهد و عملیات‌هایی را روی خرده‌هایی که روی آن قرار دارند انجام می‌دهد.

گلیم
این چیزی شبیه ادغام Kibana با Logstash در یک پشته ELK است. Graylog هر دو رابط کاربری و خط لوله پردازش گزارش را ترکیب می کند. زیر کاپوت، Graylog Kafka و Zookeeper را اجرا می‌کند که به عنوان یک خوشه به Graylog متصل می‌شوند. Graylog می‌تواند گزارش‌ها (کافکا) را در صورت در دسترس نبودن Elasticsearch ذخیره کند و درخواست‌های خواندن و نوشتن ناموفق را تکرار کند، گزارش‌ها را طبق قوانین مشخص شده گروه‌بندی و علامت‌گذاری کند. مانند Logstash، Graylog قابلیت تغییر ردیف‌ها را قبل از نوشتن آنها در Elasticsearch دارد.

علاوه بر این، Graylog یک کشف سرویس داخلی دارد که بر اساس یک گره Elasticsearch موجود، اجازه می‌دهد تا کل نقشه خوشه‌ای را به‌دست آورد و آن را با یک برچسب خاص فیلتر کند، که امکان هدایت درخواست‌ها به کانتینرهای خاص را فراهم می‌کند.

از نظر بصری چیزی شبیه به این است:

Elasticsearch cluster 200 TB+

این یک اسکرین شات از یک نمونه خاص است. در اینجا ما یک هیستوگرام بر اساس پرس و جوی جستجو می سازیم و ردیف های مربوطه را نمایش می دهیم.

شاخص

با بازگشت به معماری سیستم، می خواهم با جزئیات بیشتری در مورد نحوه ساخت مدل شاخص صحبت کنم تا همه آن به درستی کار کند.

در نمودار بالا، این پایین ترین سطح است: گره های داده Elasticsearch.

ایندکس یک موجودیت مجازی بزرگ است که از قطعات Elasticsearch تشکیل شده است. به خودی خود، هر یک از خرده ها چیزی بیش از یک شاخص لوسن نیستند. و هر شاخص لوسن به نوبه خود از یک یا چند بخش تشکیل شده است.

Elasticsearch cluster 200 TB+

هنگام طراحی، متوجه شدیم که برای برآوردن نیاز سرعت خواندن در مقدار زیادی داده، باید این داده‌ها را به طور یکنواخت در گره‌های داده پخش کنیم.

این منجر به این واقعیت شد که تعداد خرده‌های هر شاخص (با کپی‌ها) باید کاملاً برابر با تعداد گره‌های داده باشد. اولاً برای اطمینان از ضریب تکرار برابر با دو (یعنی می توانیم نیمی از خوشه را از دست بدهیم). و دوم، به منظور پردازش درخواست های خواندن و نوشتن در حداقل نیمی از خوشه.

ما ابتدا زمان ذخیره سازی را 30 روز تعیین کردیم.

توزیع خرده ها را می توان به صورت گرافیکی به صورت زیر نشان داد:

Elasticsearch cluster 200 TB+

کل مستطیل خاکستری تیره یک شاخص است. مربع قرمز سمت چپ در آن خرده اولیه است، اولین در شاخص. و مربع آبی یک تکه ماکت است. آنها در مراکز داده مختلف قرار دارند.

وقتی یک قطعه دیگر اضافه می کنیم، به مرکز داده سوم می رود. و، در پایان، ما این ساختار را دریافت می کنیم، که باعث می شود بدون از دست دادن ثبات داده، DC را از دست دهیم:

Elasticsearch cluster 200 TB+

چرخش شاخص ها، یعنی. با ایجاد یک نمایه جدید و حذف قدیمی ترین، آن را برابر با 48 ساعت کردیم (طبق الگوی استفاده از نمایه: 48 ساعت گذشته بیشتر جستجو می شود).

این فاصله چرخش شاخص به دلایل زیر است:

هنگامی که یک درخواست جستجو به یک گره داده خاص می رسد، از نقطه نظر عملکرد، زمانی سودآورتر است که یک خرده پرس و جو شود، اگر اندازه آن با اندازه باسن گره قابل مقایسه باشد. این به شما امکان می دهد بخش "گرم" شاخص را در یک پشته نگه دارید و به سرعت به آن دسترسی پیدا کنید. هنگامی که تعداد زیادی "قطعات داغ" وجود دارد، سرعت جستجوی فهرست کاهش می یابد.

هنگامی که یک گره شروع به اجرای یک پرس و جوی جستجو بر روی یک خرده می کند، تعدادی رشته برابر با تعداد هسته های ابر رشته ماشین فیزیکی اختصاص می دهد. اگر یک پرس و جوی جستجو بر تعداد زیادی از خرده ها تأثیر بگذارد، تعداد رشته ها به نسبت افزایش می یابد. این تأثیر منفی بر سرعت جستجو دارد و بر نمایه سازی داده های جدید تأثیر منفی می گذارد.

برای ارائه تأخیر جستجوی لازم، تصمیم گرفتیم از SSD استفاده کنیم. برای پردازش سریع درخواست‌ها، ماشین‌هایی که این کانتینرها را میزبانی می‌کنند باید حداقل 56 هسته داشته باشند. رقم 56 به‌عنوان مقدار کافی مشروط انتخاب شد که تعداد رشته‌هایی را که Elasticsearch در طول عملیات ایجاد می‌کند، تعیین می‌کند. در Elasitcsearch، بسیاری از پارامترهای thread pool مستقیماً به تعداد هسته های موجود بستگی دارد، که به نوبه خود مستقیماً بر تعداد گره های مورد نیاز در خوشه مطابق با اصل "هسته های کمتر - گره های بیشتر" تأثیر می گذارد.

در نتیجه، متوجه شدیم که به طور متوسط ​​یک خرده حدود 20 گیگابایت وزن دارد و 1 خرده در هر شاخص وجود دارد. بر این اساس، اگر هر 360 ساعت یک بار آنها را بچرخانیم، 48 عدد از آنها خواهیم داشت. هر شاخص حاوی داده های 15 روزه است.

مدارهای نوشتن و خواندن داده ها

بیایید بفهمیم که چگونه داده ها در این سیستم ثبت می شوند.

فرض کنید درخواستی از Graylog به هماهنگ کننده می رسد. به عنوان مثال، ما می خواهیم 2-3 هزار ردیف را ایندکس کنیم.

هماهنگ کننده، پس از دریافت درخواستی از Graylog، از استاد سؤال می کند: "در درخواست نمایه سازی، ما به طور خاص یک نمایه را مشخص کردیم، اما در کدام قطعه برای نوشتن آن مشخص نشده بود."

استاد پاسخ می دهد: "این اطلاعات را در قسمت شماره 71 بنویسید"، پس از آن مستقیماً به گره داده مربوطه ارسال می شود، جایی که شماره شارد اولیه 71 در آن قرار دارد.

پس از آن، گزارش تراکنش به یک replica-shard، که در مرکز داده دیگری قرار دارد، کپی می‌شود.

Elasticsearch cluster 200 TB+

یک درخواست جستجو از Graylog به هماهنگ کننده می رسد. هماهنگ کننده آن را با توجه به شاخص تغییر مسیر می دهد، در حالی که Elasticsearch درخواست ها را بین اصلی-shard و replica-shard با استفاده از اصل round-robin توزیع می کند.

Elasticsearch cluster 200 TB+

180 گره به طور ناهموار پاسخ می دهند، و در حالی که آنها پاسخ می دهند، هماهنگ کننده اطلاعاتی را جمع آوری می کند که قبلاً توسط گره های داده سریعتر "بیرون ریخته شده است". پس از این، زمانی که یا تمام اطلاعات به دست می‌آید، یا درخواست به پایان می‌رسد، همه چیز را مستقیماً به مشتری می‌دهد.

کل این سیستم به طور متوسط ​​پرس‌و‌جوهای جستجو را در 48 ساعت گذشته در 300-400 میلی‌ثانیه پردازش می‌کند، به استثنای آن دسته از پرس‌و‌جوهایی که دارای علامت عام اصلی هستند.

Flowers with Elasticsearch: راه اندازی جاوا

Elasticsearch cluster 200 TB+

برای اینکه همه آن‌طور که در ابتدا می‌خواستیم کار کند، مدت زمان زیادی را صرف اشکال‌زدایی طیف گسترده‌ای از چیزها در خوشه کردیم.

اولین بخش از مشکلات کشف شده مربوط به نحوه از پیش پیکربندی جاوا به صورت پیش فرض در Elasticsearch بود.

مشکل یک
ما تعداد بسیار زیادی از گزارش‌ها را مشاهده کرده‌ایم که در سطح Lucene، زمانی که کارهای پس‌زمینه در حال اجرا هستند، ادغام‌های بخش Lucene با یک خطا با شکست مواجه می‌شوند. در همان زمان، در گزارش ها مشخص بود که این یک خطای OutOfMemoryError است. ما از تله متری دیدیم که لگن آزاد است و معلوم نبود چرا این عمل با شکست مواجه شده است.

معلوم شد که ادغام شاخص لوسن در خارج از لگن اتفاق می افتد. و کانتینرها از نظر منابع مصرفی کاملاً محدود هستند. فقط heap می‌توانست در این منابع قرار بگیرد (مقدار heap.size تقریباً برابر با RAM بود)، و برخی از عملیات‌های off-heap با خطای تخصیص حافظه خراب می‌شدند، اگر به دلایلی در ~500 مگابایتی که قبل از حد باقی مانده بود جا نشوند.

راه حل کاملاً بی اهمیت بود: مقدار RAM موجود برای کانتینر افزایش یافت، پس از آن فراموش کردیم که حتی چنین مشکلاتی داشتیم.

مشکل دو
4-5 روز پس از راه اندازی کلاستر، متوجه شدیم که گره های داده به طور دوره ای از خوشه خارج شده و پس از 10-20 ثانیه وارد آن می شوند.

وقتی شروع به کشف آن کردیم، معلوم شد که این حافظه خارج از هیپ در Elasticsearch به هیچ وجه کنترل نمی شود. زمانی که حافظه بیشتری به کانتینر دادیم، توانستیم استخرهای بافر مستقیم را با اطلاعات مختلف پر کنیم و تنها پس از راه اندازی GC صریح از Elasticsearch پاک شد.

در برخی موارد، این عملیات زمان زیادی طول کشید و در این مدت خوشه موفق شد این گره را به عنوان قبلاً خارج شده علامت گذاری کند. این مشکل به خوبی توضیح داده شده است اینجا.

راه حل به شرح زیر بود: ما توانایی جاوا را برای استفاده از بخش عمده حافظه خارج از پشته برای این عملیات محدود کردیم. ما آن را به 16 گیگابایت (-XX:MaxDirectMemorySize=16g) محدود کردیم، و مطمئن شدیم که GC صریح خیلی بیشتر فراخوانی می‌شود و بسیار سریع‌تر پردازش می‌شود، در نتیجه دیگر خوشه را بی‌ثبات نمی‌کند.

مسئله سه
اگر فکر می کنید که مشکلات مربوط به "خروج گره ها از خوشه در غیرمنتظره ترین لحظه" به پایان رسیده است، در اشتباهید.

وقتی کار را با ایندکس ها پیکربندی کردیم، mmapfs را انتخاب کردیم کاهش زمان جستجو روی خرده های تازه با تقسیم بندی عالی. این یک اشتباه کاملاً اشتباه بود، زیرا هنگام استفاده از mmapfs، فایل به RAM نگاشت می‌شود و سپس با فایل نگاشت شده کار می‌کنیم. به همین دلیل، مشخص می‌شود که وقتی GC سعی می‌کند موضوعات را در برنامه متوقف کند، ما برای مدت طولانی به امن‌پوینت می‌رویم و در مسیر رسیدن به آن، برنامه دیگر به درخواست‌های استاد درباره زنده بودن آن پاسخ نمی‌دهد. . بر این اساس، استاد معتقد است که گره دیگر در خوشه وجود ندارد. پس از این، پس از 5-10 ثانیه، جمع کننده زباله کار می کند، گره زنده می شود، دوباره وارد خوشه می شود و شروع به مقداردهی اولیه خرده ها می کند. همه اینها بسیار شبیه «تولیداتی بود که شایسته آن بودیم» و برای هیچ چیز جدی مناسب نبود.

برای رهایی از این رفتار، ابتدا به سراغ niofهای استاندارد رفتیم و بعد از مهاجرت از نسخه پنجم الاستیک به نسخه ششم، هیبریدف ها را امتحان کردیم که این مشکل تکرار نشد. می توانید در مورد انواع ذخیره سازی بیشتر بخوانید اینجا.

مسئله چهار
سپس یک مشکل بسیار جالب دیگر وجود داشت که ما آن را برای مدت رکوردی درمان کردیم. ما 2-3 ماه آن را گرفتیم زیرا الگوی آن کاملاً نامفهوم بود.

گاهی اوقات هماهنگ کننده های ما معمولاً بعد از ناهار به فول جی سی می رفتند و دیگر از آنجا برنگشتند. در همان زمان، هنگام ثبت تاخیر GC، به نظر می رسید: همه چیز خوب است، خوب، خوب، و سپس ناگهان همه چیز بسیار بد پیش می رود.

در ابتدا فکر کردیم که یک کاربر شرور داریم که در حال انجام نوعی درخواست است که هماهنگ کننده را از حالت کار خارج می کند. ما درخواست‌ها را برای مدت طولانی ثبت کردیم و سعی کردیم بفهمیم چه اتفاقی می‌افتد.

در نتیجه، مشخص شد که در لحظه ای که کاربر درخواست بزرگی را راه اندازی می کند و به یک هماهنگ کننده Elasticsearch خاص می رسد، برخی از گره ها طولانی تر از دیگران پاسخ می دهند.

و در حالی که هماهنگ کننده منتظر پاسخ از همه گره ها است، نتایج ارسال شده از گره هایی را که قبلاً پاسخ داده اند جمع آوری می کند. برای GC، این بدان معنی است که الگوهای استفاده از پشته ما خیلی سریع تغییر می کند. و GC که ما استفاده کردیم نتوانست با این کار کنار بیاید.

تنها راه حلی که برای تغییر رفتار خوشه در این شرایط یافتیم، مهاجرت به JDK13 و استفاده از زباله جمع‌آور Shenandoah است. این مشکل را حل کرد، هماهنگ کننده های ما از سقوط باز ماندند.

اینجا بود که مشکلات جاوا به پایان رسید و مشکلات پهنای باند شروع شد.

"توت ها" با Elasticsearch: توان عملیاتی

Elasticsearch cluster 200 TB+

مشکلات با توان عملیاتی به این معنی است که خوشه ما به طور پایدار کار می کند، اما در اوج تعداد اسناد نمایه شده و در طول مانورها، عملکرد ناکافی است.

اولین علامتی که با آن مواجه شد: در طی برخی "انفجارها" در تولید، زمانی که تعداد بسیار زیادی از گزارش ها به طور ناگهانی تولید می شوند، خطای نمایه سازی es_rejected_execution به طور مکرر در Graylog شروع به چشمک زدن می کند.

این به دلیل این واقعیت بود که thread_pool.write.queue در یک گره داده، تا زمانی که Elasticsearch بتواند درخواست نمایه سازی را پردازش کند و اطلاعات را در قطعه قطعه روی دیسک آپلود کند، به طور پیش فرض قادر است تنها 200 درخواست را کش کند. و در اسناد Elasticsearch در مورد این پارامتر بسیار کم گفته شده است. فقط حداکثر تعداد رشته ها و اندازه پیش فرض نشان داده شده است.

البته، ما به سمت چرخاندن این مقدار رفتیم و متوجه موارد زیر شدیم: به طور خاص، در راه اندازی ما، حداکثر 300 درخواست به خوبی ذخیره می شوند، و مقدار بالاتر مملو از این واقعیت است که ما دوباره به Full GC پرواز می کنیم.

علاوه بر این، از آنجایی که اینها دسته‌ای از پیام‌ها هستند که در یک درخواست به دست می‌آیند، لازم بود Graylog را به گونه‌ای تنظیم کنید که نه اغلب و در دسته‌های کوچک، بلکه در دسته‌های بزرگ یا هر 3 ثانیه یک بار در صورتی که دسته هنوز کامل نشده است بنویسد. در این حالت، معلوم می‌شود که اطلاعاتی که در Elasticsearch می‌نویسیم نه در دو ثانیه، بلکه در پنج ثانیه (که کاملاً مناسب ما است) در دسترس قرار می‌گیرد، اما تعداد بازگردانی‌هایی که باید برای عبور از یک صفحه بزرگ ایجاد شوند، در دسترس قرار می‌گیرند. پشته اطلاعات کاهش می یابد.

این امر به ویژه در لحظاتی مهم است که چیزی در جایی خراب شده است و با عصبانیت در مورد آن گزارش می دهد تا یک الاستیک کاملاً اسپم دریافت نشود و بعد از مدتی - گره های Graylog که به دلیل مسدود شدن بافرها غیر قابل اجرا هستند.

علاوه بر این، زمانی که ما همین انفجارها را در تولید داشتیم، شکایاتی از برنامه‌نویسان و آزمایش‌کنندگان دریافت کردیم: در لحظه‌ای که آنها واقعاً به این لاگ‌ها نیاز داشتند، بسیار آهسته به آنها داده شد.

آنها شروع به کشف آن کردند. از یک طرف، واضح بود که هم پرس‌و‌جوهای جستجو و هم عبارت‌های نمایه‌سازی، اساساً روی یک ماشین فیزیکی پردازش می‌شوند، و به هر نحوی مشکلات خاصی وجود دارد.

اما این امر می تواند تا حدی نادیده گرفته شود زیرا در نسخه ششم Elasticsearch، الگوریتمی ظاهر شد که به شما امکان می دهد پرس و جوها را بین گره های داده مربوطه توزیع کنید، نه بر اساس اصل تصادفی تصادفی (محفظه ای که نمایه سازی می کند و اولیه را نگه می دارد. -shard می تواند بسیار شلوغ باشد، هیچ راهی برای پاسخ سریع وجود نخواهد داشت)، اما برای ارسال این درخواست به یک ظرف کم بار با یک replica-shard، که بسیار سریعتر پاسخ می دهد. به عبارت دیگر، به use_adaptive_replica_selection: true رسیدیم.

تصویر خواندن شروع به شکل زیر می کند:

Elasticsearch cluster 200 TB+

انتقال به این الگوریتم امکان بهبود قابل توجه زمان پرس و جو را در آن لحظاتی که جریان زیادی از گزارش‌ها برای نوشتن داشتیم را ممکن کرد.

در نهایت، مشکل اصلی حذف بدون درد مرکز داده بود.

آنچه ما از خوشه بلافاصله پس از قطع ارتباط با یک DC می خواستیم:

  • اگر یک Master فعلی در مرکز داده شکست خورده داشته باشیم، مجدداً انتخاب شده و به عنوان یک نقش به گره دیگری در DC دیگر منتقل می شود.
  • Master به سرعت تمام گره های غیرقابل دسترسی را از خوشه حذف می کند.
  • بر اساس موارد باقیمانده، او متوجه خواهد شد: در مرکز داده از دست رفته، ما فلان خرده‌های اولیه را داشتیم، او به سرعت تکه تکه‌های تکراری را در مراکز داده باقی‌مانده تبلیغ می‌کند و ما به نمایه‌سازی داده‌ها ادامه می‌دهیم.
  • در نتیجه، سرعت نوشتن و خواندن خوشه به تدریج کاهش می یابد، اما به طور کلی همه چیز کار خواهد کرد، هرچند آهسته، اما پایدار.

همانطور که معلوم شد، ما چیزی شبیه به این می خواستیم:

Elasticsearch cluster 200 TB+

و به موارد زیر رسیدیم:

Elasticsearch cluster 200 TB+

چگونه اتفاق افتاد؟

وقتی مرکز داده سقوط کرد، استاد ما به گلوگاه تبدیل شد.

چرا؟

واقعیت این است که Master یک TaskBatcher دارد که وظیفه توزیع وظایف و رویدادهای خاص در کلاستر را بر عهده دارد. هر خروج گره، هر ارتقای یک قطعه از replica به اولیه، هر کار برای ایجاد یک خرده در جایی - همه اینها ابتدا به TaskBatcher می رود، جایی که به صورت متوالی و در یک رشته پردازش می شود.

در زمان خروج یک مرکز داده، معلوم شد که همه گره‌های داده در مراکز داده باقیمانده وظیفه خود می‌دانستند که به استاد اطلاع دهند «ما فلان خرده‌ها و فلان گره‌های داده را از دست داده‌ایم».

در همان زمان، گره های داده باقیمانده تمام این اطلاعات را برای استاد فعلی ارسال کردند و سعی کردند منتظر تأیید شوند که او آن را پذیرفته است. آنها منتظر این نبودند، زیرا استاد سریعتر از آنچه که می توانست پاسخ دهد وظایف را دریافت کرد. نودها زمان درخواست های تکراری را به پایان رساندند و استاد در این زمان حتی سعی نکرد به آنها پاسخ دهد، اما به طور کامل در وظیفه مرتب سازی درخواست ها بر اساس اولویت جذب شد.

در شکل ترمینال، معلوم شد که گره‌های داده، Master را تا حدی اسپم می‌کنند که به GC کامل می‌رود. پس از آن، نقش اصلی ما به گره بعدی منتقل شد، دقیقاً همان اتفاق برای آن افتاد و در نتیجه خوشه به طور کامل از بین رفت.

ما اندازه گیری ها را انجام دادیم و قبل از نسخه 6.4.0، جایی که این مشکل برطرف شد، برای ما کافی بود که به طور همزمان تنها 10 گره داده از 360 را خروجی دهیم تا به طور کامل خوشه را خاموش کنیم.

چیزی شبیه این به نظر می رسید:

Elasticsearch cluster 200 TB+

پس از نسخه 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 شد.
  • علاوه بر این، برای اطمینان از عملکرد جستجو، ما سعی کردیم تعداد اشیاء در خوشه را تا حد امکان کوچک نگه داریم تا تا حد امکان تعداد کمتری از رویدادها را در گلوگاهی که در master به دست آوردیم پردازش کنیم.

در نهایت در مورد نظارت

برای اطمینان از اینکه همه اینها همانطور که در نظر گرفته شده کار می کند، موارد زیر را کنترل می کنیم:

  • هر گره داده به ابر ما گزارش می دهد که وجود دارد، و فلان خرده روی آن وجود دارد. وقتی چیزی را در جایی خاموش می کنیم، خوشه بعد از 2 تا 3 ثانیه گزارش می دهد که در مرکز A گره های 2، 3 و 4 را خاموش کردیم - این بدان معنی است که در سایر مراکز داده ما تحت هیچ شرایطی نمی توانیم گره هایی را که روی آنها فقط یک قطعه وجود دارد خاموش کنیم. ترک کرد.
  • با دانستن ماهیت رفتار استاد، ما با دقت به تعداد کارهای معلق نگاه می کنیم. از آنجا که حتی یک کار گیر کرده، اگر به موقع تمام نشود، از نظر تئوری در برخی شرایط اضطراری می‌تواند دلیلی شود که مثلاً تبلیغ یک تکه ماکت در اولیه کار نمی‌کند، به همین دلیل است که نمایه‌سازی از کار می‌افتد.
  • ما همچنین به تأخیرهای جمع‌آوری زباله بسیار دقیق نگاه می‌کنیم، زیرا قبلاً در طول بهینه‌سازی با مشکلات زیادی در این زمینه روبرو بوده‌ایم.
  • با نخ رد می کند تا از قبل بفهمد گلوگاه کجاست.
  • خوب، معیارهای استاندارد مانند heap، RAM و I/O.

هنگام ساخت مانیتورینگ، باید ویژگی های Thread Pool در Elasticsearch را در نظر بگیرید. اسناد Elasticsearch گزینه‌های پیکربندی و مقادیر پیش‌فرض را برای جستجو و نمایه‌سازی توصیف می‌کند، اما در مورد thread_pool.management کاملاً بی‌صدا است. این رشته‌ها، به‌ویژه، پرس‌وجوهایی مانند _cat/shards و سایر موارد مشابه را پردازش می‌کنند، که برای استفاده در هنگام نوشتن مانیتورینگ راحت هستند. هرچه خوشه بزرگتر باشد، چنین درخواست‌هایی در واحد زمان بیشتر اجرا می‌شوند و thread_pool.management فوق‌الذکر نه تنها در مستندات رسمی ارائه نمی‌شود، بلکه به طور پیش‌فرض به 5 رشته محدود می‌شود که خیلی سریع پس از حذف از بین می‌رود. که نظارت به درستی کار نمی کند.

آنچه می خواهم در پایان بگویم: ما آن را انجام دادیم! ما توانستیم ابزاری را در اختیار برنامه نویسان و توسعه دهندگان خود قرار دهیم که تقریباً در هر شرایطی می تواند به سرعت و با اطمینان اطلاعاتی در مورد آنچه در تولید اتفاق می افتد ارائه دهد.

بله، معلوم شد که بسیار پیچیده است، اما، با این وجود، ما موفق شدیم خواسته های خود را در محصولات موجود قرار دهیم، که مجبور نبودیم برای خودمان وصله و بازنویسی کنیم.

Elasticsearch cluster 200 TB+

منبع: www.habr.com

اضافه کردن نظر