+− THE DAILY DIFFdev & AI news
SHIP IT

A Shopify a készletfoglalásokat MySQL-be helyezte át

A Shopify a készletfoglalási rendszerét Redis-ből átköltöztette a MySQL adatbázisba, amely már tartalmazta a készletnyilvántartást.

A Shopify a készletfoglalási rendszerét Redis-ből átköltöztette a MySQL adatbázisba, amely már tartalmazta a készletnyilvántartást. Az egyedileg zárolható egységsorok korlátozott készlete lehetővé teszi, hogy az egyidejű pénztárellenőrzések a SKIP LOCKED funkcióval különböző, jogosult egységeket válasszanak ki. A tervezés függ a tranzakciós határoktól, a elsődleges kulcs elrendezésétől, az utántöltési szabályoktól és a kapcsolattartási idő megfigyelésétől a pénztárellenőrzés során.

Olvassa el az írott kiadást (angolul) ↗

Amit ez a videó tartalmaz

  • A régi Redis mennyiségszámláló modell kezelte az egyidejűséget, de a foglalások takarítása és a MySQL főkönyvi frissítése nem oszthatott meg egyetlen helyi atomi tranzakciót.
  • A helyettesítés tételenként egy sort használ az elérhető egységekre, legfeljebb 1000 darabot tételezve fel termék/hely kombinációnként. Egy üres készlet kiválthatja az azonnali utántöltést, miközben az egyidejű kérések egy utántöltési zár mögött várakoznak.
  • Az összetett elsődleges kulcs a (shop_id, inventory_item_id, inventory_group_id, id). A Shopify csökkentette a zárolási terhelést a prototípusában, és a READ COMMITTED-et használta a hiányzárak elkerülésére, amelyek blokkolták az utántöltést.
  • A foglalások törlése törli a készletsort a foglalási rekordok beillesztése előtt. A commit felszabadítja az adatbáziszárakat, miközben a tárolt tartás megmarad a fizetés során; a sikeres fizetés igénybe veszi a főkönyvet, és egy későbbi atomi tranzakcióban eltávolítja a foglalást.
  • A MySQL dokumentációja szerint a SKIP LOCKED egy inkonzisztens nézetet eredményez, amely kihagyja a zárolt sorokat. Nem biztosít teljes készletet vagy méltányos sorrendiséget, csak sorszintű zárakra vonatkozik, és nem biztonságos az utasításalapú replikációhoz.
  • A forrás példa tartalmazza az expires_at mezőt, de a Shopify nem dokumentálja a MySQL lejárati takarítási algoritmusát. A videóban szereplő feloldási/lejárati ág egy magyarázó életciklus követelmény.
  • A kapcsolattartási idő a pénztárellenőrzés egyéb kódjaiban volt az utolsó áteresztőképességi szűk keresztmetszet. A Shopify mindkét rendszert "árnyékosan" írta, összehasonlította az eredményeket, és fokozatosan váltott egy Redis "kill-switch" visszaváltással.

Lefordított átirat

Az eredeti angol narrációból fordítva. A rendelkezésre álló hangot és feliratokat a YouTube vezérli.

Miért helyeztük át a foglalásokat MySQL-be?

0:00 A pénztárellenőrzésnek gyorsnak kell maradnia a Redis segítségével. A Shopify a készletfoglalásokat MySQL-be helyezte át, egységenként egy sort használva egy korlátozott készletben. Miért a MySQL-t választották? Hogyan ugorhatja át biztonságosan a zárakat? Ez a The Daily Diff, a háttérben. És miért ütöttek még mindig plafont a gyors lekérdezések? A Shopify egy kereskedelmi platform online és személyes értékesítéshez. A Redis egy memóriabeli adattároló.

0:21 A MySQL egy relációs adatbázis, és a Shopify már ott tárolta a készletnyilvántartását. Egy foglalás röviden tartja a készletet, amíg a vevő fizet.

Miért volt kockázatos két bolt?

0:29 A Redis modelljük csökkentette egy elem számlálóját. Egy kifizetett rendelés igénylése a MySQL főkönyvének frissítését és a Redis takarítását jelentette. Ezek a különálló írások azt eredményezhették, hogy a készletet kétszer adták el, vagy elérhetetlenné vált, amikor eladhatónak kellett volna lennie. A régi modellnek hiányzott a helyszín szerinti tudatossága is. A helyettesítésnek olyan helyről kell készletet választania, amely teljesíteni tudja a rendelést. Egy raktár rossz kontinensen kiváló adatbázis bejegyzést, és borzalmas szállítási ígéretet eredményez. Korábbi MySQL kísérletek mennyiségi sort használtak, így a versengő pénztárellenőrzések ugyanazon a záron sorakoztak.

Mi lesz a zárolható egység?

0:56 Gondoljon egy bársony kötélre egy táblázat cellája körül. Több dolgozó hozzáadása csak meghosszabbítja a sort. A Shopify megváltoztatta a zárolható objektumot. Minden elérhető egység saját sort kap. Egy zároló olvasás kihagyja azokat az egységeket, amelyeket egy másik tranzakció tart, és más jogosult egységeket választ ki. Különböző dolgozók különböző sorokat szerezhetnek meg, miközben a forró számláló távol marad az útjukból.

Mi történik, ha kiürül a készlet?

1:15 Ez a készlet ezer sorra korlátozott termék- és helyszínpáronként. Az utántöltés a főkönyvből történik. Ha kiürül, a foglalási útvonal azonnal utántölt, a versengő kérések egy utántöltési zár mögött várakoznak. Üres készlet nem jelent üres raktárat. A foglalás törli a kiválasztott készletsort, majd beilleszti a foglalási rekordokat egy tranzakcióban. A commit felszabadítja az adatbázis zárakat.

1:35 A rollback visszavonja a változtatásokat. A foglalás túléli a fizetési feldolgozást, mint tárolt állapot. A sikeres fizetés atomi módon igényli a főkönyvet és eltávolítja a foglalást. Az adatbázis záraknak soha nem kell felügyelniük a fizetési űrlapot. Az összetett elsődleges kulcsuk a bolttal, tétellel, csoporttal, majd az egységazonosítóval kezdődik. Az egyező keresés csökkentette az indexzárolást a prototípusukban. Emellett read committed-et használnak a hiányzárak elkerülésére, amelyek blokkolták a készlet

1:57 utántöltését, és konzisztens táblarendet a körkörös várakozások megakadályozására. A közzétett példa egy lejárati időt rögzít. Az elhagyott fizetéseknek előbb-utóbb fel kell szabadítaniuk a készletet, különben a bevásárlókosár földbirtokossá válik. A Shopify bejegyzése nem határozza meg ezt a takarítási algoritmust, így ez a diagram az életciklus követelményt mutatja. Itt a csavar.

Mit hagy ki a SKIP LOCKED?

2:14 A Skip locked kizárja a zárolt sorokat, így a kézikönyv inkonzisztens nézetnek nevezi az eredményét. Nem biztosít sem teljes készletszámot, sem méltányos sorrendiséget. Tartsa meg a rendelkezésre állási döntést és az utántöltési szabályokat körülötte.

Hol volt az igazi plafon?

2:26 És az a plafon? Más pénztárellenőrző kód túl sokáig tartotta az adatbázis kapcsolatokat. A Shopify címkézte a hívókat és mérte a kapcsolattartási időt, majd kitakarította a pénztárellenőrző útvonalat és újraértékelte a szálak egyidejűségét. A gyors lekérdezések még mindig sorban állhatnak a lekérdezésen kívül.

Miért szállítanám ezt a tervezést?

2:38 Mindkét rendszert "árnyékosan" írták, a Redis volt a mérvadó, összehasonlították az eredményeket, majd fokozatosan váltottak egy "kill switch"-csel. Az ítéletem: SHIP IT. Szállítanám a megosztott tranzakciós határt és azt a visszaállítható bevezetést, a teljes pénztárellenőrző útvonallal műszerezve. Van kérdése ezzel kapcsolatban? Tegye fel a kommentekben. És ez a mai diff.

2:54 Niko vagyok az Axrisi-től. Összevonás felelősségteljesen.

Források

  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

Kapcsolódó videók