Shopify přesunul rezervace zásob do MySQL
Shopify přesunul svůj systém rezervace zásob z Redis do databáze MySQL, která již obsahovala účetní knihu zásob.
Shopify přesunul svůj systém rezervace zásob z Redis do databáze MySQL, která již obsahovala účetní knihu zásob. Omezený fond řádků jednotek, které lze individuálně uzamknout, umožňuje souběžným platbám používat SKIP LOCKED k výběru různých vhodných jednotek. Návrh také závisí na hranicích transakcí, rozložení primárního klíče, pravidlech doplňování a sledování doby držení připojení napříč pokladnou.
Přečtěte si psané vydání (anglicky) ↗
Co toto video pokrývá
- Starý model počítadla množství v Redis zvládal souběžnost, ale čištění rezervací a aktualizace účetní knihy v MySQL nemohly sdílet jedinou lokální atomickou transakci.
- Náhrada používá jeden řádek na dostupnou jednotku ve fondu omezeném na 1 000 na kombinaci položky a umístění. Prázdný fond může spustit inline doplnění se souběžnými požadavky čekajícími za zámkem pro doplnění.
- Složený primární klíč je (shop_id, inventory_item_id, inventory_group_id, id). Shopify snížil režii zámků ve svém prototypu a použil READ COMMITTED, aby se vyhnul zámkům mezer, které blokovaly doplňování.
- Rezerva maže řádky fondu před vložením záznamů rezervací. Potvrzení uvolní zámky databáze, zatímco uložená blokace přetrvává napříč platbou; úspěšná platba nárokuje účetní knihu a odstraní rezervaci v pozdější atomické transakci.
- Dokumentace MySQL označuje SKIP LOCKED jako nekonzistentní pohled, který vynechává uzamčené řádky. Nezajišťuje kompletní počet zásob ani spravedlivé střídání, platí pouze pro zámky na úrovni řádků a je nebezpečný pro replikaci založenou na příkazech.
- Příklad zdroje obsahuje expires_at, ale Shopify nedokumentuje algoritmus čištění vypršení platnosti v MySQL. Větev vydání/vypršení platnosti ve videu je vysvětlujícím požadavkem životního cyklu.
- Doba držení připojení v jiném kódu pokladny byla posledním úzkým hrdlem propustnosti. Shopify zapisoval do obou systémů souběžně, porovnával výsledky a postupně přešel s nouzovým přepínačem na Redis.
Přeložený přepis
Přeloženo z původního anglického vyprávění. Dostupné audio a titulky jsou řízeny YouTube.
Proč přesunout rezervace do MySQL?
0:00 Pokladna potřebuje Redis, aby zůstala rychlá. Shopify přesunul rezervace zásob do MySQL pomocí jednoho řádku na jednotku v omezeném fondu. Proč zvolit MySQL? Jak bezpečně přeskočit zámky? Toto je The Daily Diff, pod kapotou. A proč rychlé dotazy stále narážely na strop? Shopify je obchodní platforma pro prodej online a osobně. Redis je úložiště dat v paměti.
0:21 MySQL je relační databáze a Shopify si zde již vedla svou účetní knihu zásob. Rezervace krátce drží zásoby, zatímco kupující platí.
Proč byly dva obchody riskantní?
0:29 Jejich model Redis snižoval počítadlo položek. Nárokování zaplacené objednávky znamenalo aktualizaci účetní knihy v MySQL a vyčištění Redis. Tyto oddělené zápisy mohly vést k tomu, že se zboží prodalo dvakrát nebo bylo nedostupné, když by mělo být prodejné. Starý model také postrádal povědomí o poloze. Starý model také postrádal povědomí o poloze. Náhrada musí vybrat zásoby z místa, které může splnit objednávku. Sklad na špatném kontinentu je vynikající záznam v databázi a hrozný slib doručení. Sklad na špatném kontinentu je vynikající záznam v databázi a hrozný slib doručení. Dřívější pokusy s MySQL používaly řádek s množstvím, takže konkurenční pokladny se řadily u stejného zámku.
Co se stane uzamykatelnou jednotkou?
0:56 Představte si sametové lano kolem buňky tabulky. Přidání více pracovníků pouze prodlouží frontu. Shopify změnil uzamykatelný objekt. Každá dostupná jednotka dostane svůj vlastní řádek. Zamykací čtení přeskočí jednotky, které drží jiná transakce, a vybere jiné vhodné jednotky. Různí pracovníci mohou získat různé řádky, zatímco horké počítadlo jim nestojí v cestě.
Co se stane, když se fond vyprázdní?
1:15 Tento fond je omezen na tisíc řádků na položku a umístění. Doplnění čerpá z účetní knihy. Pokud se vyprázdní, cesta rezervace doplní inline, s konkurenčními požadavky čekajícími za zámkem pro doplnění. s konkurenčními požadavky čekajícími za zámkem pro doplnění. Prázdný fond neznamená prázdný sklad. Rezerva maže vybrané řádky fondu a poté v transakci vkládá záznamy rezervací. Commit uvolní zámky databáze.
1:35 Rollback vrátí změny zpět. Rezervace přežije zpracování platby jako uložený stav. Úspěšná platba nárokuje účetní knihu a atomicky odstraní rezervaci. Zámky databáze nikdy nemusí hlídat platební formulář. Jejich složený primární klíč začíná obchodem, položkou, skupinou, poté identitou jednotky. Porovnání vyhledávání snížilo zamykání indexů v jejich prototypu. Také používají read committed, aby se vyhnuli zámkům mezer, které blokovaly doplňování fondu,
1:57 a konzistentní pořadí tabulek, aby se zabránilo kruhovým čekáním. Zveřejněný příklad zaznamenává dobu vypršení platnosti. Opuštěné platby potřebují, aby se zásoby nakonec uvolnily, jinak se nákupní košík stane pronajímatelem. Příspěvek Shopify tento algoritmus čištění nespecifikuje, takže tento diagram ukazuje požadavek životního cyklu. Tady je háček.
Co SKIP LOCKED vynechává?
2:14 Skip locked vylučuje uzamčené řádky, takže manuál nazývá jeho výsledek nekonzistentním pohledem. Neposkytuje ani kompletní počet zásob, ani spravedlivé střídání. Ponechejte si kolem něj rozhodnutí o dostupnosti a pravidla doplňování.
Kde byl skutečný strop?
2:26 A ten strop? Jiný kód pokladny držel databázová připojení příliš dlouho. Shopify označil volající a změřil dobu držení připojení, poté vyčistil cestu pokladny a znovu probral souběžnost vláken. Rychlé dotazy se stále mohou řadit mimo dotaz.
Proč bych tento design implementoval?
2:38 Souběžně zapisovali do obou systémů s autoritativním Redis, porovnali výsledky a poté postupně přepnuli s vypínačem. Můj verdikt je SHIP IT. Implementoval bych sdílenou hranici transakcí a to rollbackovatelné nasazení, s celou cestou pokladny instrumentovanou. Máte k tomu otázku? Napište ji do komentářů. A to je dnešní diff.
2:54 Jsem Niko z Axrisi. Sloučit zodpovědně.
Zdroje
- 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



