در سیستم های توزیع شده که بر پایه Event-Driven Architecture می باشند ترتیب رویدادها یکی مهم ترین چالش ها می باشد. منظور از آن ترتیب دقیق رخ دادن رویدادها و پردازش ها آن ها در سیستم می باشد. خیلی از اوقات نیاز داریم که رویدادها به ترتیب صحیحی پردازش شوند تا سیستم به شکل صحیح کار کند.
برای مثال تلگرام را در نظر بگیرید, میخواهیم دو پیام به دوستمان ارسال کنیم:
1- سلام.
2- خوبی؟
در اینجا توقع داریم که دوستمان پیام ها را به همان ترتیبی که ارسال کردیم ببینید. حال به دلیل توزیع شده بودن و مشکلاتی مانند ترافیک زیاد, تاخیر و... ممکن است پیام های ما با ترتیب نادرست ارسال شوند. برای همین نیاز می باشد که ترتیب آن ها را حفظ کنیم. همچنین این یک مثال از Causal Consistency می باشد: https ://lnkd.in/di7Hun55
اهمیت
حفظ هم زمانی داده ها: بعضی از سیستم ها وابسته به ترتیب خاصی از رویدادها هستند که در صورت رعایت نشدن ترتیب ها سیستم با مشکل مواجه می شود. برای مثال رویدادهای مربوط به پروسه رزرو اتاق در هتل ها یا همان تلگرام!
سازگاری (Consistency): گاهی اوقات ممکن است بخش های مختلف رویدادها را به ترتیب های مختلف دریافت کنند که این می تواند باعث inconsistency شود.
تحمل خطا (Fault Tolerance): زمانی که یک بخشی از سیستم دچار مشکل می شود نیاز به پردازش مجدد رویدادها به ترتیب قبلی داریم.
چالش ها
تاخیر در شبکه (Latency): تاخیر در شبکه می تواند باعث بهم ریختن و پردازش زودتر برخی از رویدادها به ترتیب اشتباه شود.
بازیابی از خرابی ها: زمانی که یک سیستم بعد از خرابی مجدد راه اندازی می شود باید تمام رویدادهای از دست رفته را مجدد پردازش کند.
توزیع رویدادها بین چندین نود: در سیستم های توزیع شده با توجه به ارسال رویدادها به چندین نود مختلف امکان دارد هر نود رویدادها را به ترتیب متفاوتی مشاهده کند.
راهکارها
پارتیشن بندی بر اساس کلید (Partitioning by Key): یکی از معروف ترین روش ها استفاده از پارتیبشن بندی بر اساس یک کلید خاص (مثل آیدی) می باشد. در این روش تمام رویدادها با یک کلید خاص به یک پارتیشن ارسال می شوند و ترتیب آنها حفظ می شود. برای مثال کافکا
نسخه بندی (Versioning): در این روش هر رویداد یک ورژن خاص دارد که نشان دهنده ترتیب آن رویداد در سیستم می باشد. در این روش اگر رویدادها به ترتیب صحیح دریافت نشوند می توان با بررسی ورژن ترتیب صحیح را بازسازی کرد.
ترتیب بر اساس علت و معلول (Causal Ordering): در این روش روابط علت و معلولی بین رویدادها بررسی می شود تا رویدادهای وابسته به ترتیب پردازش شوند.
پردازش بدون تکرار (Idempotent Processing): در این روش حتی اگر رویدادها چندین بار پردازش شوند نتیجه نهایی یکسان خواهد بود که این باعث کاهش مشکلات ناشی از ترتیب رویدادها می شود.
پخش با ترتیب کلی (Total Order Broadcast): در این روش از پروتکل های توزیع شده مانند Raft یا Paxos استفاده می شود تا ترتیب کلی رویدادها بین تمام نودها حفظ شود.
پترن Outbox: ابتدا رویدادها در دیتابیس ذخیره و سپس ارسال و پردازش می شوند که این کار باعث اطمینان از ترتیب پردازش رویدادها می شود.
در پایان, باید بدانیم که توجه به ترتیب رویدادها و استفاده از روش مناسب در سیستم های توزیع شده با معماری Event-Driven بسیار مهم و ضروری می باشد. زیرا می تواند از بروز مشکلات ناشی از پردازش اشتباه رویدادها جلوگیری کند.