OpenAI

23. října 2026

Inženýrství

Rychlé naškálování online úložiště pro více než 1 miliardu uživatelů ChatGPT (část II)

Jak jsme optimalizovali Azure Cosmos DB v naší platformě pro ukládání aplikačních dat Habitat, abychom zvládli bezprecedentní růst.

Autoři: Jon Lee, Hrachya Hakobyan a Chaomin Yu, členové technického týmu

Načítání…

Všechny produkty OpenAI vyžadují rychlý a spolehlivý přístup k datům, který zajišťuje naše úložná platforma Habitat. Musí odpovídat v řádu milisekund více než 1 miliardě uživatelů ve 40 geografických regionech. Naše infrastruktura čelila mimořádné výzvě: zvládnout prudký růst a nové případy použití a zároveň dál zlepšovat spolehlivost, výkon a rychlost vývoje produktů. Abychom tuto výzvu zvládli, museli jsme přehodnotit návrh i provoz naší platformy pro online ukládání dat. Neustále jsme zvažovali kompromisy a postupovali podle zásady: nejdřív dosáhnout dostatečné spolehlivosti pro kritický produktový provoz, pak dostatečné rychlosti pro uživatele po celém světě a nakonec efektivně zvládat provoz v obrovském měřítku.

Tato dvoudílná série vysvětluje, jak jsme Habitat vyvinuli z jednoduché klientské knihovny a databáze v globálně distribuovanou úložnou platformu obsluhující přes 500 petabajtů dat. První část se věnovala proměně Habitatu z klienta v Pythonu ve službu. Popsala také postupy, díky nimž jsme službu v Pythonu posunuli daleko za hranice toho, co by mnozí považovali za prakticky možné.

V této druhé části popisujeme, jak jsme škálovali podkladovou úložnou komponentu: Azure Cosmos DB. V úzké spolupráci s týmem Azure jsme dospěli k funkčnímu řešení pro více tenantů založenému na společně spravovaných kontejnerech, které nabízí vynikající výkon čtení v obrovském globálním měřítku.

Obrázek 01 · Co je Habitat?

Platforma online úložiště

Habitat je platforma online úložiště, kterou jsme vytvořili, aby produkty OpenAI mohly rychle a spolehlivě přistupovat k potřebným informacím.

  • Požadavek
  • Odpověď
  • Změny (CDC)

Klienti

Platforma online úložiště

Prostředky úložiště

  • ChatGPT
  • API
  • Codex
  • Interní služby
  • A další

Habitat

  • Ukládání do mezipamětiMezipaměti
  • Zásady ACLAutorizace
  • Umístění a datová rezidenceDatová rezidence
  • ŠifrováníZabezpečení dat
  • IzolaceVíceklientský provoz
  • Omezování frekvenceFormování požadavků
  • SměrováníVyhledání schématu · Datová rezidence
  • Azure Cosmos DBOnline úložiště
  • NanobaseOnline úložiště
  • ValkeyMezipaměti
  • Objektové úložištěProstředky úložiště
Služby CDCZachytávání změn dat
  • Databricks
  • Rockset
  • Kafka
  • A další

Spolehlivý provoz více tenantů ve velkém měřítku

S růstem firem infrastrukturní týmy často přecházejí od systémů jednoho tenanta k systémům více tenantů. V prostředí jednoho tenanta si každý tým odpovědný za část produktu udržuje vlastní systém. Tím se omezuje dopad případných problémů, jasně vymezuje odpovědnost a zajišťuje izolace úloh. Jak týmy a jednotlivé části produktů rostou, je takový provoz stále dražší. Prostředí jednoho tenanta přenáší odpovědnost za plánování kapacity na každý produktový tým a často vede k výraznému předimenzování zdrojů.

Naproti tomu prostředí více tenantů svěřuje správu centrálnímu databázovému týmu, který má s přidělováním zdrojů více znalostí a zkušeností. Přináší však i vlastní problémy, například hlučné sousedy, kdy jeden tenant spotřebovává neobvykle velký podíl zdrojů na úkor ostatních.

Při návrhu Habitatu jsme museli všechny tyto kompromisy zvážit, abychom vytvořili spolehlivý a efektivní úložný systém pro velké měřítko. Dnes je Habitat databázovou vrstvou pro více tenantů, kterou využívá mnoho produktů OpenAI. Naše cesta ale opsala kruh: od jednoho kontejneru Azure Cosmos DB pro více tenantů přes zřizování podkladových kontejnerů pro jednotlivé tenanty až po návrat ke sdílenému kontejneru jako výchozí volbě. S podporou více tenantů v Habitatu jsme stále na začátku. Podporujeme širokou škálu případů použití, ale investice do této oblasti jsme mohli odložit díky tomu, že všude, kde to šlo, využíváme základní mechanismy zabudované v Azure Cosmos DB.

Stručný úvod do kontejnerů Azure Cosmos DB

Než popíšeme naši cestu s Azure Cosmos DB, uvedeme několik základních informací:

  • Účet Azure Cosmos DB definuje sadu kontejnerů a zásady replikace

  • Každému kontejneru se zřizuje určitý výkon v jednotkách požadavků za sekundu (RU/s)

  • Data v každém kontejneru se standardně dělí do shardů podle zadaného klíče logického oddílu, přičemž pro každý takový klíč platí zdokumentované limity úložiště a výkonu

  • Azure Cosmos DB rozděluje klíče logických oddílů mezi menší počet podkladových fyzických oddílů. Ty dále dělí, když objem uložených dat překročí prahovou hodnotu nebo když kontejner potřebuje více fyzických oddílů k zajištění zřízeného výkonu

Fáze I: Spoléhání na základní mechanismy Azure Cosmos DB

Zpočátku jsme propouštěli veškerou klientskou zátěž a spoléhali na to, že uváděný limit 10 tis. RU/s na klíč logického oddílu zajistí zpětné omezení zátěže. Na začátku jsme také v každém účtu používali jen jeden výchozí kontejner Azure Cosmos DB. Fungovalo to poměrně dobře, ale z několika důvodů se ukázaly problémy:

Limity klíčů logických oddílů

Kvůli raným rozhodnutím při návrhu API jsme výběr klíče logického oddílu zpřístupnili přímo klientům. Mezi různými případy použití produktů tak často dochází ke kolizím u běžných klíčů oddílů, například user_id nebo workspace_id. Protože tyto případy použití sdílely limity Azure Cosmos DB pro stejné klíče logických oddílů, návrh omezoval celkový výkon dostupný danému uživateli.

Před přechodem na Habitat a Azure Cosmos DB jsme při škálování Postgresu často řešili problém, kdy velké množství požadavků od mimořádně aktivní organizace nebo na silně vytížený klíč dokázalo vyřadit celou databázi. Šlo o jediného tenanta, který vytvářel neúměrně vysokou zátěž. Společně jsme vynaložili značné úsilí na ukládání těchto klíčů do mezipaměti a zavedení dočasných zámků při nenalezení dat v mezipaměti, aby výsledná zátěž nepřetížila podkladovou databázi.

Figure 02a · Logical partition key limits

Different clients, the same partition key

Cosmos DB containerPhysical partitionPK: user-id-28104CapacityMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedConversationsSuccess rateResponses returned in this animation loop—AuthSuccess rateResponses returned in this animation loop—Memory / dreamingSuccess rateResponses returned in this animation loop—

Hluční sousedé

Ačkoli se zdokumentované limity velikosti dat a výkonu vztahují na klíče logických oddílů, ve skutečnosti se vynucují na úrovni fyzického oddílu. V praxi to znamená, že logické oddíly nedokážou dosáhnout 10 000 RU/s. Místo toho sdílejí limity fyzického oddílu se všemi ostatními klíči logických oddílů umístěnými na témže fyzickém oddílu.

Hluční sousedé tak mohli ovlivňovat mnoho nesouvisejících klíčů logických oddílů. Úlohy pracující s daty okrajových funkcí produktů narušovaly základní procesy přihlášení a registrace.

Figure 02b · Noisy neighbors

Different users, the same physical partition

Cosmos DB containerPhysical partitionPKs: user-id-28104, user-id-10384Conversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversationsuser-id-28104Success rateResponses returned in this animation loop—Conversationsuser-id-10384Success rateResponses returned in this animation loop—

Slabé oddíly

Limit výkonu daného fyzického oddílu je navíc proměnlivý: závisí na celkovém výkonu přiděleném kontejneru Azure Cosmos DB. Zřízený výkon kontejneru se rozděluje přibližně rovnoměrně mezi jeho fyzické oddíly.

S růstem objemu dat se fyzické oddíly dělí, takže jejich celkový počet roste, zatímco celkový zřízený výkon zůstává stejný. Výsledkem je, že efektivní limit výkonu na jeden oddíl s rostoucím objemem dat klesá.

U našich případů použití s nejvyššími nároky na úložiště, připomínajících ukládání blobů, to vede k situaci, kdy samotný růst uložených dat snižuje dostupný výkon pro aktivní úlohy, i když frekvence požadavků a využití zůstávají stabilní.

Figure 02C · Weak partitions

The limit falls below demand

A partition splits when it reaches its storage limit. Each child receives half the throughput capacity.

Before split: 10K RU/s capacity

After split: 5K RU/s capacity × 2 partitions

RU/s05K6K10K200200429

Fáze II: Pokusy s izolací úloh a prostředím pro jednoho tenanta

Oddělené kontejnery pomáhají částečně řešit limity klíčů oddílů i problém hlučných sousedů. Každému samostatnému kontejneru lze přidělit vlastní nezávislé fyzické oddíly. Hlučnými sousedy se pak mohou stát jen úlohy v daném kontejneru a pouze mezi nimi se mohou překrývat klíče oddílů. Zřizování nových kontejnerů má ale svou režii: každý vyžaduje samostatné plánování kapacity. Chceme je proto vytvářet jen tam, kde dává smysl oddělit služby nebo případy použití.

Pro nejkritičtější nové případy použití vyžadující silnou izolaci jsme začali používat samostatné kontejnery Azure Cosmos DB. Zároveň jsme nasadili skript, který řešil slabé oddíly tím, že přizpůsoboval celkový zřízený výkon každého kontejneru počtu jeho fyzických oddílů. Díky této kombinaci jsme se do značné míry vyhnuli všem dosavadním problémům.

Protože jsme ale začínali s jedním výchozím kontejnerem, mnoho starších kritických úloh v něm bohužel muselo zůstat, dokud se neprovedla migrace dat. Abychom chránili kritické služby, které stále závisely na datech ve sdíleném výchozím kontejneru, často jsme týmům doporučovali vytvářet pro nové služby či významné funkce produktů samostatné kontejnery. S rostoucím měřítkem rostla zátěž výchozího kontejneru i počet incidentů v produkci. Začali jsme zřizovat kontejnery pro každou novou službu nebo rozsáhlou funkci produktu, jen abychom výchozí kontejner ochránili před další zátěží.

Ušetřilo nás to mnoha celkových výpadků. Dopad se omezil na výpadky či zhoršení fungování jednotlivých funkcí a služeb. Režie spojená se zřizováním nových kontejnerů nás ale nakonec dostihla:

Chybějící stabilní růst souhrnné zátěže

V původním sdíleném výchozím kontejneru bylo nepravděpodobné, že by růst jednoho nového případu použití z 0 na 1 milion QPS výrazně změnil celkové využití. V izolovaném kontejneru ale stejný růst z 0 na 1 milion QPS mohl znamenat 1 000násobnou zátěž oproti výchozímu stavu tvořenému pouze interním testováním produktu.

S vyhrazenými kontejnery teď týmy musely pamatovat na to, aby jim před spuštěním přidělily výkon odpovídající očekávané zátěži. Produktové týmy často nasadily funkce do produkce a zapomněly předem navýšit kapacitu. V den spuštění jsme pak seděli na krizových schůzkách k závažným incidentům a snažili se kontejnery na poslední chvíli zvětšit.

Právě vyrovnávání zátěže kombinací různých úloh je zásadní výhodou systémů pro více tenantů, kterou touto kontejnerovou strategií obětujeme ve prospěch lepší izolace.

Figure 03 · Lack of stable aggregate growth

The same workload, different headroom

1K RU/s during load testing → 1M RU/s at launch

Shared container

100M RU/s capacity · 80% utilized

Load test

1K20M=

0.005%

of headroom

Launch

1M20M=

5%

of headroom

New dedicated container

10K RU/s capacity · no other workloads

Load test

1K10K=

10%

of headroom

Launch

1M10K=

10,000%

of headroom

Plánování kapacity

Sledování využití vyhrazených kontejnerů postupem času také vyžadovalo podrobnou znalost produktu: kdy se provoz změní nebo poroste.

Můžeme poskytnout jednoduchý skript v řídicí vrstvě, který navyšuje zřízený výkon jednotlivých kontejnerů podle růstových trendů. Bez stabilního růstu souhrnné zátěže ale správné škálování v podstatě vyžadovalo zapojení každého produktového týmu v OpenAI do plánování kapacity.

Z organizačního hlediska tento přístup neškáloval. Jednotlivé týmy odpovědné za služby věnovaly dimenzování Azure Cosmos DB velmi rozdílnou míru péče.

Fáze III: Sdílení mezi tenanty jako výchozí volba s možností přesunu dat

S růstem organizace bylo stále těžší tyto provozní problémy zvládat. Chyběl jediný centrální tým pro plánování, a tak mnoho týmů plánovalo špatně. Nakonec jsme se proto vrátili k řešení pro více tenantů. V úzké spolupráci s týmem Azure jsme upravili návrh sdíleného prostředí tak, abychom vyřešili původní problémy:

Omezování požadavků na vytížené klíče

Přednostní omezování požadavků na nejvytíženější klíče brání hlučným sousedům spotřebovat veškerý dostupný výkon daného fyzického oddílu. Tím se zmírňuje jejich vliv, kdy jediný vytížený klíč může zasáhnout celý web.

Kvalita služeb (QoS)

QoS založená na úrovních požadavků podobně brání offline úlohám, například hromadnému vkládání nebo extrakci dat, aby spotřebovaly veškerý výkon daného fyzického oddílu. Požadavkům těchto úloh přidělujeme nižší prioritu, takže se omezují jako první. Interaktivní požadavky s vyšší prioritou, které obsluhují koncové uživatele, tak zůstávají bez omezení.

Bezserverový režim

Azure Cosmos DB již nabízela bezserverový režim, který by vyřešil náš problém se slabými oddíly v režimu se zřízeným výkonem. Měl ale zásadní nevýhodu: škáloval pouze podle využití úložiště a omezoval spotřebu RU na 5 tis. RU/s na fyzický oddíl. Vyřešil by tedy slabé oddíly, ale znemožnil by nám škálovat případy použití s vysokou spotřebou RU.

Tým Azure Cosmos DB pro nás vytvořil vylepšený bezserverový režim. Ten umožnil každému fyzickému oddílu škálovat až na 10 tis. RU/s a kromě dělení podle využití úložiště zavedl i dělení podle spotřeby RU. Díky tomu jsme přestali kontejnery ručně sledovat a navyšovat jejich kapacitu.

Díky těmto změnám jsme se mohli vrátit k jednomu sdílenému kontejneru. Produktovým týmům to výrazně usnadnilo počáteční i průběžné plánování kapacity a zároveň zůstala zachována izolace úloh. Za několik měsíců od té doby jsme nezaznamenali žádný incident související s přidělováním kapacity nebo hlučnými sousedy, přestože se vývoj produktů zrychluje.

Vyšší spolehlivost díky společné správě služeb

Když firmy dosáhnou velikosti OpenAI, spravované služby už nejsou tak úplně „spravované“. Mnohé úlohy se v infrastruktuře cloudového poskytovatele vymykají běžným parametrům. Když se OpenAI stala jedním z největších uživatelů Azure Cosmos DB, úspěšný provoz vyžadoval jiný přístup: společné testy, sdílené přehledy, přímé komunikační kanály mezi vývojáři a společnou odpovědnost za selhání, která se objevují až v našem měřítku. Dnes náš největší účet Azure Cosmos DB ukládá desítky petabajtů dat a obsluhuje přes 20 milionů QPS. Pokud víme, jsme jediná firma, která Azure Cosmos DB nasadila v takovém měřítku.

Koncem roku 2024 regionální výpadek jasně ukázal, proč je tato spolupráce nezbytná. Výpadek napájení tehdy zasáhl primární region Azure jednoho z našich největších účtů Azure Cosmos DB. Při následném přepínání na záložní region jsme zjistili, že u největších účtů potrvá přechod několik hodin. Ani náš tým, ani tým Azure Cosmos DB to v našem měřítku neotestoval.

Zhruba o měsíc později jsme při přepínání těchto účtů zpět do původního regionu vyvolali další závažný výpadek. Nápor připojení do původního regionu zahltil tamní bránu Azure Cosmos DB. Zvláštnost ve způsobu, jakým klient Azure Cosmos DB v režimu brány řešil přepínání při selhání, způsobila, že všichni klienti okamžitě navázali spojení a začali odesílat požadavky do původního regionu, přestože se do něj vrátila jen část fyzických oddílů.

Při každém výpadku OpenAI i Azure postupovaly podle svých procesů řízení incidentů, identifikovaly řadu hlavních příčin a nasadily opravy. Tyto výpadky ale byly příznakem širšího systémového problému v tom, jak náš tým a tým Azure Cosmos DB provozovaly a testovaly své systémy. Zpočátku nám spravované služby umožnily postupovat rychle a soustředit se na obchodní cíle. Ve velkém měřítku ale poskytovatel nepřebírá tolik správy a služby vyžadují hluboké propojení s jeho týmem na všech úrovních, od návrhu po provoz.

Dnes vývojové týmy Habitatu a Azure společně monitorují každou vrstvu Habitatu, od našich služeb až po fyzické úložné vrstvy Azure Cosmos DB. Provozujeme neprodukční účet Azure Cosmos DB o velikosti produkčního prostředí a testujeme na něm změny. Společně testujeme a zdokonalujeme SDK a stanovujeme osvědčené postupy pro škálování a dimenzování našich účtů Azure Cosmos DB. Naše vývojové týmy spolu přímo komunikují přes Teams a zavedli jsme i možnost vzájemně si přímo vyvolat pohotovost, aniž bychom museli procházet jednotlivými úrovněmi podpory.

Za poslední rok jsme společně odvedli značný kus práce na zlepšení škálovatelnosti řídicí vrstvy a brány Azure Cosmos DB. Do brány jsme přidali ochranu proti přetížení a ukládání různých metadat Azure Cosmos DB do mezipaměti, abychom chránili oddíl s metadaty. Sdílením připojení v poolu a jejich častějším opětovným používáním jsme snížili zátěž z naší flotily procesů habitat-service v Pythonu. Kde to bylo možné, umístili jsme úlohy do stejné lokality a pomocí oddělených VPC jsme izolovali kritické úlohy od úloh běžících offline.

Takto úzká vývojová spolupráce byla v posledním roce zásadní pro stabilitu našeho Azure Cosmos DB. Každý dostatečně velký nebo kritický systém vyžaduje tento druh týmové práce: překonávání hranic odpovědnosti i organizačních bariér.

Zlepšování výkonu v globálním měřítku

Jak jsme uvedli v první části, naše základní filozofie zní: nejdřív zajistit funkčnost, pak rychlost a nakonec nízké náklady. Nejdřív spolehlivost, pak výkon a nakonec efektivita. Habitat se stal kritickou infrastrukturou OpenAI, takže první prioritou bylo zajistit jeho spolehlivost. Když se systém v roce 2025 stabilizoval a OpenAI expandovala po celém světě, dalším omezením pro uživatele i produktové týmy se stala latence.

Výpočetní a úložné kapacity se často nacházely v různých regionech, takže požadavkům napříč regiony se nešlo vyhnout.

Figure 04 · Improving performance at a global scale

Global traffic

Compute and storage capacity were often located in different regions, making cross-region requests unavoidable.

ComputeStorageIllustrative routes · Longer journeys take more time

Geografické umístění výpočetních prostředků a úložišť je pouze ilustrační.

Latence se výrazně lišila podle toho, kde byla data uložena a kde se požadavek zpracovával. Aby byly požadavky na Habitat rychlé, vývojáři produktů používali další mezipaměti na straně klienta, dávkovali požadavky, minimalizovali čtení a zápisy do databáze a přesouvali práci mimo kritickou cestu, kde to jen šlo. Vznikla tak sice zajímavá produktová řešení odolnější vůči problémům s databází, ale produkty se zároveň staly složitějšími a jejich vývoj se zpomalil. Nenaplnili jsme tedy cíl Habitatu: umožnit rychlý vývoj produktů bez nutnosti rozumět databázi.

V roce 2026 se na tuto oblast intenzivně zaměřujeme. Vyvinuli jsme vícevrstvou strategii pro optimalizaci výkonu čtení, které tvoří přes 90 % požadavků na Habitat:

Ukládat data blízko uživatelů, pokud to kapacita dovolí

Pro uživatele s požadavky na datovou rezidenci máme řadu účtů Azure Cosmos DB v různých regionech Azure po celém světě. I u uživatelů bez striktních požadavků na datovou rezidenci zlepšuje umístění dat v jejich blízkosti uživatelský zážitek díky nižší latenci.

V praxi to ale mimo případy vyžadující datovou rezidenci nedokážeme zajistit plošně, protože umístění omezuje fyzická kapacita cloudu. Vzhledem k velikosti našich datových sad nedokáže mnoho regionů pojmout obrovský objem dat odpovídající jejich podílu na uživatelském provozu.

V regionech s omezenou kapacitou datových center, napájení či chlazení někdy stojíme před přímou volbou: vyhradit kapacitu pro místní úložiště a snížit latenci Habitatu, nebo ji využít pro další výpočetní prostředky obsluhující požadavky a požadavky na úložiště směrovat dál.

Rozhodování o umístění je tak často produktovým kompromisem mezi A) optimalizací latence pro různé produkty a skupiny uživatelů a B) samotnou úložnou a výpočetní kapacitou.

Plošně replikovat jen nejmenší datové sady s nejvyššími nároky na latenci

U úloh s nejvyššími nároky na latenci, například u autentizačních metadat potřebných při každém požadavku, zkracujeme dobu obousměrné komunikace (RTT) mezi výpočetními prostředky a Habitatem pomocí účtů Azure Cosmos DB s rozsáhlou replikací do mnoha sekundárních regionů. Některé účty replikují data do všech 40 regionů Azure, kde obsluhujeme provoz; jiné alespoň do jednoho regionu na každém kontinentu.

Do Habitatu jsme museli dříve, než jsme chtěli, zabudovat transparentní vrstvu pro přesun dat a směrování, abychom mohli přesouvat datové sady mezi účty s různými replikačními topologiemi.

I tento přístup však nakonec naráží na kapacitní omezení, a proto jej používáme jen pro několik pečlivě vybraných datových sad.

Pro vše ostatní využít integrovanou mezipaměť

V úlohách Habitatu výrazně převládá čtení. Aplikace neustále načítají nastavení, stav a další vlastnosti; neúměrně velký podíl provozu připadá na poměrně malou pracovní sadu často používaných typů. Systém je proto mimořádně vhodný pro distribuovanou mezipaměť. Mezipaměť zlepšuje výkon už v infrastruktuře jednoho regionu, ale při práci napříč regiony se její přínos násobí: může „skrýt“ latenci meziregionální komunikace.

Do Habitatu jsme integrovali distribuovanou vrstvu mezipaměti typu lookaside. Ukládá kopie nedávno načtených objektů a hran na serverech Valkey umístěných v naší infrastruktuře blízko míst, kde se zpracovávají uživatelské požadavky. Takové mezipaměti obvykle používají dobu platnosti (TTL), která představuje kompromis mezi mírou zásahů do mezipaměti a zastaralostí dat. Krátké TTL snižuje zastaralost dat, ale oslabuje přínos mezipaměti, protože položkám rychle vyprší platnost a musí se častěji načítat znovu. Delší TTL zvyšuje míru zásahů, ale po delší dobu vrací zastaralá data, což zhoršuje uživatelský zážitek a vede k nepředvídatelnému chování produktu.

Další možností je explicitně zneplatňovat položky mezipaměti, když aplikace zapisuje do odpovídajících podkladových dat. To výrazně zlepšuje aktuálnost dat v mezipaměti, ale správná implementace může být obtížná. Nadále navíc hrozí řada okrajových situací, například částečná selhání, po nichž mezipaměť zůstane zastaralá. Nasazení ve více regionech tyto problémy násobí: meziregionální sítě jsou méně spolehlivé a operace s mezipamětí soupeří s replikací podkladového úložiště. Doplnění TTL sice omezí maximální stáří dat, ale stále přináší tentýž základní kompromis popsaný výše.

Zvolili jsme pokročilejší přístup ke zneplatňování, inspirovaný systémy jako TAO od společnosti Meta. Integrovaná mezipaměť Habitatu využívá zachytávání změn dat (CDC) prostřednictvím kanálu změn Azure Cosmos DB. Zneplatnění tak šíří po celém světě během sekund a dosahuje vysoké míry zásahů při nízké zastaralosti dat. Služba v naší infrastruktuře tento kanál změn odebírá a při aktualizaci podkladových dat zneplatňuje položky v místních mezipamětích. Při příštím čtení se proto data v mezipaměti nenajdou a mezipaměť se naplní jejich nejnovější verzí.

Snížit režii proxy pomocí Rustu

Latenci jsme výrazně snížili také odstraněním režie v samotné službě Habitat: kód jsme přepsali do Rustu, který je výkonnější než původní Python.

Tyto změny společně snížily celkovou globální latenci čtení p50 ze zhruba 120 ms na přibližně 10 ms. Od začátku letošního roku, kdy jsme se začali zaměřovat na výkon, jde o 12násobné zrychlení.

Figure 05 · Improving performance at a global scale

p50 latency for reads

Three major design changes improved read latency

roughly 120 ms → roughly 10 ms

12x improvement

Milliseconds020406080100120140160Čas123
  1. critical data replicated into nearby geos
  2. in-region caching launched
  3. rust rewrite launched

Mezipaměť sice výrazně snížila medián latence, ale nejpomalejší požadavky stále vyžadují načítání dat mimo mezipaměť z podkladového úložiště, často ve vzdálených regionech. S přibývající kapacitou a zlepšováním efektivity úložiště plánujeme řešit zásadnější výzvu: ukládat data už od začátku blíže místu, odkud se budou načítat.

Škálování zachytávání změn dat

Spolehlivé a škálovatelné CDC, tedy šíření databázových změn do navazujících systémů, je klíčovou součástí nejen strategie mezipaměti Habitatu. Miliony zachycených změn za sekundu z tisíců kontejnerů a milionů jejich oddílů proudí přes více než stovku témat Kafky. Napájejí také sekundární indexy s eventualní konzistencí, datové toky pro přesun dat, offline analytiku a další funkce produktů pracující v reálném čase. S globálním růstem naší podkladové infrastruktury je sledování změn řádků stále složitější. Pokud chce klient zaregistrovat zpětné volání spouštěné při každé změně řádků svého typu, musí nejprve mimo jiné zjistit, které účty a kontejnery Cosmos obsahují jeho data a které nasazení služby CDC v příslušných regionech tyto kontejnery sleduje. Musí také správně škálovat flotilu pracovních procesů CDC, Kafku i svého konzumenta. Naše platforma CDC má za cíl všechny tyto detaily před vývojáři produktů skrýt. Místo nich nabízí jednoduché rozhraní, v němž si klienti zaregistrují funkci, která se má volat při změně jejich řádků. Veškeré propojení a škálování pak řešíme my.

Interní řídicí vrstva průběžně zajišťuje zachytávání změn ze všech požadovaných kontejnerů, vybírá regiony Cosmos pro čtení a efektivně rozděluje práci mezi tisíce pracovních procesů ve více geografických regionech. Používání replik regionů a čtení kanálu změn s nižší prioritou chrání provoz Habitatu citlivý na latenci před úlohami zachytávání změn na pozadí. V takto rozsáhlé flotile neustále dochází k pádům pracovních procesů, problémům s kontejnery, chybám úložiště dočasných zámků, neplatným konfiguracím i selháním cílových systémů. Posílili jsme odolnost životního cyklu pracovních procesů CDC i správy dočasných zámků, izolovali selhání mezi datovými toky a zavedli ochranné mechanismy pro změny konfigurace a nasazování. Používáme fronty nedoručitelných zpráv, aby trvalá selhání doručení neblokovala zpracování dalších zpráv. Regionální výpadky zvládáme přepnutím čtecích procesů do alternativních regionů Cosmos. V našem měřítku jsme dokonce museli upravit SDK pro CDC od Azure, aby efektivněji zpracovávalo kontrolní body: seskupovalo je do dávek v paměti a zapisovalo je trvale jen v pravidelných intervalech.

Ačkoli je interní využití Azure Cosmos DB v Habitatu složité, jeho hlavní přínos vždy spočíval v ukrytí detailů infrastruktury před vývojáři produktů, aby mohli vyvíjet rychleji. U naší platformy CDC je tomu stejně.

Výhled do budoucna

Malý tým dokázal podporovat rychle rostoucí úložnou platformu tím, že záměrně udržoval API úložiště úzce zaměřené, dál škáloval službu v Pythonu a dával přednost nejnaléhavějším technickým výzvám. Nejdřív jsme se zaměřili na spolehlivost kritického produktového provozu, pak na výkon čtení pro uživatele po celém světě a nakonec na provozní efektivitu ve velkém měřítku. Tento přístup umožnil rychlý růst a nové případy použití a zároveň zlepšil spolehlivost, výkon i rychlost vývoje produktů.

Abychom Habitat a úložiště konverzací připravili na další miliardu uživatelů, musíme vyřešit obtíže s replikací našich dat napříč naší infrastrukturou v ještě větším měřítku. Proto už vyvíjíme vlastní systém pro online ukládání dat v exabajtovém měřítku, optimalizovaný pro objemné datové typy Habitatu. Tento vyvíjený systém kombinuje jádro RocksDB Cloud od Rocksetu s replikací založenou na protokolu Raft. Implementuje stejný dokumentový model jako Azure Cosmos DB, ale využívá oddělené úložiště a fyzickou replikaci, aby snížil potřebnou kapacitu flash za cenu nižšího maximálního počtu dotazů za sekundu ve špičce.

Pokud vás láká práce na datové infrastruktuře tohoto typu v dosud nevídaném měřítku, podívejte se na naše volné pozice⁠.

Autor

OpenAI