Shopify flyttade lagerrättigheter till MySQL
Shopify flyttade sitt lagerrättighetssystem från Redis till MySQL-databasen som redan innehöll lagerreskontran.
Shopify flyttade sitt lagerrättighetssystem från Redis till MySQL-databasen som redan innehöll lagerreskontran. En avgränsad pool av individuellt låsbara enhetsrader låter samtidiga kassor använda SKIP LOCKED för att välja olika berättigade enheter. Designen beror också på transaktionsgränser, primärnyckelns layout, påfyllningsregler och observation av anslutningens hålltid under kassan.
Läs den skrivna upplagan (engelska) ↗
Vad den här videon täcker
- Den gamla Redis-modellens kvantitetsräknare hanterade samtidighet, men reserveringsrensning och MySQL-reskontrauppdateringen kunde inte dela en enda lokal atomisk transaktion.
- Ersättningen använder en rad per tillgänglig enhet i en pool som är begränsad till 1 000 per artikel-/platskombination. En tom pool kan utlösa direkt påfyllning med samtidiga förfrågningar som väntar bakom ett påfyllningslås.
- Den sammansatta primärnyckeln är (shop_id, inventory_item_id, inventory_group_id, id). Shopify minskade låsöverhänget i sin prototyp och använde READ COMMITTED för att undvika gaplås som blockerade påfyllning.
- Reservation raderar poolrader innan reservationsposter infogas. En commit släpper databaslås medan det lagrade hållet kvarstår under betalningen; en lyckad betalning gör anspråk på reskontran och tar bort reservationen i en senare atomisk transaktion.
- MySQL dokumenterar SKIP LOCKED som en inkonsekvent vy som utelämnar låsta rader. Det etablerar varken en fullständig lagerkvantitet eller rättvis turordning, gäller endast på radnivå och är osäkert för uttalsbaserad replikering.
- Källans exempel inkluderar expires_at, men Shopify dokumenterar inte MySQL:s algoritm för utgångsrensning. Videons utgivnings-/utgångsgren är ett förklarande livscykelkrav.
- Anslutningens hålltid i annan kassakod var den slutliga flaskhalsen för genomströmning. Shopify skuggskrev båda systemen, jämförde resultat och växlade gradvis med en Redis kill-switch som reservlösning.
Översatt transkription
Översatt från den ursprungliga engelska berättelsen. Tillgängligt ljud och undertexter styrs av YouTube.
Varför flytta reservationer till MySQL?
0:00 En kassa behöver Redis för att förbli snabb. Shopify flyttade lagerrättigheter till MySQL med en rad per enhet i en avgränsad pool. Varför välja MySQL? Hur hoppar man över lås säkert? Detta är The Daily Diff, under huven. Och varför nådde snabba frågor fortfarande ett tak? Shopify är en handelsplattform för försäljning online och personligen. Redis är ett minnesbaserat datalager.
0:21 MySQL är en relationsdatabas, och Shopify hade redan sin lagerreskontra där. En reservation håller kortvarigt lager medan en köpare betalar.
Varför var två butiker riskabla?
0:29 Deras Redis-modell minskade en artikelräknare. Att göra anspråk på en betald order innebar att uppdatera MySQL-reskontran och rensa Redis. Dessa separata skrivningar kunde leda till att lager såldes två gånger eller var otillgängligt när det skulle vara säljbart. Den gamla modellen saknade också platsmedvetenhet. Ersättningen måste välja lager från någonstans som kan uppfylla ordern. Ett lager på fel kontinent gör en utmärkt databaspost och ett fruktansvärt leveranslöfte. Tidigare MySQL-försök använde en kvantitetsrad, så konkurrerande kassor köade vid samma
Vad blir den låsbara enheten?
0:56 lås. Tänk på ett sammetsrep runt en kalkylarkscell. Att lägga till fler arbetare förlänger bara kön. Shopify ändrade det låsbara objektet. Varje tillgänglig enhet får sin egen rad. En låsande läsning hoppar över enheter en annan transaktion håller och väljer andra berättigade enheter. Olika arbetare kan förvärva olika rader, medan den heta räknaren håller sig ur vägen.
Vad händer när poolen töms?
1:15 Den poolen är begränsad till tusen rader per artikel och plats. Påfyllning drar från reskontran. Om den töms, fylls reserven på direkt, med konkurrerande förfrågningar väntande bakom ett påfyllningslås. Tom pool betyder inte tomt lager. Reservation raderar valda poolrader och infogar sedan reservationsposter i en transaktion. Commit släpper databaslåsen.
1:35 Rollback ångrar ändringarna. Reservationen överlever betalningsbehandlingen som lagrat tillstånd. En lyckad betalning gör anspråk på reskontran och tar bort reservationen atomiskt. Databaslås behöver aldrig passa betalningsformuläret. Deras sammansatta primärnyckel börjar med butik, artikel, grupp, sedan enhetsidentitet. Att matcha uppslagningen minskade indexlåsningen i deras prototyp. De använder också read committed för att undvika gaplås som blockerade pool
1:57 påfyllning, och en konsekvent tabellordning för att förhindra cirkulära väntetider. Det publicerade exemplet registrerar en utgångstid. Övergivna betalningar behöver lagret släppt så småningom, annars blir varukorgen en hyresvärd. Shopifys inlägg lämnar den rensningsalgoritmen ospecificerad, så detta diagram visar livscykelkravet. Här är haken.
Vad utelämnar SKIP LOCKED?
2:14 Skip locked exkluderar låsta rader, så manualen kallar dess resultat en inkonsekvent vy. Det ger varken en fullständig lagerkvantitet eller rättvis turordning. Håll tillgänglighetsbeslutet och påfyllningsreglerna runt det.
Var fanns det verkliga taket?
2:26 Och det taket? Annan kassakod höll databasanslutningar för länge. Shopify taggade uppringare och mätte anslutningens hålltid, rensat sedan kassan och återbesökte tråd samtidighet. Snabba frågor kan fortfarande köa utanför frågan.
Varför skulle jag skicka den här designen?
2:38 De skuggskrev båda systemen med Redis som auktoritativt, jämförde resultat och växlade sedan gradvis med en kill switch. Mitt omdöme är SHIP IT. Jag skulle SHIP IT med den delade transaktionsgränsen och den återställningsbara utrullningen, med hela kassavägen instrumenterad. Har du en fråga om detta? Lägg den i kommentarerna. Och det var dagens diff.
2:54 Jag är Niko från Axrisi. Slå samman ansvarsfullt.
Källor
- We replaced Redis with MySQL for inventory reservations—and it scaledShopify Engineering — Emilie Noel
- Simplified reservation SQL embedded in Shopify's articleShopify Engineering / CourtneySymons on GitHub Gist
- MySQL 8.0 — Locking ReadsOracle / MySQL Reference Manual
- MySQL 8.0 — Transaction Isolation LevelsOracle / MySQL Reference Manual
- What Is Shopify and How Does It Work?Shopify
- Redis quick startsRedis documentation
- What is MySQL?Oracle / MySQL Reference Manual



