فرض کنید یک فروشگاه سفارشهای هر مشتری را در MySQL نگه میدارد. با بزرگ شدن جدول، تیم تصمیم میگیرد داده را در چند سرور تقسیم کند. مشکل اصلی پس از تقسیم پدیدار میشود. برنامه هنگام ثبت سفارش باید بداند ردیف به کدام سرور میرود و هنگام نمایش سابقه مشتری باید همان ردیف را پیدا کند. افزون بر این، جابهجایی داده در آینده باید بدون بازنویسی مسیرهای فراوان برنامه امکانپذیر باشد. Vitess این تصمیمهای مسیریابی را در لایهای میان کلاینت و مجموعه پایگاههای MySQL سامان میدهد. برای فهم اثر آن بر برنامه، باید مسیر خواندن و نوشتن یک سفارش را دنبال کنیم.
Keyspace و shard در مدل داده فروشگاه
در واژگان Vitess، یک keyspace پایگاه داده منطقی است که میتواند به یک یا چند shard تقسیم شود. هر شارد بخش معینی از فضای کلید را نگه میدارد. همان طرح جدول میتواند روی شاردهای مختلف وجود داشته باشد، ولی ردیفهای متعلق به هر شارد متفاوتاند. از نگاه برنامه همچنان جدول سفارش وجود دارد و مقصد تغییرها از روی قواعد مسیریابی تعیین میشود. از نگاه اپراتور، هر شارد مجموعهای از منابع و فرایندهای پایگاه داده دارد که باید جداگانه پایش شوند. خطا در یکی از این مجموعهها میتواند فقط بخشی از درخواستهای مشتریان را درگیر کند.
اگر تمام سفارشهای یک مشتری روی یک شارد قرار گیرند، نمایش سابقه یا ثبت تغییرهای مربوط به آن مشتری ممکن است در همان محل انجام شود. در مقابل، یک گزارش سراسری درباره همه مشتریان میتواند به چندین شارد نیاز داشته باشد. انتخاب کلید تقسیم باید هم حجم داده و هم الگوی دسترسی را در نظر بگیرد. توزیع یکنواخت تعداد مشتریان کافی نیست. ممکن است یک مشتری بزرگ به تنهایی بیشتر حجم و ترافیک یک شارد را ایجاد کند. پیش از انتخاب کلید، توزیع تاریخچه سفارشها، سهم مشتریان پرترافیک و پرسوجوهای اصلی را با داده واقعی اندازه بگیرید.
VTGate هنگام دریافت پرسوجو چه میکند؟
کلاینت به VTGate وصل میشود. این مؤلفه درخواست را تحلیل میکند، از اطلاعات طرح مجازی برای تعیین مقصد کمک میگیرد و اجرای کار روی شاردهای لازم را هماهنگ میکند. در یک پرسوجوی هدفمند، شرط مربوط به کلید مسیریابی اجازه میدهد درخواست به مقصد مشخصی برود. مثلاً اگر شناسه مشتری مبنای توزیع باشد، جستوجوی سفارشهای همان مشتری معمولاً مسیر روشنتری دارد. در گزارشهای گسترده، VTGate ممکن است نیاز داشته باشد بخشی از کار را میان چند مقصد توزیع و نتایج را ترکیب کند. سادگی متن SQL برای نویسنده برنامه به معنی سادگی برنامه اجرای توزیعشده نیست.
شکایت کاربر درباره کندی یک گزارش را میتوان با همین مسیر بررسی کرد. ابتدا طرح اجرا و شمار مقصدهای درگیر را نگاه کنید. سپس زمان اجرای بخش محلی روی MySQL و هزینه انتقال یا ترکیب نتایج را تفکیک کنید. ممکن است هر شارد پاسخ سریعی داشته باشد ولی تعداد شاردهای درگیر و اندازه خروجی نهایی زمان پاسخ را افزایش دهد. همچنین کندترین مقصد میتواند زمان تکمیل عملیات گسترده را تعیین کند. افزایش ظرفیت VTGate پیش از شناخت این رفتار شاید تنها اجرای همزمان درخواستهای سنگین بیشتری را ممکن کند و فشار ذخیرهسازی را افزایش دهد.
VSchema و Vindex مسیر ردیف را تعیین میکنند
VSchema توصیفی از قواعد توزیع و مسیریابی جدولها در اختیار Vitess قرار میدهد. Vindex رابطه میان مقدار یک یا چند ستون و فضای شناسههای keyspace را بیان میکند. Vindex اصلی جدول در تعیین جای ردیف اثر دارد. با نگاه به مقدار ستون مربوط میتوان شناسه فضای کلید و سپس شارد مقصد را یافت. در مثال فروشگاه، این ستون میتواند شناسه مشتری باشد. طراح باید بررسی کند مقدار هنگام درج در دسترس است، در طول عمر ردیف چگونه تغییر میکند و آیا پرسوجوهای مهم آن را در شرط خود دارند. هزینه تغییر این انتخاب پس از رشد جدول چشمگیر است.
Vindex را از شاخص محلی MySQL جدا در نظر بگیرید. اولی در تعیین مقصد توزیعشده نقش دارد و دومی به موتور پایگاه داده برای یافتن ردیف روی همان مقصد کمک میکند. یک پرسوجو میتواند مستقیم به شارد درست برود اما به دلیل نبود شاخص مناسب روی آن شارد کند باشد. عکس این وضعیت هم رخ میدهد. همه شاردها ممکن است شاخص محلی خوبی داشته باشند ولی درخواست بدون کلید مسیریابی ناچار به جستوجو در چندین مقصد شود. برای ارزیابی عملکرد باید هم تعداد مقصدها و هم برنامه اجرای محلی هر مقصد را بررسی کرد.
دسترسی با شناسه سفارش چه هزینهای دارد؟
کاربران گاهی شماره سفارش را دارند ولی شناسه مشتری را ارسال نمیکنند. اگر توزیع فقط بر اساس مشتری انجام شده باشد، مسیریابی مستقیم با شماره سفارش به اطلاعات دیگری نیاز دارد. یکی از راهها استفاده از Vindex مناسب برای الگوی دسترسی دوم است. نوع lookup میتواند نگاشت کلید جایگزین به مقصد را از داده کمکی بیابد. این انتخاب هزینه نگهداری و سازگاری آن نگاشت را وارد طراحی میکند. هر مسیر جستوجوی جدید ارزش این هزینه را ندارد. فراوانی درخواست، حساسیت به تأخیر و رفتار تغییر شناسه سفارش باید پیش از ساخت نگاشت سنجیده شود.
راه دیگر آن است که برنامه شناسه مشتری را در زمینه درخواست نگه دارد و همراه شماره سفارش ارسال کند. این تصمیم رابط برنامه را تغییر میدهد اما میتواند یک جستوجوی اضافی را حذف کند. در محیط چندمستاجری نیز کلید مسیریابی جای کنترل مجوز را نمیگیرد. دانستن شماره مشتری به خودی خود اثبات نمیکند درخواستکننده حق مشاهده سفارشهای او را دارد. لایه برنامه باید هویت و مجوز را جداگانه بررسی کند. آزمون کاربردی باید هم مسیر درست مسیریابی و هم جلوگیری از دسترسی غیرمجاز میان مشتریان را پوشش دهد، زیرا خطای هر کدام پیامد متفاوتی دارد.
Tablet، VTTablet و نسخههای داده
هر tablet نماینده یک نمونه MySQL تحت مدیریت Vitess است و VTTablet در کنار آن وظایف مرتبط با سرویسدهی و مدیریت را انجام میدهد. شارد معمولاً یک primary برای نوشتن و نمونههایی برای تکثیر داده دارد. نوع tablet در مسیریابی خواندن اثر میگذارد. درخواستهایی که باید نتیجه یک نوشتن اخیر را فوراً ببینند با گزارشهایی که کمی تأخیر را تحمل میکنند یک قرارداد ندارند. انتخاب مقصد خواندن باید این قرارداد را منعکس کند. توزیع همه خواندنها روی replica بدون بررسی نیاز سازگاری میتواند کاربر را پس از ثبت سفارش با صفحهای مواجه کند که هنوز تغییر تازه را نشان نمیدهد.
در بررسی چنین شکایتی، ابتدا مشخص کنید نوشتن روی کدام شارد تأیید شده و خواندن بعدی به کدام نوع tablet رفته است. سپس وضعیت تکثیر همان شارد را بررسی کنید. جستوجوی عمومی در گزارش همه سرورها ممکن است نشانه مربوط به کاربر را پنهان کند. اگر برنامه برای مسیر خاص به مشاهده فوری تغییر نیاز دارد، مسیر خواندن مناسب باید آگاهانه انتخاب شود. اگر تأخیر قابل پذیرش است، آن را در طراحی محصول و شاخص پایش بیان کنید. یک عدد میانگین برای تأخیر کل خوشه میتواند عقبماندگی یک replica پرترافیک را پنهان کند.
مرز تراکنش و هزینه کار چندشاردی
تراکنشی که تغییرهایش روی یک شارد قرار میگیرد، مسیر سادهتری برای هماهنگی دارد. اگر عملیات میان چند شارد توزیع شود، هماهنگی موفقیت یا شکست بخشهای مختلف به مسئلهای مستقل تبدیل میشود. Vitess گزینههای تراکنشی متفاوتی دارد و رفتار مورد نیاز باید با نسخه و پیکربندی واقعی تطبیق داده شود. برنامه نباید فقط از مشاهده موفقیت یک نمونه آزمایشی نتیجه بگیرد که همه حالتهای خطا اتمی مدیریت میشوند. قطع ارتباط هنگام commit، خطای یک مقصد و تکرار درخواست پس از پاسخ نامشخص، مواردی هستند که طراحی تراکنش باید برای آنها پاسخ روشن داشته باشد.
در فروشگاه، قرار دادن سفارش و اقلام آن بر اساس همان شناسه مشتری میتواند عملیات معمول را در یک شارد نگه دارد. اما کاهش موجودی یک انبار مشترک ممکن است مرز دیگری داشته باشد. تیم باید تصمیم بگیرد کدام تغییرها واقعاً به تعهد همزمان نیاز دارند و کدام را میتوان با گردش کار چندمرحلهای مدیریت کرد. برای مسیر دوم، شناسه یکتای عملیات و رفتار قابل تکرار اهمیت پیدا میکند. اگر کلاینت پس از قطع ارتباط دوباره سفارش را ارسال کند، سامانه باید بتواند عملیات قبلی را تشخیص دهد. تقسیم جدول این مسئولیت تجاری را از برنامه حذف نمیکند.
جابهجایی داده و ارزیابی تغییر
افزودن یک شارد خالی به فهرست مقصدها به تنهایی داده موجود را توزیع نمیکند. تغییر آرایش شاردها به گردش کاری نیاز دارد که داده را منتقل کند، تغییرهای همزمان را دنبال کند و مسیر ترافیک را در زمان مناسب عوض کند. Vitess ابزارهای مدیریت جریانهای انتقال را فراهم میکند، ولی اپراتور باید ظرفیت منبع، مقصد و شبکه را برای دوره انتقال بسنجد. در این دوره، سامانه عادی همچنان درخواست کاربر را پاسخ میدهد. انتقالی که بدون محدودیت منابع آغاز شود ممکن است پیش از تغییر مسیر، تأخیر روی شارد مبدا را بالا ببرد و تجربه کاربران فعلی را خراب کند.
پیش از تغییر مسیر، صحت داده و میزان عقبماندگی جریان بررسی میشود. بعد از تغییر نیز آزمون روی مشتریانی از محدودههای مختلف لازم است. یک مشتری موفق فقط یک مسیر را پوشش میدهد. نمونهها باید عملیات درج، خواندن با کلید اصلی، جستوجو با کلید جایگزین و گزارش گسترده را شامل شوند. برنامه بازگشت باید مشخص کند در هر مرحله کدام سمت مرجع نوشتن است و تغییرهای تازه چگونه حفظ میشوند. بازگرداندن تنظیم مسیریابی بدون توجه به داده نوشتهشده پس از انتقال میتواند نتیجهای متفاوت از بازگشت واقعی سرویس داشته باشد.
پرونده عیبیابی برای یک سفارش گمشده
فرض کنیم سفارش ثبت شده اما پشتیبانی با شماره سفارش آن را پیدا نمیکند. رسید ثبت، شناسه مشتری و زمان عملیات را ثبت کنید. نخست خواندن هدفمند روی مسیر همان مشتری را بررسی کنید. اگر ردیف پیدا شد، مشکل در جستوجوی جایگزین یا انتخاب مقصد خواندن محدودتر میشود. اگر ردیف دیده نشد، نتیجه تراکنش و مقصد نوشتن نیازمند بررسی است. سپس وضعیت replica و نگاشت کمکی را با همان شواهد بسنجید. این ترتیب از اجرای پرسوجوی سنگین روی همه شاردها برای هر رخداد جلوگیری میکند و میان خرابی داده، خطای مسیریابی و تأخیر تکثیر تمایز میگذارد.
برای طراحی ظرفیت آینده، نرخ درخواست را به تفکیک keyspace، شارد و نوع عملیات ثبت کنید. رشد نامتوازن یک شارد ممکن است از رفتار یک مشتری یا الگوی ضعیف توزیع ناشی شود. عدد کلی ذخیرهسازی خوشه این تفاوت را نشان نمیدهد. گزارشهای گسترده را نیز جدا از تراکنشهای کوتاه مشتری اندازه بگیرید. وقتی تصمیمهای مربوط به Vindex، محل تراکنش و مقصد خواندن با داده واقعی پیوند بخورند، تیم میتواند پیش از افزودن سختافزار تشخیص دهد که مشکل از ظرفیت ذخیرهسازی، مسیر جستوجو یا توزیع نامتوازن کار میآید.