به طور معمول، برنامههای مدرن از موتورهای دیتابیس مختلف استفاده میکنند، هر یک سرویس خاصی را ارائه میدهد. در تحویل آژروت سفارشها، از پایگاه داده MySQL برای ذخیره فرمهای اصلی داده استفاده میشود و از Elasticsearch برای ارائه قابلیتهای جستجوی پیشرفته استفاده میشود. MySQL به عنوان ابزار اصلی ذخیرهسازی دادههای خام عمل میکند و Elasticsearch به عنوان ذخیرهسازی تبعیت شده.
تلاشهایی برای همزمانسازی دادهها بین MySQL و Elasticsearch انجام شده است. در این پست، مجموعهای از تکنیکها برای بهینهسازی فرایند نمایهسازی دادههای جستجوی تدریجی معرفی خواهد شد.
زمینه
همگامسازی دادهها از ذخیرهسازی اصلی داده تا ذخیرهسازی مشتقشده داده توسط پلتفرم Food-Puxian، یک پلتفرم همگامسازی داده (DSP)، برعهده است. در یک سرویس جستجو، همگامسازی دادهها بین MySQL و Elasticsearch صورت میگیرد.
فرایند همگامسازی داده برای هر بروزرسانی داده زمان واقعی در MySQL فعال میشود و دادههای بروزرسانی شده به صورت جریانهای Kafka تجمیع میشوند. DSP لیستی از جریانهای Kafka را مصرف میکند و شاخصهای جستجو مربوطه را در Elasticsearch به صورت تدریجی بروزرسانی میکند. این فرایند همچنین به عنوان همگامسازی تدریجی شناخته میشود.
Kafka به DSP
DSP از جریانهای Kafka برای پیادهسازی همگامسازی تدریجی استفاده میکند. هر جریان مجموعهایی از دادههای بدون محدودیت، به صورت مداوم به روز میشوند است که مرتب، قابل بازپخش و مقاوم در برابر خطا هستند.
نمودار فوق نحوه همگامسازی دادهها با استفاده از Kafka را نشان میدهد. تولیدکننده داده برای هر عملیاتی که در MySQL صورت میگیرد، یک جریان Kafka ایجاد میکند و آن را به صورت زمان واقعی به Kafka ارسال میکند. DSP برای هر جریان Kafka یک مصرفکننده جریان ایجاد میکند و مصرفکننده دادههای بروزرسانی را از جریانهای Kafka مربوطه خوانده و آنها را در Elasticsearch همگامسازی میکند.
از MySQL به Elasticsearch
شاخصها در Elasticsearch با جداول در MySQL مطابقت دارند. دادههای MySQL در جداول ذخیره میشوند، در حالی که دادههای Elasticsearch در شاخصها ذخیره میشوند. چندین جدول MySQL برای ایجاد یک شاخص Elasticsearch پیوست میشوند. فریبکاوی زیر به تصویر کشیدن تطابق موجودیت-رابطه در MySQL و Elasticsearch میپردازد. موجودیت ای یک رابطه یک-به-چند با موجودیت ب دارد. موجودیت ای جداول مرتبط چندین در MySQL دارد، جدول A1 و A2 و آنها در یک شاخص Elasticsearch یکپارچه میشوند.
گاهی اوقات یک شاخص جستجو شامل هم موجودیت ای و هم موجودیت ب است. در یک پرسمان جستجو با کلماتکلیدی در این شاخص، مثلاً «برگر»، اشیاءی از هر دو موجودیت ای و هم موجودیت ب که نام آنها شامل «برگر» باشد، در پاسخ جستجو نمایش داده میشوند.
همگامسازی تدریجی اصلی
جریانهای Kafka اصلی
تولیدکنندگان داده جریان Kafka برای هر جدول MySQL در نمودار ER فوق ایجاد میکنند. هر بار که در جداول MySQL عملیات درج، بروزرسانی یا حذف انجام میشود، یک کپی از داده بعد از اجرای عملیات به جریان Kafka مربوطه ارسال میشود. DSP برای هر جریان Kafka مصرفکنندههای جریان مختلفی ایجاد میکند زیرا ساختار دادههای آنها متفاوت است.
زیرساخت مصرفکننده جریان
مصرفکننده جریان شامل 3 مولفه است.
- پخش کننده رویداد: رویدادها را از جریان Kafka گوش میدهد و آنها را به بافر رویداد ارسال میکند و برای هر رویدادی که شناسهاش در بافر رویداد وجود نداشته باشد، یک goroutine را برای اجرای دستگاه پخش رویداد راهاندازی میکند.بافر رویداد: رویدادها را بر اساس کلید اصلی (aID، bID و غیره) در حافظه نهان میکند. یک رویداد تا زمانی که توسط یک goroutine برداشت نشده یا در صورت اضافه شدن یک رویداد جدید با همان کلید اصلی، جایگزین شود در بافر باقی میماند.واسطهگر رویداد: یک رویداد را از بافر رویداد برداشت میکند و goroutine توسط پخش کننده رویداد راهاندازی شده آن را پردازش میکند.
روند بافر رویداد
بافر رویداد شامل بسیاری از زیربافرها است، هرکدام با یک شناسه یکتا که کلید اصلی رویداد نهانشده در آن است. حداکثر اندازه یک زیربافر ۱ است. این به بافر رویداد اجازه میدهد رویدادهایی که همان شناسه را دارند در بافر تکرار شوند را حذف کند.
نمودار زیر نمایش روند فشار دادن یک رویداد به بافر رویداد را نشان میدهد. هنگامی که یک رویداد جدید به بافر فشار داده میشود، رویداد قدیمی که همان شناسه را به اشتراک میگذارد جایگزین میشود. رویداد جایگزین شده بنابراین پردازش نمیشود.
روند دستگاه پردازشکننده رویداد
نمودار جریان کار دستگاه پردازشکننده رویدادها را نشان میدهد. این شامل جریان کار دستگاه پردازش معمول (در رنگ سفید) و روندهای اضافی برای رویدادهای شیء ب (در رنگ سبز) است. پس از ایجاد یک سند Elasticsearch جدید با دادههای بارگیری شده از پایگاه داده، سند اصلی را از Elasticsearch به منظور مقایسه بازیابی کرده و تصمیم میگیرد که آیا ارسال سند جدید به Elasticsearch ضروری است یا خیر.
هنگام پردازش رویداد شیء ب، در کنار جریان کار همگانی، همچنین به روزرسانی مرتبط به شیء الف در شاخص Elasticsearch را پخش میکند. این نوع عملیات را به عنوان به روزرسانی پیوسته مینامیم.
مشکلات در زیرساخت اصلی
داده در یک شاخص Elasticsearch ممکن است از چندین جدول MySQL مختلف به دست آید، همانطور که در زیر نشان داده شده است.
زیرساخت اصلی با چند مشکل همراه بود.
- بار سنگین بانک اطلاعاتی: مصرفکنندهها از جریانهای Kafka خواندن میکنند، رویدادهای جریان را به عنوان اعلانها میپذیرند و سپس با استفاده از شناسهها از بانک اطلاعاتی برای بارگیری داده و ایجاد یک سند Elasticsearch جدید استفاده میکنند. دادههای در رویدادهای جریان به خوبی استفاده نمیشوند. بارگیری داده از بانک اطلاعاتی در هر بار ایجاد سند Elasticsearch جدید منجر به ترافیک سنگین به بانک اطلاعاتی میشود. بانک اطلاعاتی به عنوان موانع میماند.گمشدن داده: تولیدکنندگان داده کپیهایی از دادهها را به Kafka در کد برنامه ارسال میکنند. تغییرات داده انجام شده از طریق ابزار خطفرمان MySQL (CLT) یا ابزار مدیریت دیتابیس دیگر گم میشوند.ارتباط نزدیک با ساختار جدول MySQL: اگر تولیدکنندگان ستون جدیدی را به یک جدول موجود در MySQL اضافه کنند و این ستون نیاز به همگامسازی با Elasticsearch باشد، DSP قادر به دریافت تغییرات دادههای این ستون نخواهد بود تا زمانی که تولیدکنندگان تغییرات کد را انجام داده و ستون را به جریان Kafka مربوطه اضافه کنند.به روزرسانیهای تکراری Elasticsearch: دادههای Elasticsearch زیرمجموعهای از دادههای MySQL هستند. تولیدکنندگان داده را به جریانهای Kafka منتشر میکنند حتی اگر تغییراتی در فیلدهایی ایجاد شود که مربوط به Elasticsearch نباشند. این رویدادهای جریانی که به Elasticsearch مربوط نیستند، همچنان برداشت شده میشوند.به روزرسانیهای تکراری پیوسته: یک مورد را در نظر بگیرید که شاخص جستجو هم شیء الف و هم شیء ب را شامل میشود. تعداد زیادی از به روزرسانیها در شیء ب در یک بازه زمانی کوتاه ایجاد میشود. همه به روزرسانیها به شاخصی که شیء الف و شیء ب را شامل میشود پیوست میشوند. این باعث ایجاد ترافیک سنگین در بانک اطلاعاتی میشود.
همگامسازی تدریجی بهینهشده
MySQL Binlog
MySQL binary log (Binlog) مجموعهای از فایلهای لاگ است که شامل اطلاعاتی درباره تغییرات اعمال شده بر روی یک نمونه سرور MySQL است. این شامل تمامی عباراتی است که داده را به روز میکنند. دو نوع باینری لاگها وجود دارد:
- بینهای سطح عبارت: رویدادها شامل عبارات SQL هستند که تغییرات دادهها را تولید میکنند (درج، بروزرسانی، حذف).
تیم Caspian از تیم مجله زیبایی و درمانی آژروت (Data Tech) یک سیستم Capture Data Change (CDC) بر اساس Binlog سطح ردیف MySQL ایجاد کرده است. این سیستم تمامی تغییرات دادههای انجام شده بر روی جداول MySQL را ثبت میکند.
جریانهای Kafka فعلی
تعریف رویداد جریان Binlog است