Přeskoč na hlavní obsah
OpenAI

11. září 2026

Inženýrství

Rychlé škálování online úložiště pro více než miliardu uživatelů ChatGPT

Jak jsme platformu aplikačního úložiště Habitat v Pythonu přizpůsobili bezprecedentnímu růstu.

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

Načítání…

Každý produkt OpenAI závisí na rychlém a spolehlivém přístupu k datům, ať se uživatel přihlašuje, kontroluje nastavení Codexu, nebo zahajuje nový rozhovor v ChatGPT. Každá z těchto akcí může vyžadovat mnoho samostatných načtení dat, než produkt dokáže odpovědět. Pokud jsou tyto požadavky pomalé, působí pomalu i produkt. Pokud tyto požadavky selžou, produkt přestane fungovat úplně.

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. Habitat dnes zpracovává přes 70 milionů požadavků za sekundu a podporuje produkty, které každý týden používá více než miliarda lidí v téměř 40 geografických oblastech. Habitat byl poprvé spuštěn na podporu GPTs při DevDay 2023 jako jednoduchá klientská knihovna v Pythonu připojená k jediné databázi. Dnes jde o komplexní distribuovaný systém, který obsluhuje více než 500 petabajtů dat.

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ší

Vybudovat a provozovat infrastrukturu v tomto měřítku není snadné, ale ani mimořádně náročné. Jedinečné na naší situaci bylo bezprecedentní tempo škálování, které bylo nutné pro podporu ohromného růstu počtu uživatelů a poptávky po produktech, zatímco jsme zároveň budovali vyspělou platformu. Systémoví vývojáři často navrhují produkty na desetinásobné měřítko a doufají, že několik let vydrží, zatímco se připravují na další desetinásobný růst. V našem případě jsme poslední tři roky meziročně rostli více než desetinásobně. Budování a provoz Habitatu proto provázela řada taktických rozhodnutí a pečlivé plánování jejich pořadí: každý prvek jsme zkoumali do nejnižší úrovně, abychom ze stávajícího systému vytěžili maximum, a zároveň jsme odvraceli nedostatek úložné a výpočetní kapacity, abychom získali čas na zásadní investice.

  • Více než 70 mil.

    požadavků za sekundu

  • Více než 1 mld.

    lidí týdně

  • Přes 500 PB

    dat

Jak rostla společnost OpenAI, musel růst i Habitat: nejprve se musela stát dostatečně spolehlivým pro kritický produktový provoz, poté dostatečně rychlým pro uživatele po celém světě a nakonec obratně fungovat v obrovském měřítku. Tento článek je první částí dvoudílné série o škálování online úložiště. Popíšeme v něm vývoj Habitatu, důvody jeho přeměny z knihovny na službu a způsob, jakým jsme ze služby napsané v Pythonu, jazyce pro tento typ provozu neobvyklém, vytvořili spolehlivou platformovou vrstvu úložiště.

V příštím článku podrobně vysvětlíme, jak jsme zajistili spolehlivost provozu s více klienty ve velkém měřítku, naši vícevrstvou strategii optimalizace výkonu čtení a jak jsme rozšířili spolupráci s Azure Cosmos DB, abychom spolehlivě zvládali bezprecedentní poptávku.

Co je Habitat?

Habitat vznikl z jednoduché myšlenky: produktoví vývojáři by se neměli zabývat správou databází. Habitat byl poprvé spuštěn na podporu GPTs při DevDay 2023 jako malá knihovna v Pythonu, která komunikovala s hlavním serverem ChatGPT. Podporoval několik operací, které se na pozadí mapovaly na databázovou aplikaci Azure Cosmos DB.

Úkolem knihovny bylo nabídnout produktovým týmům jednoduchý způsob ukládání a načítání dat bez nutnosti ovládat podrobnosti podkladového systému. Habitat se postaral o vše potřebné: zjistil, o jaký typ dat jde, odkud se mají načíst či kam uložit, zda je požadavek povolen, a podobně.

Produktoví vývojáři se nemusí zabývat vyhledáváním schématu, směrováním, autorizací, šifrováním, serializací, formováním požadavků ani sdružováním připojení. Nemuseli ani řešit, odkud data pocházejí: zda z Azure Cosmos DB, mezipamětí, nebo jiných typů úložišť.

Obrázek 02 · Služba Habitat

Zjednodušený tok požadavku v Habitatu

Oddělením logiky úložiště do samostatné služby jsme získali jednotný řídicí bod pro nasazování, pozorovatelnost a vylepšování platformy.

  • Požadavek
  • Odpověď

Klient

OpenAI

Azure Cosmos DB

Klientská sada SDK Habitatu
envoy
  • habitat-serviceproces 1
  • habitat-serviceproces 2
  • habitat-serviceproces 3
habitat-envoy
  • habitat-cosmos-db-us0
  • habitat-cosmos-db-us1
  • habitat-cosmos-db-eu0

Tato knihovna v Pythonu fungovala dobře a produktoví vývojáři v OpenAI si Habitat rychle osvojili, přestože neprobíhala žádná koordinovaná centrální iniciativa k opuštění samoobslužného Postgresu a Azure Cosmos DB.

S vývojem potřeb produktů mohli produktoví vývojáři do sdílené knihovny snadno přidávat podporu funkcí, jako je ukládání do mezipaměti na straně klienta, komprese nebo šifrování.

Vytvoření služby pro lepší podporu více komplexních produktů

V polovině roku 2025 dosáhl Habitat limitů implementace klientů. S rostoucí složitostí vrstvy Habitat a počtem služeb OpenAI přestaly být zpětně kompatibilní změny protokolu proveditelné.

V jednom případě jsme chtěli omezit dopad výpadku jediné oblasti na nejdůležitější datové sady jejich migrací do skupiny regionálně distribuovaných účtů Azure Cosmos DB. Tato změna vyžadovala přidat do klienta další logiku směrování, ponechat ji vypnutou příznakem funkce, zajistit její nasazení u všech klientů a následně příznak zapnout.

Koordinace nasazení v desítkách služeb a spolupráce s každým týmem na zavedení trvala několik dní. Před aktivací jsme si uvědomili, že chceme přidat stínování požadavků a ověřit správnost logiky dělení. Jeho zavedení trvalo další dva dny. A oprava chyby, kterou jsme mezitím objevili? Další dva dny. Nakonec jsme byli připraveni příznak zapnout. Jeden z týmů však z nesouvisejících důvodů vrátil svou službu k dřívější chybné verzi klienta, což způsobilo právě ten výpadek, kterému jsme se tak usilovně snažili předejít.

Změny klientské knihovny vyžadovaly složitou koordinaci napříč desítkami služeb. Tento proces byl stále křehčí, neefektivnější a náchylnější k provozním selháním. Abychom při budoucím nasazování omezili tento provozní rozptyl, rozhodli jsme se z Habitatu vytvořit samostatnou službu.

Oddělením logiky úložiště do samostatné služby jsme získali jednotný řídicí bod pro nasazování, pozorovatelnost a vylepšování platformy. Místo správy roztříštěných aktualizací jsme mohli zavádět vylepšení centrálně a okamžitě je zpřístupnit každému produktu OpenAI.

Centralizovaná služba nám také nabízí jediný kontrolní bod pro nejsilnější základní mechanismy zabezpečení a ochrany soukromí dat. Ve službě Habitat můžeme centrálně vynucovat zásady řízení přístupu, protokolovat audity a omezovat přístup k podkladovým prostředkům úložiště, jako je Azure Cosmos DB. Habitat hraje zásadní roli při ochraně uživatelských dat a prevenci neoprávněného přístupu externích, interních i agentních aktérů.

Spuštění služby v Pythonu ve velkém měřítku

Věděli jsme, že potřebujeme službu, ale zatím jsme nechtěli Python opustit, přestože jeho použití pro službu přináší dodatečnou režii. Použití Pythonu pro službu s vysokým výkonem zvýšilo síťovou latenci a oproti lokálnímu spouštění knihovny výrazně prodražilo škálování procesoru a paměti. Zároveň jsme věděli, že při stonásobném měřítku už nebude neefektivita Pythonu přijatelná, takže budoucí přepsání bylo téměř jisté.

Považovali jsme to však za strategicky přijaté technické zadlužení. Naším hlavním cílem tehdy nebyla optimalizace nákladů ani zdrojů, ale odstranění překážek pro produktové vývojáře a dosažení stability platformy. Tím, že jsme v krátkodobém horizontu přijali výkonnostní kompromisy spojené se službou v Pythonu, jsme se mohli soustředit na naléhavější problémy, vytvořit základní API a vybudovat robustní infrastrukturu.

Také jsme vědomě vsadili na to, že rychlý pokrok našich vlastních modelů pro programování v budoucnu technické řešení zjednoduší. Vsadili jsme na to, že až bude nutný úplný přechod z Pythonu, Codex a GPT nám ho umožní uskutečnit. Tato sázka se nakonec vyplatila.

Provozovat Habitat jako službu v Pythonu nebylo z hlediska výkonu optimální, ale bylo to nutné. Python nám umožňuje postupovat rychle, to ale neznamená, že jsme mohli přestat být obezřetní a smířit se s výrazně horší latencí. Když průměrný požadavek uživatele vyvolá stovky databázových volání, uživatel pocítí právě to nejpomalejší. Zjistili jsme, že hlavní výzvou při provozu služby v Pythonu v tomto měřítku je řízení koncových latencí.

Sledování zpoždění v asyncio

Asyncio umožňuje Pythonu souběžně zpracovávat úlohy omezené vstupem a výstupem, nedokáže však obejít Python GIL a zajistit paralelní využití procesoru. Vedle předávání požadavků náročného na vstup a výstup zajišťuje Habitat mnoho úloh náročných na procesor a úloh na pozadí: směrování, kompresi, šifrování, kontrolní součty, kontroly stavu návazných systémů, stínování a jištění požadavků.

Při tolika úlohách náročných na procesor a úlohách na pozadí může zpoždění plánování asyncio snadno převládnout v koncové latenci požadavků. Před laděním prvního nasazení služby jsme v trasování požadavků s latencí p99 a vyšší pozorovali, že návazné úložiště sice odpovědělo rychle, ale požadavky často uvázly při čekání, až plánovač znovu spustí příslušnou korutinu a zpracuje odpověď.

Obrázek 03 · Sledování zpoždění asyncio

Souběžnost není paralelní využití procesoru

Asyncio v Pythonu umožňuje souběžné zpracování požadavků, ale ve vlákně procesoru se vždy provádí jen jeden požadavek. Při velkém množství činností procesoru to výrazně ovlivňuje latenci požadavků.

Zpracování požadavku/odpovědi procesoremSíťové čtení/zápis v PythonuČekání na Cosmos

Nízká zátěž procesoru

Krátké kroky Pythonu, čekání na I/O se překrývají

Vysoká zátěž procesoru

Dlouhé kroky Pythonu nechávají připravené odpovědi čekat

0.0 / 40 ilustračních jednotek

U služeb OpenAI v Pythonu je podle nás vedle běžných metrik využití a saturace paměti, procesoru, sítě a disku zásadní sledovat také smyčku asyncio a její vytížení a podle toho systém ladit.

Pravidelným plánováním úloh na pozadí a zaznamenáváním rozdílu mezi očekávaným a skutečným časem spuštění dokážeme empiricky a v reálném čase měřit zpoždění plánování smyčky událostí. Při vysokém vytížení a mnoha náročných úlohách stačí i poměrně málo souběžných požadavků na proces, aby vzniklo výrazné kolísání plánování v řádu stovek milisekund a v krajních případech i několika sekund.

Proto každý proces obsluhuje jen malý počet souběžných požadavků a místo toho masivně škálujeme počet pracovních procesů Pythonu.

Snížení koncové latence v konfiguraci příznaků funkcí

Při prvním spuštění služby jsme díky profilování procesoru za provozu odhalili jednu z hlavních příčin vysokého zpoždění asyncio, a tedy i koncových latencí: pravidelné zpracování konfigurací příznaků funkcí ve formátu JSON prostřednictvím Statsigu (nástroj pro správu příznaků funkcí, A/B testy a další účely).

Statsig byl ve výchozím nastavení nakonfigurován tak, aby bez časového rozptylu každou minutu načítal aktualizované konfigurace, které obsahovaly všechna produkční pravidla všech služeb. Jinde jsme se z architektonických důvodů rozhodli spouštět až osm procesů Pythonu v každém podu, abychom více využili procesor a snížili latenci. V důsledku toho v každém podu jednou za minutu nastal okamžik, kdy všichni jeho pracovníci přestali zpracovávat probíhající požadavky a místo toho využívali procesor ke zpracování obřího konfiguračního souboru.

Jakmile nám profilování procesoru pomohlo odhalit hlavní příčinu, byla náprava snadná: nasadit menší cílenou konfiguraci, prodloužit interval aktualizace a přidat podobným úlohám na pozadí časový rozptyl.

Vyvažování zátěže a správa poolů připojení

Pro udržení nízkého zpoždění asyncio je také zásadní dobře vyvažovat požadavky mezi serverovými procesy. Bez vyladění může sdružování připojení působit přesně opačně.

Při sdružování připojení na straně klienta může jediný klientský proces odesílající mnoho souběžných požadavků navázat jen několik serverových připojení, a veškerou zátěž tak směrovat pouze na několik procesů. Před úpravou vyvažování zátěže se využití naší služby výrazně lišilo a některé procesy na konci rozdělení obsluhovaly pětkrát až desetkrát více souběžných požadavků než průměr.

Odhalili jsme to při náhodném incidentu: přestože jsme zastavili klienta, který část služby přetěžoval, některé procesy zůstaly v omezeném stavu ještě dlouho po odeznění nárazového provozu. Zjistili jsme dokonce, že se stav těchto procesů nekontrolovaně zhoršoval a přijímaly stále více požadavků, dokud jsme je nerestartovali. Jakmile se pod přetížil, určitý mechanismus na něj začal směrovat ještě více provozu. Šlo o typ selhání, který někteří kolegové dobře znali z dřívější práce: metastabilní selhání(otevře se v novém okně).

Podezírali jsme pool připojení. Domněnku jsme ověřili omezením maximální doby opakovaného využívání připojení, což skutečně zmírnilo zhoršování a potvrdilo správný směr šetření. Další šetření ukázalo, že TCPConnector knihovny aiohttp v Pythonu ve výchozím nastavení opakovaně využívá připojení podle LIFO: pro další požadavek vybere naposledy vrácené připojení. Obvykle jde o rozumné výchozí nastavení: opakované využívání nedávných připojení umožní, aby nadbytečným připojením vytvořeným kvůli nárazovému provozu vypršel časový limit nečinnosti, čímž se sníží režie jejich udržování. V tomto případě nám však způsobilo metastabilní selhání. Během nárazové vlny požadavků vracely pomalejší přetížené servery připojení do fondu později, takže je následné požadavky vybíraly častěji. Na podech, které už měly potíže, se tak postupně soustřeďovalo ještě více provozu. Úprava fondu připojení tak, aby je opakovaně využíval podle FIFO, tuto zpětnou vazbu přerušila a zároveň snížila rozptyl požadavků v ustáleném stavu.

Obrázek 04A · Sdružování připojení na straně klienta

LIFO posílá novou práci zpět pomalému procesu

Po nárazové vlně požadavků vracejí pomalejší servery připojení do poolu jako poslední. LIFO podporuje soustředění další práce právě na těchto pomalejších serverech.

Počáteční nárazová zátěž zasáhne A, B a pomalejší proces C.

Obrázek 04B · Sdružování připojení na straně klienta

FIFO přerušuje zpětnou vazbu opakovaného využívání připojení

FIFO po nárazové zátěži zachovává více aktivních připojení, ale spravedlivě vyvažuje práci mezi všemi servery.

Počáteční nárazová zátěž zasáhne A, B a pomalejší proces C.

Dnes v infrastruktuře OpenAI spoléháme převážně na Istio a Envoy, které zajišťují sdružování připojení a lepší strategie vyvažování zohledňující zatížení serverů, takže se tomuto problému zcela vyhneme.

Jak nezahltit návazné prostředky

Jedním z vedlejších účinků ladění na nízké zpoždění asyncio a velkého počtu procesů Pythonu je, že lze obrovským množstvím připojení velmi snadno zahltit návazné závislosti, což se označuje jako „thundering herd“.

Běžné každodenní nasazení může bez nastavení pomalého průběhu způsobit výrazné kolísání zátěže procesoru kvůli obnovování připojení. Únik připojení zase může vyřadit síť saturací brány NAT. Tyto problémy nejsou neobvyklé ani u jiných služeb, ale řádově vyšší počet procesů výrazně snižuje práh jejich vzniku. Často se tak saturují síťové prostředky, u nichž klienti na základě samotného výkonu neočekávají, že je budou muset v ustáleném stavu zvládat.

Na Envoy spoléháme také při maximalizaci slučování připojení. Pomocí Envoy převádíme připojení HTTP/1 Pythonu na HTTP/2, abychom využili multiplexování, a následně je sdružujeme a prodlužujeme jejich životnost. Envoy nám také poskytuje centrální místo pro implementaci limitů frekvence a jističů, které by byly v jednotlivých samostatných procesech Pythonu méně účinné.

Obrázek 05 · Slučování připojení

Stejné požadavky, méně připojení

Sdružování připojení a multiplexování připojení HTTP/2 pomáhají snížit zátěž připojení v návazných systémech.

PožadavekOdpověďNečinné trvalé připojení

Proč toho Habitat dělá méně

Jedním z důvodů, proč jsme mohli Python škálovat až sem, je omezené rozhraní API Habitatu, díky němuž jsou náklady požadavků předvídatelné. Místo aby klientům umožňoval sestavovat libovolné SQL dotazy, které mohou vést k rozsáhlému procházení tabulek nebo spojování mnoha tabulek, nabízí Habitat jednoduché rozhraní NoSQL API. Omezené možnosti rozhraní API jsou záměrným kompromisem v návrhu Habitatu.

Optimalizujeme s cílem dosáhnout jednoduchých a předvídatelných požadavků s konstantní náročností. Podle našich zkušeností se takové systémy výrazně snáze škálují a je obtížné je špatně navrhnout nebo používat. Požadavky s nepředvídatelným rozvětvením jsou provozně nebezpečné: komplikují izolaci a vyvažování zátěže a vytvářejí prudké nárůsty latence, na které se obtížně škáluje služba i její klienti.

Před přechodem na Habitat a Azure Cosmos DB byla většina online dat OpenAI uložena v Postgresu. Tehdy bylo snadné před nasazením do produkce zkontrolovat všechny změny dotazů a schémat a ověřit, že se chovají správně a pracují s indexovanými daty. Jak rostly týmy a produkty, stalo se to nezvladatelným a častou příčinou výpadků byl jediný nový náročný dotaz na kritické cestě, který vyřadil databázi.

Problém spočívá v nerovnováze nákladů: napsat dotaz SQL, jehož spuštění je náročné a obtížné, je levné a snadné. V Habitatu se tomu vyhýbáme a náročné dotazy jsou na straně klienta zcela zřejmé. Habitat neumožňuje neohraničené dotazy, které by ho mohly přetížit. Složité spojování a procházení grafů navíc vyžaduje část práce od produktových týmů, což celkově podporuje efektivnější návrhy.

Habitat nabízí rozhraní NoSQL API založené na typech objektů a hran definovaných klientem, inspirované systémem TAO(otevře se v novém okně). Klienti předem definují objekty, hrany a jejich vzájemné vztahy, nikoli však obsah jednotlivých typů. Výsledné vztahy připomínají graf, samotný Habitat však kromě dotazování na přímé hrany konkrétního objektu běžné dotazy pro průchod grafem nepodporuje.

Graf dělíme tak, aby byl každý objekt se svými hranami umístěn ve stejném oddílu úložiště. Na úrovni databáze se však nesnažíme společně umisťovat objekty a vzdálené objekty, na které jejich hrany odkazují. Výsledný model lze snadno rozdělit pro horizontální škálování, procházení grafu je však neefektivní, protože každý přechod mezi objekty může vyžadovat načtení ze dvou zcela odlišných účtů Azure Cosmos DB uložených v různých oblastech.

Klientům se složitějšími požadavky na dotazování poskytujeme sekundární offline pohled na Habitat prostřednictvím Rocksetu. Pomocí funkce change data capture (CDC) streamujeme změny z online úložiště do izolovaných instancí Rocksetu téměř v reálném čase. Každý klientský tým odpovídá za škálování vlastní instance Rocksetu podle svých potřeb složitého dotazování.

Poskytování Rocksetu přináší klientům další komplikace, v této chvíli je však považujeme za správný kompromis: jednoduché dotazy zůstávají výchozí možností a kdo potřebuje složité dotazy, má k dispozici alternativu. Tento návrh izoluje naše online úložiště od analytických a vyhledávacích úloh náročných na čtení.

Přechod z Pythonu na Rust

Odložení přepisu Pythonu o rok nám během hyperrůstu umožnilo soustředit se na naléhavější problémy s větším dopadem. Platforma dozrávala, růst dál zrychloval a naše služba byla v OpenAI druhá největší podle počtu jader a čtvrtá podle rozsahu nasazení Envoy. Nastal tedy čas Python opustit. Na vrcholu nám Python pomáhal obsluhovat více než 20 milionů požadavků za sekundu.

Ve druhém čtvrtletí roku 2026 jsme s pouhými dvěma vývojáři, Codexem a GPT‑5.5 dokázali celou službu přepsat do Rustu. Nová služba v Rustu nyní zpracovává 95 % produkčních požadavků a v příštích týdnech Python zcela vyřadíme. Podle našich dat je služba v Rustu šestkrát efektivnější ve využití procesoru a patnáctkrát efektivnější ve využití paměti než verze v Pythonu a má výrazně nižší průměrnou i koncovou latenci. O další poznatky se plánujeme podělit v některém z budoucích článků.

Optimalizace databázové vrstvy Azure Cosmos DB

Služba v Pythonu, a nyní v Rustu, je jen jednou částí Habitatu. Ve druhé části této série o rychlém škálování online úložiště pro více než miliardu uživatelů ChatGPT se zaměříme na vrstvu úložiště a na to, jak Habitat obsluhuje přes 500 petabajtů dat a více než 70 milionů požadavků za sekundu.

Pokud chcete pracovat na systémech OLTP ve špičkovém rozsahu a tento typ vývoje vás zajímá, podívejte se na volnou pozici v našem týmu.

Autoři

Jon Lee, Chaomin Yu, Ben Ries