Shopify va moure les reserves d'inventari a MySQL
Shopify va moure el seu sistema de reserva d'inventari de Redis a la base de dades MySQL que ja contenia el llibre major d'inventari.
Shopify va moure el seu sistema de reserva d'inventari de Redis a la base de dades MySQL que ja contenia el llibre major d'inventari. Un pool acotat de files d'unitats bloquejables individualment permet que les compres simultànies utilitzin SKIP LOCKED per seleccionar diferents unitats elegibles. El disseny també depèn dels límits de transacció, la disposició de la clau primària, les regles de reposició i l'observació del temps de retenció de la connexió durant la compra.
Llegeix l'edició escrita (anglès) ↗
Què cobreix aquest vídeo
- L'antic model de comptador de quantitat de Redis gestionava la concurrència, però la neteja de reserves i l'actualització del llibre major de MySQL no podien compartir una única transacció atòmica local.
- El reemplaçament utilitza una fila per unitat disponible en un pool limitat a 1.000 per combinació d'article/ubicació. Un pool buit pot activar la reposició en línia amb sol·licituds concurrents que esperen darrere d'un bloqueig de reposició.
- La clau primària composta és (shop_id, inventory_item_id, inventory_group_id, id). Shopify va reduir la sobrecàrrega de bloqueig en el seu prototip i va utilitzar READ COMMITTED per evitar bloquejos de buits que bloquejaven la reposició.
- La reserva elimina les files del pool abans d'inserir els registres de reserva. La confirmació allibera els bloquejos de la base de dades mentre la retenció emmagatzemada persisteix durant el pagament; el pagament correcte reclama el llibre major i elimina la reserva en una transacció atòmica posterior.
- MySQL documenta SKIP LOCKED com una vista inconsistent que omet les files bloquejades. No estableix un recompte complet d'existències ni un torn just, només s'aplica a bloquejos a nivell de fila i no és segur per a la replicació basada en declaracions.
- L'exemple de la font inclou expires_at, però Shopify no documenta l'algoritme de neteja de caducitat de MySQL. La branca d'alliberament/caducitat del vídeo és un requisit explicatiu del cicle de vida.
- El temps de retenció de la connexió en un altre codi de compra va ser el coll d'ampolla final del rendiment. Shopify va escriure en paral·lel ambdós sistemes, va comparar els resultats i va canviar gradualment amb una solució de retrocés de tall de Redis.
Transcripció traduïda
Traduït de la narració original en anglès. L'àudio i els subtítols disponibles estan controlats per YouTube.
Per què moure les reserves a MySQL?
0:00 Una compra necessita que Redis es mantingui ràpid. Shopify va moure les reserves d'inventari a MySQL utilitzant una fila per unitat en un pool acotat. Per què triar MySQL? Com es poden saltar els bloquejos amb seguretat? Això és The Daily Diff, entre bastidors. I per què les consultes ràpides encara topaven amb un límit? Shopify és una plataforma de comerç per vendre en línia i en persona. Redis és un emmagatzematge de dades en memòria.
0:21 MySQL és una base de dades relacional, i Shopify ja hi guardava el seu llibre major d'inventari. Una reserva manté breument l'estoc mentre un comprador paga.
Per què eren arriscades dues botigues?
0:29 El seu model Redis decrementava un comptador d'elements. Reclamar una comanda pagada significava actualitzar el llibre major de MySQL i netejar Redis. Aquestes escriptures separades podien deixar l'estoc venut dues vegades o no disponible quan hauria de ser vendible. L'antic model també mancava de consciència de la ubicació. El reemplaçament ha de triar l'estoc d'un lloc que pugui satisfer la comanda. Un magatzem en un continent equivocat fa una excel·lent entrada de base de dades i una terrible promesa de lliurament. Els intents anteriors de MySQL utilitzaven una fila de quantitat, de manera que les compres concurrents feien cua al
Què esdevé la unitat bloquejable?
0:56 mateix bloqueig. Imagineu-vos una corda de vellut al voltant d'una cel·la d'un full de càlcul. Afegir més treballadors només allarga la cua. Shopify va canviar l'objecte bloquejable. Cada unitat disponible té la seva pròpia fila. Una lectura de bloqueig omet les unitats que una altra transacció reté i selecciona altres unitats elegibles. Diferents treballadors poden adquirir diferents files, mentre que el comptador calent es manté fora del seu camí.
Què passa quan el pool es buida?
1:15 Aquest pool està limitat a mil files per article i ubicació. La reposició es basa en el llibre major. Si es buida, el camí de reserva es reposa en línia, amb sol·licituds concurrents esperant darrere d'un bloqueig de reposició. El pool buit no significa magatzem buit. La reserva elimina les files seleccionades del pool, després insereix registres de reserva en una transacció. La confirmació allibera els bloquejos de la base de dades.
1:35 La reversió desfà els canvis. La reserva sobreviu al processament del pagament com a estat emmagatzemat. El pagament correcte reclama el llibre major i elimina la reserva de forma atòmica. Els bloquejos de la base de dades mai necessiten vigilar el formulari de pagament. La seva clau primària composta comença amb botiga, article, grup, després la identitat de la unitat. La concordança de la cerca va reduir el bloqueig d'índexs en el seu prototip. També utilitzen lectura confirmada per evitar els bloquejos de buits que bloquejaven la reposició del pool,
1:57 i un ordre de taula consistent per evitar esperes circulars. L'exemple publicat registra un temps de caducitat. Els pagaments abandonats necessiten que l'estoc s'alliberi finalment, o el carret de la compra es converteix en un propietari. La publicació de Shopify deixa aquest algoritme de neteja sense especificar, de manera que aquest diagrama mostra el requisit del cicle de vida. Aquí hi ha la trampa.
Què exclou SKIP LOCKED?
2:14 Skip locked exclou les files bloquejades, de manera que el manual anomena el seu resultat una vista inconsistent. No proporciona ni un recompte complet d'estoc ni un torn just. Mantingueu la decisió de disponibilitat i les regles de reposició al voltant.
On era el sostre real?
2:26 I aquell límit? Un altre codi de compra mantenia les connexions de la base de dades massa temps. Shopify va etiquetar els qui trucaven i va mesurar el temps de retenció de la connexió, després va netejar la ruta de compra i va revisar la concurrència de fils. Les consultes ràpides encara poden fer cua fora de la consulta.
Per què hauria d'enviar aquest disseny?
2:38 Van escriure en paral·lel ambdós sistemes amb Redis autoritari, van comparar els resultats, i després van canviar gradualment amb un interruptor de tall. El meu veredicte és SHIP IT. Jo enviaria el límit de transacció compartit i aquella implementació reversible, amb tota la ruta de compra instrumentada. Tens alguna pregunta sobre això? Posa-la als comentaris. I aquesta és la diferència d'avui.
2:54 Sóc Niko d'Axrisi. Fusiona de forma responsable.
Fonts
- 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



