+− THE DAILY DIFFdev & AI news
SHIP IT

Shopify flyttede lagerreservationer ind i MySQL

Shopify flyttede sit lagerreservationssystem fra Redis til MySQL-databasen, der allerede indeholdt lagerregnskabet.

Shopify flyttede sit lagerreservationssystem fra Redis til MySQL-databasen, der allerede indeholdt lagerregnskabet. En afgrænset pulje af individuelt låsbare enhedsrækker lader samtidige kasser bruge SKIP LOCKED til at vælge forskellige egnede enheder. Designet afhænger også af transaktionsgrænser, primærnøglelayout, genopfyldningsregler og observation af forbindelsestid under kassen.

Læs den skriftlige udgave (engelsk) ↗

Hvad denne video dækker

  • Den gamle Redis-mængdetæller-model håndterede samtidighed, men reservationsoprydning og MySQL-regnskabsopdateringen kunne ikke dele en enkelt lokal atomar transaktion.
  • Erstatningen bruger én række pr. tilgængelig enhed i en pulje, der er begrænset til 1.000 pr. vare/lokationskombination. En tom pulje kan udløse intern genopfyldning, hvor samtidige anmodninger venter bag en genopfyldningslås.
  • Den sammensatte primærnøgle er (shop_id, inventory_item_id, inventory_group_id, id). Shopify reducerede låseoverhead i sin prototype og brugte READ COMMITTED for at undgå gap-låse, der blokerede genopfyldning.
  • Reservation sletter puljerækker, før reservationsposter indsættes. Committing frigiver databaselåse, mens den gemte beholdning består efter betaling; vellykket betaling kræver regnskabet og fjerner reservationen i en senere atomar transaktion.
  • MySQL-dokumenter SKIP LOCKED som en inkonsistent visning, der udelader låste rækker. Det etablerer ikke et komplet lagertal eller fair tur-tagning, gælder kun for række-niveau låse og er usikkert for statement-baseret replikering.
  • Kildeeksemplet inkluderer expires_at, men Shopify dokumenterer ikke MySQL-udløbsoprydningsalgoritmen. Videoens udgivelses-/udløbsgren er et forklarende livscykluskrav.
  • Forbindelsens holdetid i anden checkout-kode var den endelige gennemløbsflaskehals. Shopify skyggeskrev begge systemer, sammenlignede resultater og skiftede gradvist med en Redis kill-switch fallback.

Oversat udskrift

Oversat fra den originale engelske fortælling. Tilgængelig lyd og undertekster styres af YouTube.

Hvorfor flytte reservationer ind i MySQL?

0:00 En checkout skal bruge Redis for at forblive hurtig. Shopify flyttede lagerreservationer ind i MySQL ved at bruge én række pr. enhed i en afgrænset pulje. Hvorfor vælge MySQL? Hvordan springer man låse sikkert over? Dette er The Daily Diff, under overfladen. Og hvorfor ramte hurtige forespørgsler stadig et loft? Shopify er en handelsplatform til salg online og personligt. Redis er et in-memory datalager.

0:21 MySQL er en relationel database, og Shopify opbevarede allerede sit lagerregnskab der. En reservation holder kortvarigt lager, mens en køber betaler.

Hvorfor var to butikker risikable?

0:29 Deres Redis-model dekrementerede en varetæller. At kræve en betalt ordre betød at opdatere MySQL-regnskabet og rydde op i Redis. Disse separate writes kunne efterlade lager solgt to gange eller utilgængeligt, når det burde være salgbart. Den gamle model manglede også lokationsbevidsthed. Erstatningen skal vælge lager fra et sted, der kan opfylde ordren. Et lager på det forkerte kontinent giver en fremragende databaseindtastning og et frygteligt leveringsløfte. Tidligere MySQL-forsøg brugte en mængderække, så konkurrerende checkouts stod i kø ved den

Hvad bliver den låsbare enhed?

0:56 samme lås. Tænk på et fløjlsreb omkring en regnearkscelle. At tilføje flere medarbejdere forlænger blot køen. Shopify ændrede det låsbare objekt. Hver tilgængelig enhed får sin egen række. En låse-læsning springer enheder over, som en anden transaktion holder, og vælger andre egnede enheder. Forskellige medarbejdere kan erhverve forskellige rækker, mens den varme tæller holder sig ude af vejen for dem.

Hvad sker der, når puljen tømmes?

1:15 Den pulje er afgrænset til tusind rækker pr. vare og lokation. Genopfyldning trækker fra regnskabet. Hvis den tømmes, genopfyldes reservevejen inline, med konkurrerende anmodninger ventende bag en genopfyldningslås. Tom pulje betyder ikke tomt lager. Reserve sletter valgte puljerækker, og indsætter derefter reservationsposter i en transaktion. Commit frigiver databaselåsene.

1:35 Rollback fortryder ændringerne. Reservationen overlever betalingsbehandling som gemt tilstand. Vellykket betaling kræver regnskabet og fjerner reservationen atomisk. Databaselåse behøver aldrig at passe på betalingsformularen. Deres sammensatte primærnøgle starter med butik, vare, gruppe, derefter enhedsidentitet. Matchning af opslaget reducerede indekslåsning i deres prototype. De bruger også read committed for at undgå de gap-låse, der blokerede pulje

1:57 genopfyldning, og en konsistent tabelrækkefølge for at forhindre cirkulære ventetider. Det publicerede eksempel registrerer en udløbstid. Forladte betalinger skal frigives lager til sidst, ellers bliver indkøbskurven en udlejer. Shopifys indlæg lader den oprydningsalgoritme uspecificeret, så dette diagram viser livscykluskravet. Her er hagen.

Hvad udelader SKIP LOCKED?

2:14 Skip locked udelukker låste rækker, så manualen kalder dets resultat en inkonsistent visning. Den giver hverken en komplet lagertælling eller fair tur-tagning. Behold tilgængelighedsbeslutningen og genopfyldningsreglerne omkring den.

Hvor var det virkelige loft?

2:26 Og det loft? Anden checkout-kode holdt databaseforbindelser for længe. Shopify taggede opkaldere og målte forbindelsestid, ryddede derefter op i checkout-stien og genbesøgte tråd-samtidighed. Hurtige forespørgsler kan stadig stå i kø uden for forespørgslen.

Hvorfor ville jeg sende dette design?

2:38 De skyggeskrev begge systemer med Redis autoritativ, sammenlignede resultater og skiftede derefter gradvist med en kill switch. Min dom er SHIP IT. Jeg ville sende den delte transaktionsgrænse og den rollbackable udrulning, med hele checkout-stien instrumenteret. Har du et spørgsmål til dette? Skriv det i kommentarerne. Og det er diff'en for i dag.

2:54 Jeg er Niko fra Axrisi. Flet ansvarligt.

Kilder

  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

Relaterede videoer