Eszközök

Mesterséges intelligenciával generált szöveg

Hogyan skálázta az OpenAI a Habitat tárolórétegét Azure Cosmos DB-vel a több milliárdos felhasználói bázis kiszolgálásához

A cikk főszereplői Jon Lee, Hrachya Hakobyan és Chaomin Yu, valamint az OpenAI Habitat tárolóplatformja és az Azure Cosmos DB.

Hogyan skálázta az OpenAI a Habitat tárolórétegét Azure Cosmos DB-vel a több milliárdos felhasználói bázis kiszolgálásához

(Szerzők: Jon Lee, Hrachya Hakobyan, Chaomin Yu — Members of Technical Staff)

OpenAI termékei alacsony késleltetésű és megbízható adat-hozzáférést igényelnek; ezt a Habitat nevű tárolóplatformunk biztosítja. A rendszernek milliszekundumos válaszidővel kell kiszolgálnia több mint 1 milliárd felhasználót körülbelül 40 földrajzi régióban. Ahogy a felhasználói és termékigények robbanásszerűen nőttek, az infrastruktúra újraértékelését igényelte: először a megbízhatóságot kellett biztosítani, utána a globális sebességet, végül a nagyméretű üzemeltetés egyszerűsítését.

Ez a cikksorozat második része azt ismerteti, hogyan skáláztuk az alapszintű tárolót: az Azure Cosmos DB-t. Szoros együttműködésben az Azure csapatával többütt kezelt, több-bérlős (multi-tenant) konténermegoldásra jutottunk, amely nagy, globális olvasási teljesítményt biztosít.

Kezdetek: konténerek és partitiók

Rövid háttér az Azure Cosmos DB-ről, amely meghatározza döntéseinket:

  • Egy Azure Cosmos DB fiók konténereket és replikációs politikát definiál.
  • Minden konténert egy megadott throughputra (request units per second, RU/s) provisionálnak.
  • Az adatok logikai partitiókulcsok szerint osztódnak; vannak dokumentált korlátok tárhelyre és throughputra logikai partitiónként.
  • A logikai partitiók fizikailag kevesebb fizikai partícióra vannak képezve; ha tárolat vagy throughput igény emelkedik, a fizikai partíciók felhasadásra kerülnek.

Kezdetben egyetlen alapértelmezett konténert használtunk minden kliens terheléséhez, és kliensoldalról hagytuk meg a logikai partitiókulcs kiválasztását. Ez rövid távon működött, de többszörös problémát okozott:

  • Gyakori ütközések adódtak közismert partitiókulcsoknál (pl. user_id, workspace_id), különböző termékesetek között. Emiatt ugyanazokra a logikai kulcsokra vonatkozó Azure Cosmos DB-korlátok összesítették a terhelést, korlátozva egy adott felhasználó throughputját.
  • A fizikailag érvényesített korlátok miatt a logikai partitiók valójában nem érték el az elméleti 10k RU/s limitet: minden logikai partitió megosztotta a fizikai partíción elérhető kapacitást más logikai partitiókkal. Ebből zajos-szomszéd (noisy neighbor) hatás és szolgáltatásokat érintő széles körű leállások születhettek.
  • Ahogy az adatmennyiség nőtt, a fizikai partitiók felhasadása a partíciók számát növelte, miközben a teljes provisionált throughput változatlan maradt, így a hatékony partíciós kapacitás csökkent. Különösen objekt-szerű, nagy tárhelyigényű (blob-like) használati eseteknél a tárhely növekedése önmagában rontotta az aktív munkaterhelések rendelkezésre álló throughputját.

Váltás elkülönített konténerekre és annak következményei

A partitiókulcs-korlátok és a zajos-szomszéd problémák részleges megoldásaként elkülönített konténereket kezdtünk használni a legkritikusabb új use case-eknél. Ez minden konténerhez független fizikai partíciók kiosztását tette lehetővé, így a terhelések izoláltabbá váltak. Egyirányban ez csökkentette a site-wide hatást, de hátrányként megnövekedett az egyedi konténerek provisioning költsége és kapacitástervezési felelőssége.

Gyorsan kialakultak gyakorlati problémák:

  • A legacy kritikus use case-ek sokáig az alapértelmezett megosztott konténerben maradtak migráció hiányában, így az alap konténerre nehezedő nyomás nőtt és többször termelési incidentekhez vezetett.
  • Az elkülönített konténerek esetén a csapatoknak előre kellett provisionálniuk a várt throughputot. Előfordult, hogy termékcsapatok elfelejtették előskálázni a konténereket és az indítási napok SEV-ügyeletekbe (súlyos incidensek) torkolltak.
  • Az izoláció elveszítette azt a „kevert munkaterheleti” előnyt, amely a multi-tenancy-val stabil, aggregált növekedést eredményezhet, és amely helyettesíti a precíz kapacitástervezést.

A dedikált konténerek működtek rövid távon és megakadályoztak site-wide kieséseket, de szervezeti skálán a konténerenkénti kapacitástervezés nem volt hosszú távon fenntartható.

Visszatérés a több-bérlős megoldáshoz és Azure együttműködés

Ahogy az operációs nehézségek nőtek, visszafordultunk a multi-tenant megközelítés felé, ezúttal szoros együttműködéssel az Azure csapatával. Az együttműködés eredményei és technikai változtatások:

  • A legforróbb kulcsok elsőként történő korlátozása (throttling) csökkenti a zajos-szomszéd hatást: ha egy kulcs túl sok erőforrást fogyaszt, azt először korlátozzuk, így nem vonja el az egész fizikai partíció kapacitását.
  • Kérések prioritási sávokra (request tiering / QoS) helyezése: az offline, háttérfeladatok (bulk insert, data extract) alacsonyabb prioritást kapnak és előbb lesznek korlátozva, így nem veszik el az interaktív, felhasználói kérésekhez szükséges throughputot.
  • Egy új, az Azure Cosmos DB csapat által fejlesztett, javított szerver nélküli (serverless) üzemmód lehetővé tette, hogy minden fizikai partíció akár 10k RU/s-ig skálázható legyen, és a partíciós felosztás ne csak tárhely, hanem RU-használat alapján is megtörténhessen. Ez lehetővé tette, hogy abbahagyjuk a konténerek manuális monitorozását és skálázását.

E változtatásokkal vissza tudtunk állni egy megosztott konténer alapértelmezésre, jelentősen egyszerűsítve a termékcsapatok kapacitástervezését, miközben megőriztük a munkaterhelések izolációját. Azóta hónapokon át nem volt olyan provisioning vagy noisy-neighbor incidens, amely korábban gyakori volt.

Működési modell: közös tesztek, közös üzemeltetés

Nagy szervezeti skálán a „managed” szolgáltatások is kevésbé menedzselté válnak: OpenAI egyike lett a Cosmos DB legnagyobb felhasználóinak, és ez együttműködés nélkül nem tartható. Különösen két késői 2024-es incidens világított rá erre:

  • Egy regionális áramkimaradás miatt a legnagyobb Cosmos DB fiókunk primer régiójában failover történt, és kiderült, hogy a visszaállás több órát vesz igénybe a mi skálánkon — erre sem Azure, sem mi nem voltunk korábban ilyen mértékben tesztelve.
  • Későbbi visszafailover során egy gateway-hez kapcsolódó túlterhelés (connection stampede) miatt további súlyos kiesés történt: kliens oldali failover-kezelési módok összegyűjtötték a forgalmat a régió felé, még akkor is, amikor csak részleges partíciók tértek vissza.

Ezek az események közös hibagyökér-felderítést és javításokat hoztak. Azóta a Habitat és az Azure mérnöki csapatai több területen közösen dolgoznak: közös monitoring, teljes körű rétegellenőrzés, production-méretű, de non-production fiókok a teszteléshez, SDK-iterációk és közvetlen mérnöki kommunikáció csatornák (Teams, direct paging). Konkrét műszaki lépések között szerepeltek Azure Cosmos DB control-plane és gateway skálázhatóságának javítása, metaadat-caching a gateway-ben, connection pooling és magasabb connection reuse a Habitat Python folyamataiban, munkaterhelések kolokációja és kritikus/offline munkák izolálása külön VPC-ken.

Ez a kooperáció döntő volt a stabilitás eléréséhez: nagy, kritikus rendszerek esetén szükséges a tulajdonjog falainak ledöntése és az átlépő üzemeltetés.

Teljesítmény: a késleltetés csökkentése globális skálán

Habitat 2025 elejére stabilizálódott; 2026-ban a késleltetés (latency) vált elsődleges korlátnak. A compute és a storage gyakran külön régiókban helyezkedik el, ezért elkerülhetetlenek a cross-region hívások, amelyek késleltetést okoznak.

Fő optimalizációs irányaink a read teljesítményre (a kérések >90%-a olvasás):

  1. Több Azure Cosmos DB fiókot üzemeltetünk különböző régiókban az adat-lokalitás és adat-országmegtartási követelmények miatt. Néhány fiók minden 40 forgalmazott régióra replikál, mások legalább kontinensenként egy régióra.
  2. A legkésleltetés-érzékenyebb munkaterhelésekhez magas replikációs számmal rendelkező fiókokat használunk, csökkentve a compute és storage közötti RTT-t.
  3. Beépítettünk egy elosztott, lokális lookaside cache réteget: Valkey szerverek tárolják a gyakran használt objektumok másolatát közel a feldolgozó helyekhez. Az invalidációt finomabban kezeljük a TTL mellett explicit invalidációval, de a több régió okozta replikációs versenyhelyzetek miatt ennél robusztusabb megoldásra volt szükség.
  4. A cache invalidációt megvalósítjuk Azure Cosmos DB change feedjén (CDC) keresztül: a change feed fogyasztásával globális invalidációkat juttatunk el másodpercek alatt a helyi cache-ekhez, így magas hit-rátát és alacsony stalenesst érünk el.
  5. Csökkentettük a Habitat szolgálati overhead-jét: a Pythonból Rustba való átírás jelentősen javította a szerveroldali teljesítményt.

E lépések együtt 2026-ban a globális olvasási p50-latenciánkat nagyjából 120 ms-ról ~10 ms-ra csökkentették — körülbelül 12x javulás.

Change data capture (CDC) és streaming háttérmunkák

A megbízható, skálázható CDC kritikus nem csak a cache invalidációhoz, hanem más rendszerekhez is: másodlagos indexekhez, adatmozgó csatornákhoz, offline analitikához és valós idejű termékfunkciókhoz. Néhány részlet:

  • Milliók másodpercenként rögzített változás áramlik több száz Kafka topicon keresztül, több ezer konténer és milliók közti partíciók adataiból.
  • A belső kontroll-plane folyamatosan biztosítja, hogy minden szükséges konténert capture-eljünk, kiválasztja, mely Cosmos régiókból olvassunk, és hatékonyan osztja el a munkát ezrek között több régióban.
  • Használunk replica régiókat és alacsonyabb prioritású feed-olvasásokat, hogy a latency-szenzitív Habitat forgalmat megvédjük a háttér capture munkáktól.
  • Robusztussági munkák: worker lifecycle és lease kezelések megerősítése, stream-ek közötti hibaizoláció, konfigurációs rollout-okra védőgátak, dead-letter queue-k a permanens delivery hibák kezelésére, régiós kiesések tolerálása alternatív olvasó régiókra való átváltással.
  • Skálánk miatt még Azure CDC SDK-ját is módosítani kellett checkpointolás hatékonyságának javítására (in-memory checkpoint batching és periódikus flush).

A cél ugyanaz marad: elrejteni a platform bonyolultságát a termékfejlesztők elől, és egy egyszerű felületet adni, ahol csak a módosításokra regisztrálnak callbackeket.

Műszaki kilátások: belső exabyte rendszer fejlesztése

Annak érdekében, hogy a következő milliárd felhasználó és a beszélgetés-alapú tárhelyek igényeit teljesíteni tudjuk, előre dolgozunk egy házon belüli exabyte-méretű online tárolórendszeren. Ez a fejlesztés:

  • Rockset által biztosított RocksDB Cloud magra épül, Raft-alapú replikációval.
  • Ugyanazt a dokumentummodellt valósítja meg, mint az Azure Cosmos DB, de disaggregált tárolást és fizikai replikációt használ, csökkentve a szükséges flash kapacitást cserébe alacsonyabb csúcs QPS-sel.

Ez a rendszer célzottan a nagy, blob-szerű Habitat adatok számára optimalizál.

Összegzés

Egy kis csapat képes volt egy gyorsan növekvő tárolóplatformot támogatni azáltal, hogy a storage API-t szándékosan szűken tartotta, skálázta a szolgáltatást, és a legsürgetőbb mérnöki kihívásokat priorizálta: először megbízhatóság, utána globális olvasási teljesítmény, végül üzemeltetési hatékonyság. A szoros együttműködés az Azure Cosmos DB csapatával és a réteges megközelítések (konténer-elválasztás, throttling, request tiering, fejlett cache+CDC, Rust átírás) lehetővé tették, hogy Habitat ma több száz petabájtnyi adatot szolgáljon ki nagy megbízhatósággal és alacsony késleltetéssel.

Ha érdekelnek ezek a határskálású adat-infrastruktúra kihívások, az OpenAI-nál nyitott pozíciókat hirdetünk.