RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها

تحمل خطا و در دسترس بودن بالا موضوعات مهمی هستند، بنابراین ما مقالات جداگانه ای را به RabbitMQ و Kafka اختصاص خواهیم داد. این مقاله در مورد RabbitMQ و مقاله بعدی در مورد کافکا در مقایسه با RabbitMQ است. این مقاله طولانی است، پس خیالتان راحت باشد.

بیایید به استراتژی های تحمل خطا، سازگاری و دسترسی بالا (HA) و معاوضه هایی که هر استراتژی ایجاد می کند نگاه کنیم. RabbitMQ می تواند روی دسته ای از گره ها اجرا شود - و سپس به عنوان یک سیستم توزیع شده طبقه بندی می شود. وقتی نوبت به سیستم های توزیع شده می رسد، ما اغلب در مورد ثبات و در دسترس بودن صحبت می کنیم.

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

خواهیم دید که ثبات و در دسترس بودن در دو طرف طیف قرار دارند و شما باید انتخاب کنید که کدام راه را بهینه کنید. خبر خوب این است که با RabbitMQ این انتخاب امکان پذیر است. شما از این نوع اهرم‌های «دلخواه» برای تغییر تعادل به سمت ثبات بیشتر یا دسترسی بیشتر دارید.

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

Single Node Resilience Primitives

صف/مسیریابی انعطاف پذیر

دو نوع صف در RabbitMQ وجود دارد: بادوام و غیر بادوام. تمام صف ها در پایگاه داده منزیا ذخیره می شوند. صف‌های بادوام در راه‌اندازی نود دوباره تبلیغ می‌شوند و بنابراین از راه‌اندازی مجدد، خرابی سیستم یا خرابی سرور جان سالم به در می‌برند (تا زمانی که داده‌ها ادامه داشته باشند). این بدان معنی است که تا زمانی که مسیریابی (تبادل) و صف را انعطاف پذیر اعلام کنید، زیرساخت صف/مسیریابی به صورت آنلاین باز می گردد.

صف های فرار و مسیریابی با راه اندازی مجدد گره حذف می شوند.

پیام های مداوم

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

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 1. ماتریس پایداری

خوشه بندی با آینه سازی صف

برای زنده ماندن از دست دادن یک کارگزار، ما نیاز به افزونگی داریم. می‌توانیم چندین گره RabbitMQ را در یک خوشه ترکیب کنیم و سپس با تکرار صف‌ها بین چندین گره، افزونگی اضافی اضافه کنیم. به این ترتیب، اگر یک گره از کار بیفتد، داده‌ها را از دست نمی‌دهیم و در دسترس باقی می‌مانیم.

آینه کاری صف:

  • یک صف اصلی (master)، که تمام دستورات نوشتن و خواندن را دریافت می کند
  • یک یا چند آینه که تمام پیام ها و ابرداده ها را از صف اصلی دریافت می کند. این آینه ها برای پوسته پوسته شدن وجود ندارند، بلکه صرفاً برای افزونگی هستند.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 2. آینه کاری صف

آینه سازی توسط خط مشی مناسب تنظیم می شود. در آن می توانید ضریب تکرار و حتی گره هایی را که صف باید روی آنها قرار گیرد را انتخاب کنید. مثال ها:

  • ha-mode: all
  • ha-mode: exactly, ha-params: 2 (یک استاد و یک آینه)
  • ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2

تایید ناشر

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

صف شکست

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

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 3. صف های چندگانه آینه ای و سیاست های آنها

بروکر 3 پایین می آید. توجه داشته باشید که آینه صف C در Broker 2 در حال ارتقاء به Master است. همچنین توجه داشته باشید که یک آینه جدید برای صف C در Broker 1 ایجاد شده است. RabbitMQ همیشه سعی می کند ضریب تکرار مشخص شده در خط مشی های شما را حفظ کند.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 4. کارگزار 3 از کار می افتد و باعث می شود صف C از کار بیفتد

بروکر 1 بعدی سقوط می کند! فقط یک دلال داریم. آینه صف B به استاد ارتقا می یابد.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
شکل 5

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

در این مورد، از دست دادن بروکر 1 و داده ها کامل بود، بنابراین صف بی آینه B به طور کامل از بین رفت.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 6. کارگزار 1 به خدمت باز می گردد

Broker 3 دوباره آنلاین شده است، بنابراین صف‌های A و B آینه‌های ایجاد شده روی آن را برمی‌گردانند تا سیاست‌های HA خود را برآورده کنند. اما اکنون تمام صف های اصلی روی یک گره هستند! این ایده آل نیست، توزیع یکنواخت بین گره ها بهتر است. متأسفانه، در اینجا گزینه های زیادی برای تعادل مجدد Masters وجود ندارد. ما بعداً به این موضوع باز خواهیم گشت زیرا ابتدا باید به همگام سازی صف نگاه کنیم.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 7. کارگزار 3 به خدمت برمی گردد. تمام صف های اصلی در یک گره!

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

همگام سازی

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

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

ما دو صف آینه ای داریم. صف A به صورت خودکار و صف B به صورت دستی همگام می شوند. هر دو صف حاوی ده پیام هستند.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 8. دو صف با حالت های هماهنگ سازی مختلف

حالا بروکر 3 را از دست می دهیم.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 9. کارگزار 3 سقوط کرد

کارگزار 3 به خدمت بازمی گردد. خوشه یک آینه برای هر صف در گره جدید ایجاد می کند و به طور خودکار صف A جدید را با master همگام می کند. با این حال، آینه صف B جدید خالی می ماند. به این ترتیب ما افزونگی کامل در صف A و فقط یک آینه برای پیام های صف B موجود داریم.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 10. آینه جدید صف A تمام پیام های موجود را دریافت می کند، اما آینه جدید صف B دریافت نمی کند.

ده پیام دیگر در هر دو صف می رسد. سپس Broker 2 از کار می‌افتد و صف A به قدیمی‌ترین آینه که روی Broker 1 است برمی‌گردد. در صورت خرابی، داده‌ای از دست نمی‌رود. در صف B، بیست پیام در مستر و فقط ده پیام در آینه وجود دارد، زیرا این صف هرگز ده پیام اصلی را تکرار نمی کند.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 11. صف A بدون از دست دادن پیام به Broker 1 برمی گردد

ده پیام دیگر در هر دو صف می رسد. اکنون Broker 1 خراب می شود. صف A به راحتی بدون از دست دادن پیام به آینه تغییر می کند. با این حال، صف B مشکل دارد. در این مرحله می‌توانیم در دسترس بودن یا سازگاری را بهینه کنیم.

اگر می‌خواهیم دسترسی را بهینه کنیم، پس سیاست ha-promote-on-failure باید نصب شود همیشه. این مقدار پیش فرض است، بنابراین به سادگی نمی توانید خط مشی را مشخص کنید. در این مورد، ما اساساً در آینه‌های غیرهمگام به خرابی اجازه می‌دهیم. این باعث می شود پیام ها از بین بروند، اما صف قابل خواندن و نوشتن باقی می ماند.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 12. صف A بدون از دست دادن پیام ها به بروکر 3 برمی گردد. صف B با از دست دادن ده پیام به Broker 3 برمی گردد

ما هم می توانیم نصب کنیم ha-promote-on-failure به معنا when-synced. در این حالت، به جای بازگشت به آینه، صف منتظر می ماند تا Broker 1 با داده هایش به حالت آنلاین بازگردد. پس از بازگشت، صف اصلی بدون هیچ گونه از دست دادن داده به بروکر 1 بازگشته است. در دسترس بودن قربانی امنیت داده ها می شود. اما این یک حالت مخاطره آمیز است که حتی می تواند منجر به از دست دادن کامل داده ها شود که به زودی به آن خواهیم پرداخت.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 13. صف B پس از از دست دادن بروکر 1 در دسترس باقی می ماند

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

بیایید به یک مثال نگاه کنیم. الان صف های خیلی طولانی داریم. چگونه می توانند به چنین اندازه ای رشد کنند؟ به چندین دلیل:

  • صف ها به طور فعال استفاده نمی شوند
  • اینها صف های پرسرعت هستند و در حال حاضر مصرف کنندگان کند هستند
  • صف های پرسرعت است، مشکلی وجود دارد و مصرف کنندگان در حال پیگیری هستند

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 14. دو صف بزرگ با حالت های هماهنگ سازی مختلف

اکنون بروکر 3 سقوط می کند.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 15. بروکر 3 می افتد و در هر صف یک استاد و آینه باقی می ماند

Broker 3 دوباره آنلاین می شود و آینه های جدید ایجاد می شود. صف اصلی A شروع به تکرار پیام های موجود در آینه جدید می کند و در این مدت صف در دسترس نیست. دو ساعت طول می کشد تا داده ها تکرار شوند، در نتیجه دو ساعت از کار افتادن برای این Queue!

با این حال، صف B در تمام طول دوره در دسترس است. او مقداری افزونگی را فدای دسترسی کرد.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 16. صف در طول همگام سازی در دسترس باقی می ماند

پس از دو ساعت، صف A نیز در دسترس می شود و می تواند دوباره خواندن و نوشتن را بپذیرد.

به روز رسانی

این رفتار مسدود کننده در هنگام همگام سازی، به روز رسانی خوشه ها را با صف های بسیار بزرگ دشوار می کند. در برخی موارد، گره اصلی نیاز به راه اندازی مجدد دارد، به این معنی که یا به یک آینه سوئیچ کنید یا صف را در حین ارتقای سرور غیرفعال کنید. اگر انتقال را انتخاب کنیم، اگر آینه‌ها هماهنگ نباشند، پیام‌ها را از دست خواهیم داد. به‌طور پیش‌فرض، در هنگام قطع کارگزار، یک خطا به یک آینه غیرهمگام انجام نمی‌شود. یعنی به محض بازگشت کارگزار هیچ پیامی را از دست نمی دهیم، تنها آسیب یک صف ساده بود. قوانین رفتار هنگام قطع ارتباط کارگزار توسط خط مشی تعیین می شود ha-promote-on-shutdown. می توانید یکی از دو مقدار را تنظیم کنید:

  • always= انتقال به آینه های غیرهمگام فعال است
  • when-synced= انتقال فقط به یک آینه همگام، در غیر این صورت صف غیرقابل خواندن و غیرقابل نوشتن می شود. به محض بازگشت کارگزار، صف به خدمت باز می گردد

به هر حال، با صف های بزرگ، باید بین از دست دادن داده ها و در دسترس نبودن، یکی را انتخاب کنید.

وقتی در دسترس بودن امنیت داده ها را بهبود می بخشد

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

در اینجا باید موارد زیر را در نظر بگیرید:

  • آیا ناشر می تواند به سادگی یک خطا را برگرداند و سرویس بالادستی یا کاربر بعداً دوباره امتحان کند؟
  • آیا ناشر می تواند پیام را به صورت محلی یا در پایگاه داده ذخیره کند تا بعداً دوباره امتحان کند؟

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

بنابراین باید به دنبال تعادل بود و راه حل بستگی به شرایط خاص دارد.

مشکلات ha-promote-on-failure=when-synced

فکر ha-promote-on-failure= وقتی همگام سازی شد این است که از جابجایی به یک آینه غیرهمگام جلوگیری می کنیم و در نتیجه از دست دادن داده ها جلوگیری می کنیم. صف ناخوانا یا قابل نوشتن باقی می ماند. در عوض، ما سعی می‌کنیم کارگزار خراب شده را با داده‌های دست نخورده آن بازیابی کنیم تا بتواند بدون از دست دادن داده‌ها، به‌عنوان اصلی کار کند.

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

برای اضافه کردن مجدد یک گره با همین نام، به خوشه می گوییم که گره گم شده را فراموش کند (با دستور rabbitmqctl forget_cluster_node) و یک بروکر جدید با همان نام میزبان راه اندازی کنید. در حالی که خوشه گره گم شده را به خاطر می آورد، صف قدیمی و آینه های همگام نشده را به خاطر می آورد. وقتی به یک خوشه گفته می شود که یک گره یتیم را فراموش کند، آن صف نیز فراموش می شود. اکنون باید آن را مجدداً اعلام کنیم. ما همه داده ها را از دست دادیم، اگرچه آینه هایی با مجموعه ای جزئی از داده ها داشتیم. بهتر است به یک آینه غیر همگام سوئیچ کنید!

بنابراین، همگام سازی دستی (و عدم همگام سازی) در ترکیب با ha-promote-on-failure=when-synced، به نظر من، بسیار خطرناک است. اسناد می گویند که این گزینه برای امنیت داده ها وجود دارد، اما این یک چاقوی دو لبه است.

تعادل مجدد استاد

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

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

  • هیچ ابزار خوبی برای انجام تعادل مجدد وجود ندارد
  • همگام سازی صف

شخص ثالثی برای تعادل مجدد وجود دارد افزونه، که به طور رسمی پشتیبانی نمی شود. در مورد پلاگین های شخص ثالث در کتابچه راهنمای RabbitMQ گفت: "این افزونه برخی از ابزارهای پیکربندی و گزارش اضافی را ارائه می دهد، اما توسط تیم RabbitMQ پشتیبانی یا تأیید نمی شود. با مسئولیت خود استفاده کنید."

ترفند دیگری برای انتقال صف اصلی از طریق سیاست های HA وجود دارد. دفترچه راهنما اشاره می کند اسکریپت برای این. اینطوری کار میکنه:

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

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

حال بیایید ببینیم که خوشه های RabbitMQ چگونه با پارتیشن های شبکه کار می کنند.

از دست دادن اتصال

گره های یک سیستم توزیع شده توسط پیوندهای شبکه به هم متصل می شوند و پیوندهای شبکه می توانند قطع شوند و قطع خواهند شد. تعداد قطعی ها به زیرساخت محلی یا قابلیت اطمینان ابر انتخاب شده بستگی دارد. در هر صورت، سیستم های توزیع شده باید بتوانند با آنها کنار بیایند. یک بار دیگر ما بین در دسترس بودن و سازگاری انتخاب داریم، و دوباره خبر خوب این است که RabbitMQ هر دو گزینه را ارائه می دهد (فقط نه در یک زمان).

با RabbitMQ ما دو گزینه اصلی داریم:

  • اجازه تقسیم منطقی (تقسیم مغز). این در دسترس بودن را تضمین می کند، اما ممکن است باعث از دست رفتن داده شود.
  • جداسازی منطقی را غیرفعال کنید. ممکن است بسته به نحوه اتصال مشتریان به خوشه منجر به از دست دادن کوتاه مدت در دسترس بودن شود. همچنین می تواند منجر به عدم دسترسی کامل در یک خوشه دو گره شود.

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

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

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

حالت های مختلف RabbitMQ یا در دسترس بودن یا سازگاری را فراهم می کند.

حالت نادیده گرفتن (پیش‌فرض)

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

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 18. سه ناشر با سه کارگزار مرتبط هستند. در داخل، خوشه تمام درخواست ها را به صف اصلی بروکر 2 هدایت می کند.

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

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 19. تقسیم منطقی (شکاف مغز). رکوردها به دو صف اصلی می روند و دو نسخه از هم جدا می شوند.

اتصال بازیابی شده است، اما جدایی منطقی باقی می ماند. مدیر باید به صورت دستی طرف بازنده را انتخاب کند. در مورد زیر، مدیر بروکر 3 را مجددا راه اندازی می کند.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 20. مدیر بروکر 3 را غیرفعال می کند.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 21. مدیر بروکر 3 را راه اندازی می کند و به خوشه می پیوندد و همه پیام هایی را که در آنجا باقی مانده اند از دست می دهد.

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

حالت Autoheal

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

مکث حالت اقلیت

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

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 22. سه ناشر با سه کارگزار مرتبط هستند. در داخل، خوشه تمام درخواست ها را به صف اصلی بروکر 2 هدایت می کند.

سپس کارگزاران 1 و 2 از کارگزار 3 جدا می شوند. به جای اینکه آینه خود را به Master معرفی کند، Broker 3 به حالت تعلیق درآمده و در دسترس نیست.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 23. بروکر 3 مکث می کند، همه مشتریان را قطع می کند و درخواست های اتصال را رد می کند.

پس از بازیابی اتصال، به خوشه باز می گردد.

بیایید به مثال دیگری نگاه کنیم که در آن صف اصلی در Broker 3 است.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 24. صف اصلی بروکر 3.

سپس همان از دست دادن اتصال رخ می دهد. بروکر 3 مکث می کند زیرا در سمت کوچکتر قرار دارد. از طرف دیگر، گره‌ها می‌بینند که Broker 3 افتاده است، بنابراین آینه قدیمی‌تر از Brokers 1 و 2 به Master ارتقا می‌یابد.

RabbitMQ در مقابل کافکا: تحمل خطا و در دسترس بودن بالا در خوشه ها
برنج. 25. اگر بروکر 2 در دسترس نباشد، به کارگزار 3 منتقل شوید.

هنگامی که اتصال بازیابی شد، Broker 3 به خوشه می پیوندد.

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

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

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

اطمینان از ارتباط با مشتری

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

گزینه های ما:

  • خوشه با استفاده از یک متعادل کننده بار قابل دسترسی است که به سادگی از طریق گره ها می چرخد ​​و کلاینت ها دوباره سعی می کنند تا زمانی که موفقیت آمیز باشد وصل شوند. اگر یک گره از کار بیفتد یا معلق باشد، تلاش برای اتصال به آن گره با شکست مواجه خواهد شد، اما تلاش‌های بعدی به سرورهای دیگر می‌روند (به صورت دورگرد). این برای از دست دادن کوتاه مدت اتصال یا یک سرور از کار افتاده که به سرعت بازیابی می شود مناسب است.
  • از طریق یک متعادل کننده بار به خوشه دسترسی داشته باشید و گره های معلق/شکست خورده را به محض شناسایی از لیست حذف کنید. اگر این کار را به سرعت انجام دهیم، و اگر مشتریان بتوانند اتصال را دوباره امتحان کنند، در آن صورت به دسترسی ثابت دست خواهیم یافت.
  • به هر کلاینت لیستی از تمام گره ها بدهید و مشتری به طور تصادفی یکی از آنها را هنگام اتصال انتخاب می کند. اگر هنگام تلاش برای اتصال خطایی دریافت کرد، تا زمانی که متصل شود به گره بعدی در لیست منتقل می شود.
  • با استفاده از DNS ترافیک را از یک گره شکست خورده/معلق حذف کنید. این کار با استفاده از یک TTL کوچک انجام می شود.

یافته ها

خوشه بندی RabbitMQ مزایا و معایب خود را دارد. جدی ترین معایب این است که:

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

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

  • شبکه غیر قابل اعتماد
  • ذخیره سازی غیر قابل اعتماد
  • صف های بسیار طولانی

در مورد تنظیمات دسترسی بالا، موارد زیر را در نظر بگیرید:

  • ha-promote-on-failure=always
  • ha-sync-mode=manual
  • cluster_partition_handling=ignore (یا autoheal)
  • پیام های مداوم
  • هنگامی که برخی از گره ها از کار می افتند، اطمینان حاصل کنید که مشتریان به گره فعال متصل می شوند

برای ثبات (امنیت داده ها)، تنظیمات زیر را در نظر بگیرید:

  • تایید ناشر و قدردانی دستی از طرف مصرف کننده
  • ha-promote-on-failure=when-synced، اگر ناشران بتوانند بعداً دوباره امتحان کنند و اگر فضای ذخیره‌سازی بسیار مطمئنی دارید! در غیر این صورت قرار دهید =always.
  • ha-sync-mode=automatic (اما برای صف‌های غیرفعال بزرگ، حالت دستی ممکن است مورد نیاز باشد؛ همچنین، در نظر بگیرید که آیا در دسترس نبودن باعث از بین رفتن پیام‌ها می‌شود)
  • مکث حالت اقلیت
  • پیام های مداوم

ما هنوز همه مسائل مربوط به تحمل خطا و در دسترس بودن بالا را پوشش نداده ایم. به عنوان مثال، نحوه اجرای ایمن رویه های اداری (مانند به روز رسانی های چرخشی). همچنین باید در مورد فدراسیون و افزونه Shovel صحبت کنیم.

اگر چیز دیگری را از دست دادم، لطفاً به من بگویید.

من را نیز ببینید ارسال، جایی که من با استفاده از Docker و Blockade برای آزمایش برخی از سناریوهای از دست دادن پیام توضیح داده شده در این مقاله، خرابکاری را روی یک خوشه RabbitMQ انجام می دهم.

مقالات قبلی این مجموعه:
شماره 1 - habr.com/ru/company/itsumma/blog/416629
شماره 2 - habr.com/ru/company/itsumma/blog/418389
شماره 3 - habr.com/ru/company/itsumma/blog/437446

منبع: www.habr.com

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