+− THE DAILY DIFFdev & AI news
SHIP IT

Shopify رزرو موجودی را به MySQL منتقل کرد

Shopify سیستم رزرو موجودی خود را از Redis به پایگاه داده MySQL منتقل کرد که از قبل شامل دفتر کل موجودی بود.

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

نسخه نوشتاری را بخوانید (انگلیسی) ↗

این ویدیو چه مواردی را پوشش می‌دهد

  • مدل شمارنده-مقدار قدیمی Redis همزمانی را مدیریت می کرد، اما پاکسازی رزرو و به روز رسانی دفتر کل MySQL نمی توانستند یک تراکنش اتمی محلی واحد را به اشتراک بگذارند.
  • جایگزین از یک ردیف برای هر واحد موجود در یک مجموعه استفاده می کند که در هر ترکیب کالا/مکان حداکثر 1000 عدد محدود شده است. یک مجموعه خالی می تواند تجدید موجودی درون خطی را با درخواست های همزمان که پشت قفل تجدید موجودی منتظر هستند، فعال کند.
  • کلید اصلی ترکیبی (shop_id, inventory_item_id, inventory_group_id, id) است. Shopify سربار قفل را در نمونه اولیه خود کاهش داد و از READ COMMITTED برای جلوگیری از قفل های گپ که مانع تجدید موجودی می شدند، استفاده کرد.
  • رزرو، ردیف های مجموعه را قبل از درج رکوردهای رزرو حذف می کند. کامیت، قفل های پایگاه داده را آزاد می کند در حالی که نگهداری ذخیره شده در طول پرداخت ادامه می یابد؛ پرداخت موفقیت آمیز، دفتر کل را تأیید می کند و رزرو را در یک تراکنش اتمی بعدی حذف می کند.
  • MySQL، SKIP LOCKED را به عنوان یک نمای ناسازگار مستند می کند که ردیف های قفل شده را حذف می کند. این نه یک شمارش کامل موجودی را ایجاد می کند و نه نوبت دهی عادلانه، فقط برای قفل های سطح ردیف اعمال می شود و برای تکثیر مبتنی بر دستور ناامن است.
  • مثال منبع شامل expires_at است، اما Shopify الگوریتم پاکسازی انقضای MySQL را مستند نکرده است. شاخه انتشار/انقضای ویدیو یک نیاز چرخه حیات توضیحی است.
  • زمان نگهداری اتصال در سایر کدهای پرداخت، گلوگاه نهایی توان عملیاتی بود. Shopify هر دو سیستم را به صورت سایه ای نوشت، نتایج را مقایسه کرد و به تدریج با یک سوئیچ قطع Redis به عنوان پشتیبان تغییر کرد.

رونوشت ترجمه شده

ترجمه شده از روایت اصلی انگلیسی. صوت و زیرنویس‌های موجود توسط YouTube کنترل می‌شوند.

چرا رزروها را به MySQL منتقل کنیم؟

0:00 یک پرداخت نیاز دارد که Redis سریع بماند. Shopify رزرو موجودی را به MySQL با استفاده از یک ردیف برای هر واحد در یک مجموعه محدود منتقل کرد. چرا MySQL را انتخاب کنیم؟ چگونه قفل ها را با خیال راحت رد کنید؟ این The Daily Diff است، در پشت صحنه. و چرا پرس و جوهای سریع هنوز به سقف می خوردند؟ Shopify یک پلتفرم تجارت الکترونیک برای فروش آنلاین و حضوری است. Redis یک فروشگاه داده در حافظه است.

0:21 MySQL یک پایگاه داده رابطه ای است و Shopify قبلاً دفتر کل موجودی خود را در آنجا نگهداری می کرد. یک رزرو به طور خلاصه موجودی را در حالی که خریدار پرداخت می کند، نگه می دارد.

چرا دو فروشگاه خطرناک بودند؟

0:29 مدل Redis آنها یک شمارنده کالا را کاهش می داد. ادعای یک سفارش پرداخت شده به معنای به روز رسانی دفتر کل MySQL و پاکسازی Redis بود. این نوشتن های جداگانه می توانست باعث شود موجودی دو بار فروخته شود یا در زمانی که باید قابل فروش باشد، در دسترس نباشد. مدل قدیمی همچنین فاقد آگاهی از مکان بود. جایگزین باید موجودی را از مکانی انتخاب کند که بتواند سفارش را تکمیل کند. یک انبار در قاره اشتباه یک ورودی عالی در پایگاه داده و یک وعده تحویل وحشتناک می سازد. تلاش های قبلی MySQL از یک ردیف مقدار استفاده می کردند، بنابراین پرداخت های رقیب در

واحد قابل قفل شدن چه چیزی می شود؟

0:56 همان قفل صف می کشیدند. به یک طناب مخملی در اطراف یک سلول صفحه گسترده فکر کنید. اضافه کردن کارگران بیشتر فقط صف را طولانی تر می کند. Shopify شیء قابل قفل شدن را تغییر داد. هر واحد موجود ردیف مخصوص به خود را می گیرد. یک خواندن قفل کننده واحدهایی را که یک تراکنش دیگر نگه می دارد، رد می کند و واحدهای واجد شرایط دیگر را انتخاب می کند. کارگران مختلف می توانند ردیف های مختلفی را به دست آورند، در حالی که شمارنده داغ از سر راه آنها دور می ماند.

وقتی مجموعه خالی می شود چه اتفاقی می افتد؟

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

1:35 برگرداندن، تغییرات را لغو می کند. رزرو به عنوان حالت ذخیره شده در طول پردازش پرداخت باقی می ماند. پرداخت موفقیت آمیز، دفتر کل را تأیید می کند و رزرو را به صورت اتمی حذف می کند. قفل های پایگاه داده هرگز نیازی به نگهداری فرم پرداخت ندارند. کلید اصلی ترکیبی آنها با shop، item، group، سپس هویت واحد شروع می شود. تطبیق جستجو، قفل گذاری شاخص را در نمونه اولیه آنها کاهش داد. آنها همچنین از read committed برای جلوگیری از قفل های گپ که مانع

1:57 تجدید موجودی مجموعه می شدند، و یک ترتیب جدول سازگار برای جلوگیری از انتظار دایره ای استفاده می کنند. مثال منتشر شده زمان انقضا را ثبت می کند. پرداخت های رها شده در نهایت باید موجودی را آزاد کنند، یا سبد خرید تبدیل به یک صاحبخانه می شود. پست Shopify آن الگوریتم پاکسازی را نامشخص گذاشته است، بنابراین این نمودار نیاز چرخه حیات را نشان می دهد. این هم نکته.

SKIP LOCKED چه چیزی را حذف می کند؟

2:14 Skip locked ردیف های قفل شده را مستثنی می کند، بنابراین راهنما نتیجه آن را یک نمای ناسازگار می نامد. این نه یک شمارش کامل موجودی را فراهم می کند و نه نوبت دهی عادلانه. تصمیم در دسترس بودن و قوانین تجدید موجودی را در اطراف آن حفظ کنید.

سقف واقعی کجا بود؟

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

چرا این طراحی را SHIP IT می کنم؟

2:38 آنها هر دو سیستم را با Redis به عنوان مرجع به صورت سایه ای نوشتند، نتایج را مقایسه کردند، سپس به تدریج با یک سوئیچ قطع تغییر کردند. حکم من SHIP IT است. من مرز تراکنش مشترک و آن rollout قابل بازگشت را SHIP IT می کنم، با تمام مسیر پرداخت مجهز شده. سوالی در مورد این دارید؟ آن را در نظرات قرار دهید. و این تفاوت برای امروز است.

2:54 من نیکو از Axrisi هستم. با مسئولیت پذیری ادغام کنید.

منابع

  1. We replaced Redis with MySQL for inventory reservations—and it scaledShopify Engineering — Emilie Noel
  2. Simplified reservation SQL embedded in Shopify's articleShopify Engineering / CourtneySymons on GitHub Gist
  3. MySQL 8.0 — Locking ReadsOracle / MySQL Reference Manual
  4. MySQL 8.0 — Transaction Isolation LevelsOracle / MySQL Reference Manual
  5. What Is Shopify and How Does It Work?Shopify
  6. Redis quick startsRedis documentation
  7. What is MySQL?Oracle / MySQL Reference Manual

ویدیوهای مرتبط

under-the-hood · fa · ۱۹ مهر ۱۴۰۵

هنگامی که پاسخ ناپدید می شود، Stripe درخواست شما را به خاطر می آورد

یک وقفه می تواند پس از اتمام عملیات توسط سرور، وضعیت پرداخت را نامشخص بگذارد. این توضیح‌دهنده «زیر کاپوت» از قرارداد مستند شده‌ی idempotency در Stripe API v1 برای نمایش کلیدهای عملیاتی پایدار، بازپخش

2:54 ↗