توی سیستمهای توزیعشده، هماهنگ نگه داشتن دادهها بین نودهای مختلف همیشه یکی از چالشهای مهم و البته جذاب بوده. مخصوصاً وقتی چند نود بهصورت همزمان امکان Write داشته باشن و انتظار بره دادهها در نهایت روی همه نودها به وضعیت یکسانی برسن.
یکی از رویکردهای قابل استفاده برای حل این مسئله، پیادهسازی Replication در لایه Application و بر بستر Event Streaming هست. در چنین معماریای، تغییرات داده بهجای اینکه مستقیماً از طریق مکانیزمهای Replication دیتابیس منتقل بشن، بهصورت Event منتشر و توسط سایر نودها مصرف میشن.
برای این کار، میشه تغییرات دیتابیس شامل Add, Update و Soft Delete رو در لحظه Commit شناسایی کرد و از طریق الگوی Outbox برای انتشار آماده کرد. از سمت مقابل نیز Consumerهایی مسئول دریافت این رویدادها، اعمال مکانیزمهای Idempotency و مدیریت خطاها از طریق DLQ خواهند بود تا تغییرات در مقصد بهصورت قابل اعتماد اعمال بشن.
در سناریوهای Multi-Master اینچنینی، اولین چالش جدی معمولاً مدیریت Conflict دادههاست. زمانی که چند نود بهطور مستقل روی یک رکورد تغییر ایجاد میکنن، باید مکانیزمی برای تعیین نسخه نهایی وجود داشته باشه. یکی از سادهترین و در عین حال رایجترین راهکارها، Last-Write-Wins (LWW) هست که در آن آخرین تغییر ثبتشده بر اساس زمان وقوع، بهعنوان نسخه معتبر در نظر گرفته میشه.
چالش مهم بعدی به شناسههای داده برمیگرده. در معماریهایی که چند نود بهصورت مستقل داده تولید میکنن، استفاده از Primary Keyهای Auto-Increment معمولاً به تداخل منجر میشه. به همین دلیل استفاده از شناسههای Globally Unique اهمیت پیدا میکنه. GUID v7 یکی از گزینههای جذاب برای این سناریوهاست؛ چون علاوه بر یکتا بودن، به دلیل داشتن Timestamp داخلی، قابلیت Sort شدن داره و نسبت به GUIDهای سنتی رفتار بهتری از نظر ایندکسگذاری ارائه میکنه.
ممکنه این سؤال مطرح بشه که چرا بهجای چنین رویکردی از Replication نیتیو دیتابیس استفاده نشه؟ پاسخ اینه که در بسیاری از موارد، مسئله صرفاً انتقال داده بین چند دیتابیس مشابه نیست. گاهی نیاز داریم کانفلیکتها در لایه Application مدیریت بشن، دادهها قبل از اعمال شدن دچار Transformation بشن یا حتی نودها از تکنولوژیهای ذخیرهسازی متفاوتی استفاده کنن.
مزیت دیگهی این رویکرد، وجود یک Log پایدار از تمام تغییرات سیستم هست. با استفاده از Kafka، رویدادها برای مدت مشخصی نگهداری میشن و هر Consumer میتونه مستقل از سایر اجزا وضعیت خودش رو بازیابی کنه. در نتیجه اگر نودی برای مدت طولانی از دسترس خارج بشه، پس از بازگشت میتونه از آخرین Offset پردازششده ادامه بده و خودش رو با وضعیت فعلی سیستم همگام کنه.
از طرفی، Eventهایی که برای Replication تولید میشن معمولاً کاربردشون به همینجا محدود نمیمونه. همون جریان رویداد میتونه توسط سرویسهای دیگه برای Cache Invalidation، Analytics، Audit Logging، Search Indexing یا انواع پردازشهای جانبی مصرف بشه. به همین دلیل، مکانیزم همگامسازی عملاً به بخشی از زیرساخت Event-Driven کل سیستم تبدیل میشه.
پیادهسازی چنین معماریای قطعاً بدون هزینه نیست و پذیرش Eventual Consistency هم چالشهای خودش رو به همراه داره. اما در ازای این پیچیدگی، سیستمی به دست میاد که نودها میتونن مستقل عمل کنن، کانفلیکتها بهصورت کنترلشده مدیریت بشن و همگامسازی دادهها بدون وابستگی مستقیم به نوع دیتابیس یا ساختار استقرار انجام بشه.
Post #3283
2.14K
Forwarded from Mahi in Tech
- ❤ 12
- 👎 1