Brzo skaliranje mrežne pohrane za više od milijardu korisnika ChatGPT‑ja (II. dio)
Kako smo optimizirali Azure Cosmos DB u Habitatu, našoj platformi za pohranu aplikacijskih podataka, da bismo podržali dosad nezabilježen rast.
Svi proizvodi tvrtke OpenAI zahtijevaju brz i pouzdan pristup podacima, koji osigurava naša platforma za pohranu Habitat. Ona mora odgovarati u milisekundama za više od milijardu korisnika u 40 geografskih regija. Naša se infrastruktura suočila s iznimnim izazovom: podržati nagli rast i nove slučajeve upotrebe, a istodobno nastaviti poboljšavati pouzdanost, performanse i brzinu rada razvojnih inženjera proizvoda. Rješavanje tog izazova zahtijevalo je preispitivanje dizajna i načina upravljanja našom platformom za mrežnu pohranu. Neprestano smo odvagivali kompromise slijedeći ovaj redoslijed: najprije postići dovoljnu pouzdanost za kritičan promet proizvoda, zatim dovoljnu brzinu za korisnike diljem svijeta i na kraju vješto upravljati sustavom golemih razmjera.
Ovaj dvodijelni serijal objašnjava kako smo Habitat razvili od jednostavne klijentske biblioteke i baze podataka u globalno distribuiranu platformu za pohranu koja omogućuje pristup više od 500 petabajta podataka. I. dio bavio se razvojem Habitata od klijenta u Pythonu do servisa. Obuhvatio je i tehnike koje su nam omogućile da servis temeljen na Pythonu razvijemo daleko izvan granica koje bi mnogi smatrali praktičnima.
U ovoj objavi, II. dijelu, opisujemo kako smo skalirali temeljnu komponentu za pohranu: Azure Cosmos DB. Bliskom suradnjom s timom Azurea došli smo do održivog pristupa s više zakupnika i zajedničkim upravljanjem spremnicima, uz izvrsne performanse čitanja pri golemoj količini podataka na globalnoj razini.
Slika 01 · Što je Habitat?
Platforma za online pohranu
Habitat je platforma za online pohranu koju smo izgradili kako bi OpenAI-jevi proizvodi brzo i pouzdano pristupali potrebnim informacijama.
- Zahtjev
- Odgovor
- Promjene (CDC)
Kako tvrtke rastu, infrastrukturni timovi često prelaze s upravljanja sustavima s jednim zakupnikom na sustave s više zakupnika. U sustavima s jednim zakupnikom svaki tim zadužen za dio proizvoda održava vlastiti sustav. Time se smanjuje opseg posljedica kvarova, jasno razgraničavaju odgovornosti i izoliraju radna opterećenja. Kako rastu timovi i dijelovi proizvoda, takav rad postaje skup. Pristup s jednim zakupnikom čini svaki produktni tim odgovornim za planiranje kapaciteta i često dovodi do dodjele znatno više resursa nego što je potrebno.
Nasuprot tome, pristup s više zakupnika prepušta upravljanje središnjem timu za baze podataka, koji ima više znanja i iskustva u dodjeli resursa. No pristup s više zakupnika donosi vlastite probleme, poput bučnih susjeda: jedan zakupnik troši neuobičajeno velik udio resursa na štetu ostalih.
U Habitatu smo morali odvagnuti sve te kompromise kako bismo osmislili pouzdan i učinkovit sustav pohrane velikih razmjera. Danas je Habitat sloj baze podataka s više zakupnika za mnoge proizvode tvrtke OpenAI. No prošli smo puni krug: od jednog spremnika sustava Azure Cosmos DB s više zakupnika, preko dodjele zasebnih pozadinskih spremnika za pojedine zakupnike, do povratka na spremnik s više zakupnika kao zadano rješenje. Još smo na samom početku razvoja podrške za više zakupnika u Habitatu. Podržavamo velik broj slučajeva upotrebe, ali ulaganja u to područje uspjeli smo odgoditi koristeći se ugrađenim osnovnim mehanizmima sustava Azure Cosmos DB gdje god je to moguće.
Prije nego što opišemo svoj put sa sustavom Azure Cosmos DB, evo nekoliko osnovnih informacija:
Račun za Azure Cosmos DB definira skup spremnika i pravilo replikacije
Svakom spremniku dodjeljuje se određena propusnost izražena u jedinicama zahtjeva u sekundi (RU/s)
Podaci unutar svakog spremnika pohranjuju se uobičajenim raspodjeljivanjem prema zadanom ključu logičke particije, uz dokumentirana ograničenja pohrane i propusnosti po ključu logičke particije
Azure Cosmos DB raspoređuje ključeve logičkih particija na manji broj pozadinskih fizičkih particija. Njih dijeli na više fizičkih particija kada količina pohranjenih podataka prijeđe prag ili kada spremnik treba više fizičkih particija za održavanje dodijeljene propusnosti
U početku smo propuštali sve klijentsko opterećenje, oslanjajući se na navedeno ograničenje od 10 tis. RU/s po ključu logičke particije da uspori klijente pri preopterećenju. Na početku smo također upotrebljavali samo jedan zadani spremnik sustava Azure Cosmos DB na svakom računu. To je funkcioniralo dovoljno dobro, ali pokazalo se problematičnim iz nekoliko razloga:
Zbog ranih odluka pri oblikovanju API-ja klijentima smo izravno omogućili odabir ključa logičke particije. Zato često dolazi do kolizija često korištenih ključeva particija, kao što su user_id ili workspace_id, između različitih slučajeva upotrebe proizvoda. Budući da su ti slučajevi upotrebe dijelili ograničenja sustava Azure Cosmos DB na istim ključevima logičkih particija, takav je dizajn ograničavao ukupnu propusnost za pojedinog korisnika.
Prije prelaska na Habitat i Azure Cosmos DB čest problem pri skaliranju Postgresa bio je to što je velik broj zahtjeva vrlo aktivne organizacije ili za vrlo tražen ključ mogao srušiti cijelu bazu podataka. Riječ je o jednom zakupniku koji stvara nerazmjerno veliko opterećenje. Uložili smo znatan zajednički trud u predmemoriranje tih ključeva i uvođenje mehanizma zakupa pri promašajima predmemorije kako opterećenje nastalo tim promašajima ne bi preopteretilo pozadinsku bazu podataka.
Figure 02a · Logical partition key limits
Different clients, the same partition key
Iako se dokumentirana ograničenja veličine podataka i propusnosti odnose na ključeve logičkih particija, ograničenja se zapravo provode na fizičkoj particiji. U praksi to znači da logičke particije ne mogu dosegnuti 10.000 RU/s. Umjesto toga, ograničenja fizičke particije dijele sa svim ostalim ključevima logičkih particija smještenima na istoj fizičkoj particiji.
Zbog toga su bučni susjedi mogli utjecati na mnoge nepovezane ključeve logičkih particija: radna opterećenja koja su obrađivala podatke za specijalizirane značajke proizvoda ometala su osnovne postupke prijave i registracije.
Figure 02b · Noisy neighbors
Different users, the same physical partition
Ograničenje propusnosti pojedine fizičke particije također je promjenjivo i ovisi o ukupnoj propusnosti dodijeljenoj spremniku sustava Azure Cosmos DB. Dodijeljena propusnost spremnika raspoređuje se približno ravnomjerno među njegovim fizičkim particijama.
Kako količina podataka raste, fizičke se particije dijele, čime se povećava njihov ukupan broj, dok ukupna dodijeljena propusnost ostaje nepromijenjena. Zato se efektivno ograničenje propusnosti po particiji smanjuje kako količina podataka raste.
U slučajevima upotrebe s najvećim zahtjevima za pohranu, nalik pohrani BLOB-ova, to stvara problem: sam rast količine pohranjenih podataka smanjuje propusnost dostupnu aktivnim radnim opterećenjima, čak i kada učestalost zahtjeva i upotreba ostaju stabilne.
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.
Odvojeni spremnici djelomično rješavaju ova ograničenja ključeva particija i problem bučnih susjeda. Svakom odvojenom spremniku mogu se dodijeliti vlastite neovisne fizičke particije, pa samo različita radna opterećenja unutar tog spremnika mogu biti bučni susjedi ili se preklapati u prostoru ključeva particija. S druge strane, dodjela novih spremnika iziskuje dodatni rad jer svaki zahtijeva zasebno planiranje kapaciteta. Zato spremnike želimo stvarati samo ondje gdje ima smisla razdvojiti servise ili slučajeve upotrebe.
Počeli smo upotrebljavati zasebne spremnike sustava Azure Cosmos DB za ključne nove slučajeve upotrebe koji zahtijevaju snažnu izolaciju. Uz skriptu za upravljanje slabim particijama, koja je ukupnu dodijeljenu propusnost svakog spremnika usklađivala s brojem njegovih fizičkih particija, uglavnom smo izbjegli sve dotadašnje probleme.
Budući da smo počeli sa zadanim spremnikom, mnogi stariji ključni slučajevi upotrebe nažalost su ostali vezani uz njega dok se ne provede migracija podataka. Kako bismo zaštitili kritične servise koji su se još oslanjali na podatke u zajedničkom zadanom spremniku, timovima smo često savjetovali da za nove servise ili veće značajke proizvoda stvore zasebne spremnike. S rastom sustava raslo je opterećenje zadanog spremnika, a s njim i broj incidenata u produkciji. Počeli smo dodjeljivati spremnike svakom novom servisu ili velikoj značajci proizvoda samo kako bismo zadani spremnik zaštitili od dodatnog opterećenja.
Time smo izbjegli mnoge prekide rada cijele platforme, ograničivši posljedice na smetnje u radu pojedine značajke ili servisa. No dodatni rad potreban za dodjelu novih spremnika s vremenom je postao problem:
U starom zajedničkom zadanom spremniku rast pojedinog novog slučaja upotrebe s 0 QPS na milijun QPS vjerojatno ne bi znatno promijenio ukupnu upotrebu. No u izoliranom spremniku rast novog slučaja upotrebe s 0 na milijun QPS mogao je značiti 1000 puta veće opterećenje od početnog, koje je potjecalo samo od internog testiranja proizvoda.
Uz namjenske spremnike timovi su sada morali unaprijed osigurati očekivanu propusnost spremnika za puštanje proizvoda u rad. Produktni timovi često bi pustili značajke u produkciju i zaboravili unaprijed povećati kapacitet. Na dan lansiranja zato bismo sjedili na sastancima za rješavanje ozbiljnih incidenata i u posljednji trenutak pokušavali povećati kapacitet spremnika.
Takvom strategijom spremnika, radi bolje izolacije, gubimo jednu od ključnih prednosti sustava s više zakupnika: kombiniranje različitih radnih opterećenja.
Figure 03 · Lack of stable aggregate growth
The same workload, different headroom
1K RU/s during load testing → 1M RU/s at launch
S vremenom je praćenje upotrebe namjenskih spremnika zahtijevalo i detaljno poznavanje proizvoda kako bi se znalo kada će se promet promijeniti ili povećati.
Možemo ponuditi osnovnu skriptu upravljačke ravnine koja povećava dodijeljenu propusnost svakog spremnika prema trendovima rasta. No bez stabilnog ukupnog rasta njihovo pravilno skaliranje značilo je uključivanje gotovo svakog produktnog tima u tvrtki OpenAI u planiranje kapaciteta.
Taj pristup nije bio organizacijski održiv pri rastu jer se razina pažnje koju su timovi odgovorni za pojedine servise posvećivali dodjeli resursa u sustavu Azure Cosmos DB znatno razlikovala.
Kako je organizacija rasla, te je operativne probleme bilo sve teže rješavati. Bez jednog središnjeg tima zaduženog za planiranje, mnogi su timovi loše planirali. Zato smo se na kraju vratili rješenju s više zakupnika i u bliskoj suradnji s timom Azurea osmislili rješenja za izvorne probleme dijeljenja resursa:
Ograničavanjem zahtjeva prvo za najtraženije ključeve sprječava se da bučni susjedi potroše svu dostupnu propusnost pojedine fizičke particije. Time se smanjuje učinak bučnih susjeda, pri kojem jedan vrlo tražen ključ može utjecati na cijelu platformu.
QoS s razvrstavanjem zahtjeva po razinama na sličan način sprječava izvanmrežna radna opterećenja, poput masovnog umetanja ili izdvajanja podataka, da iskoriste svu propusnost pojedine fizičke particije. Zahtjevima tih radnih opterećenja dodjeljuje se niži prioritet pa se oni prvi ograničavaju. Tako se izbjegava ograničavanje interaktivnih zahtjeva višeg prioriteta koji služe krajnjim korisnicima.
Azure Cosmos DB već je imao način rada bez poslužitelja koji bi riješio naš problem slabih particija u načinu rada s unaprijed dodijeljenim resursima. No imao je velik nedostatak: skalirao se samo prema količini pohranjenih podataka i ograničavao potrošnju RU-a na 5 tis. RU/s po fizičkoj particiji. To bi riješilo problem slabih particija, ali bi nas spriječilo da skaliramo slučajeve upotrebe s velikom potrošnjom RU-a.
Tim za Azure Cosmos DB za nas je izradio novi, poboljšani način rada bez poslužitelja. Omogućio je skaliranje svake fizičke particije do 10 tis. RU/s te, uz podjelu prema količini pohranjenih podataka, uveo podjelu prema potrošnji RU-a. Zahvaljujući tome više nismo morali ručno pratiti i povećavati kapacitet spremnika.
Te su nam promjene omogućile povratak na jedan zajednički spremnik, čime je produktnim timovima znatno olakšano početno i kontinuirano planiranje kapaciteta, uz očuvanu izolaciju radnih opterećenja. U mjesecima nakon toga nismo imali nijedan incident povezan s dodjelom resursa ili bučnim susjedima, unatoč ubrzanom razvoju proizvoda.
Kada tvrtke dosegnu veličinu tvrtke OpenAI, upravljane usluge postaju manje „upravljane”. Mnoga radna opterećenja počinju odudarati od uobičajenih u infrastrukturi pružatelja usluga u oblaku. Kako je OpenAI postajao jedan od najvećih korisnika sustava Azure Cosmos DB, uspješan rad zahtijevao je drukčiji pristup: zajedničke testove i nadzorne ploče, izravne kanale između inženjera te zajedničku odgovornost za kvarove koji se pojavljuju samo pri našim razmjerima. Danas naš najveći račun za Azure Cosmos DB pohranjuje desetke petabajta podataka i obrađuje više od 20 milijuna QPS. Koliko znamo, jedina smo tvrtka koja je implementirala Azure Cosmos DB u tim razmjerima.
Krajem 2024. regionalni prekid rada jasno je pokazao zašto je ta suradnja nužna. Tada je nestanak struje pogodio primarnu regiju Azurea za jedan od naših najvećih računa za Azure Cosmos DB. Tijekom prebacivanja na rezervnu regiju shvatili smo da bi našim najvećim računima za prelazak u sekundarnu regiju trebalo nekoliko sati. Ni naš tim ni tim za Azure Cosmos DB to nisu testirali pri našim razmjerima.
Otprilike mjesec dana poslije, pri vraćanju tih računa u izvornu regiju, izazvali smo još jedan ozbiljan prekid rada. Navala veza prema izvornoj regiji preopteretila je tamošnji pristupnik sustava Azure Cosmos DB. Zbog specifičnog načina na koji je klijent za Azure Cosmos DB u načinu rada s pristupnikom obrađivao prebacivanja, svi su klijenti odmah uspostavili veze i poslali zahtjeve u izvornu regiju, iako se u nju vratio samo dio fizičkih particija.
Pri svakom prekidu rada i OpenAI i Azure proveli su svoje postupke upravljanja incidentima, utvrdili više temeljnih uzroka i primijenili popravke. No ti su prekidi bili simptomi šireg sustavnog problema u načinu na koji su naš tim i tim za Azure Cosmos DB radili i testirali. U početku nam je upotreba upravljanih usluga omogućila brz napredak i usredotočenost na poslovne ciljeve. Pri velikim razmjerima upravljane usluge postaju manje upravljane i zahtijevaju duboku povezanost s pružateljem usluge na svim razinama, od dizajna do operativnog rada.
Danas inženjerski timovi Habitata i Azurea zajednički nadziru svaki sloj Habitata, od naših servisnih slojeva do fizičkih slojeva pohrane sustava Azure Cosmos DB. Radimo i testiramo promjene na neprodukcijskom računu za Azure Cosmos DB koji je veličinom jednak produkcijskom. Zajedno testiramo i poboljšavamo SDK-ove te utvrđujemo najbolje prakse za skaliranje i dimenzioniranje naših računa za Azure Cosmos DB. Naši inženjeri mogu izravno komunicirati putem Teamsa, a omogućili smo i izravno pozivanje dežurnih kolega bez prolaska kroz razine podrške.
Tijekom protekle godine uložili smo znatan zajednički trud u poboljšanje skalabilnosti upravljačke ravnine i pristupnika sustava Azure Cosmos DB. Dodali smo zaštitu od preopterećenja i predmemoriranje raznih metapodataka sustava Azure Cosmos DB u pristupniku radi zaštite particije s metapodacima. Smanjili smo opterećenje koje stvara naša flota procesa habitat-service u Pythonu udruživanjem veza i njihovom češćom ponovnom upotrebom, smještali radna opterećenja na iste lokacije gdje je to bilo moguće te odvojili kritična radna opterećenja od izvanmrežnih upotrebom različitih VPC-ova.
Takva razina zajedničkog inženjerskog rada bila je ključna za stabilnost našeg sustava Azure Cosmos DB tijekom protekle godine. Svaki dovoljno velik ili kritičan sustav zahtijeva ovakav timski rad: uklanjanje prepreka između područja odgovornosti i suradnju preko organizacijskih granica.
Kao što smo spomenuli u I. dijelu, naša je temeljna filozofija: najprije neka radi, zatim neka bude brzo, a na kraju jeftino. Prvo pouzdanost, zatim performanse, pa učinkovitost. Habitat je postao kritična infrastruktura za OpenAI, pa je prvi prioritet bio osigurati njegovu pouzdanost. Kako se sustav stabilizirao tijekom 2025. godine, a OpenAI širio globalno, latencija je postala sljedeće ograničenje za korisnike i produktne timove.
Računalni i pohrambeni kapaciteti često su bili smješteni u različitim regijama, pa su međuregionalni zahtjevi bili neizbježni.
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.
Geografske lokacije računalnih resursa i pohrane služe samo za ilustraciju.
Latencija je znatno varirala ovisno o tome gdje su podaci pohranjeni i gdje se zahtjev obrađuje. Kako bi zahtjevi prema Habitatu bili brzi, razvojni inženjeri proizvoda oslanjali su se na dodatno predmemoriranje na strani klijenta, grupiranje zahtjeva, smanjivanje broja čitanja i pisanja u bazu te premještanje rada izvan kritičnog puta gdje god je to bilo moguće. Iako je to dovelo do zanimljivih rješenja otpornijih na probleme s bazom podataka, proizvodi su postali složeniji, a razvojni ciklusi sporiji. Time nije ostvaren cilj Habitata: omogućiti brz razvoj proizvoda bez potrebe za razumijevanjem baze podataka.
To nam je jedno od glavnih područja rada u 2026. Razvili smo višeslojnu strategiju optimizacije performansi čitanja, na koje otpada više od 90 % zahtjeva prema Habitatu:
Imamo niz računa za Azure Cosmos DB u različitim regijama Azurea diljem svijeta za korisnike sa zahtjevima za rezidentnost podataka. Čak i korisnicima bez strogih zahtjeva za rezidentnost podataka smještanje podataka u njihovoj blizini poboljšava iskustvo zahvaljujući manjoj latenciji.
U praksi to ne možemo šire primijeniti izvan slučajeva koji zahtijevaju rezidentnost podataka jer smještaj ograničava fizički kapacitet oblaka. Zbog veličine naših skupova podataka mnoge regije nemaju dovoljno prostora za golemu količinu podataka potrebnu za njihov razmjerni udio korisničkog prometa.
U regijama s ograničenim kapacitetima podatkovnih centara, napajanja ili hlađenja ponekad moramo izravno birati: rezervirati kapacitet za lokalnu pohranu i nižu latenciju Habitata ili ga iskoristiti za dodatne računalne resurse za obradu zahtjeva, a zahtjeve za pohranu usmjeriti dalje.
Odluke o smještaju stoga često zahtijevaju kompromis između: A) optimizacije latencije za različite proizvode i skupine korisnika te B) raspoloživih pohrambenih i računalnih kapaciteta.
Za radna opterećenja kojima je latencija najvažnija, poput autentifikacijskih metapodataka potrebnih pri svakom zahtjevu, smanjujemo RTT između računalnih resursa i Habitata upotrebom računa za Azure Cosmos DB s velikim brojem replika u mnogim sekundarnim regijama. Neki računi repliciraju podatke u svih 40 regija Azurea u kojima obrađujemo promet, a drugi u barem jednu regiju na svakom kontinentu.
Morali smo ranije nego što smo željeli u Habitat ugraditi transparentan sloj za premještanje podataka i usmjeravanje kako bismo mogli premještati skupove podataka između računa s različitim topologijama replikacije.
No i ovaj pristup u konačnici ograničava kapacitet, pa ga primjenjujemo samo na nekoliko pažljivo odabranih skupova podataka.
U radnim opterećenjima Habitata izrazito prevladava čitanje: aplikacije neprestano dohvaćaju postavke, stanje i druga svojstva. Nerazmjerno velik dio prometa otpada na relativno malen radni skup često korištenih tipova podataka. Zbog toga je sustav posebno prikladan za distribuirano predmemoriranje. Predmemoriranje poboljšava performanse infrastrukture u jednoj regiji, ali su poboljšanja još veća pri radu u više regija jer može „sakriti” međuregionalnu latenciju.
U Habitat smo integrirali distribuirani sloj predmemorije koji se provjerava prije pristupa bazi podataka. On pohranjuje kopije nedavno korištenih objekata i bridova na poslužiteljima Valkey smještenima u našoj infrastrukturi blizu mjesta obrade korisničkih zahtjeva. Takve predmemorije obično upotrebljavaju vrijeme valjanosti (TTL), kojim se postiže kompromis između stope pogodaka i zastarjelosti podataka. Kratak TTL smanjuje zastarjelost, ali i pozitivan učinak predmemoriranja jer stavke brzo istječu iz predmemorije i moraju se češće dohvaćati. Dulji TTL poboljšava stopu pogodaka, ali dulje poslužuje zastarjele podatke, što vodi lošem korisničkom iskustvu i nepredvidivom ponašanju proizvoda.
Drugi je pristup izričito poništavanje valjanosti predmemorije kada aplikacija zapisuje promjene u iste temeljne podatke. To znatno poboljšava ažurnost predmemoriranih podataka, ali može biti teško pravilno implementirati. I dalje ostaje niz rubnih slučajeva, poput djelomičnih kvarova, zbog kojih predmemorija može ostati zastarjela. Implementacije u više regija dodatno otežavaju te probleme zbog manje pouzdanih međuregionalnih mreža i utrke između predmemorije i replikacije pozadinske pohrane. Dodavanje TTL-a ograničava najdulje trajanje zastarjelosti, ali i dalje donosi isti kompromis povezan s TTL-om koji smo već opisali.
Primijenili smo napredniji pristup poništavanju valjanosti, slijedeći primjer sustava poput Metina TAO-a. Integrirana predmemorija Habitata oslanja se na bilježenje promjena podataka (CDC) putem toka promjena sustava Azure Cosmos DB kako bi unutar nekoliko sekundi globalno proširila poništavanja valjanosti. Time postiže visoku stopu pogodaka uz malu zastarjelost. Servis u našoj infrastrukturi obrađuje taj tok promjena i poništava valjanost stavki u lokalnim predmemorijama kada se temeljni podaci ažuriraju. To pri sljedećem čitanju tih podataka uzrokuje promašaj predmemorije, nakon čega se ona popunjava najnovijom verzijom podataka.
Latenciju smo znatno smanjili i uklanjanjem dodatnog opterećenja u samom servisu Habitat: kod smo prepisali u Rustu, koji pruža bolje performanse od izvornog Pythona.
Zajedno su te promjene smanjile ukupnu globalnu latenciju čitanja p50 s približno 120 ms na približno 10 ms, što je 12-struko poboljšanje otkako smo se početkom ove godine usredotočili na performanse.
Figure 05 · Improving performance at a global scale
p50 latency for reads
Three major design changes improved read latency
Iako je predmemoriranje znatno smanjilo medijan latencije, najsporiji zahtjevi i dalje moraju dohvaćati nepredmemorirane podatke iz pozadinske pohrane, često iz udaljenih regija. Kako se novi kapaciteti budu puštali u rad i kako budemo poboljšavali učinkovitost pohrane, planiramo riješiti temeljniji izazov: od samog početka smještati podatke bliže mjestu s kojeg će im se pristupati.
Pouzdan i skalabilan CDC, odnosno prosljeđivanje promjena iz baze podataka nizvodnim sustavima, ključan je ne samo za strategiju predmemoriranja Habitata. Milijuni zabilježenih promjena u sekundi iz tisuća spremnika i milijuna njihovih particija prolaze kroz više od stotinu tema u sustavu Kafka. One također pokreću sekundarne indekse s eventualnom dosljednošću, pipelineove za premještanje podataka, izvanmrežnu analitiku i druge značajke proizvoda u stvarnom vremenu. Kako je naša pozadinska infrastruktura rasla diljem svijeta, praćenje promjena redaka postajalo je sve složenije. Želi li klijent registrirati povratni poziv koji se izvršava pri svakoj promjeni redaka njegova tipa, među ostalim mora najprije utvrditi koji računi i spremnici sustava Cosmos sadrže njegove podatke te koja implementacija servisa CDC u odgovarajućim regijama prati te spremnike. Mora i pravilno skalirati flotu radnih procesa servisa CDC, Kafku i vlastitog potrošača. Naša platforma CDC sve to nastoji sakriti od razvojnih inženjera proizvoda i ponuditi jednostavno sučelje u kojem klijenti registriraju funkciju koja će se pozivati za promijenjene retke, a mi preuzimamo svu infrastrukturu i skaliranje.
Interna upravljačka ravnina neprestano osigurava bilježenje promjena iz svih potrebnih spremnika, odabire regije sustava Cosmos iz kojih će se čitati i učinkovito raspoređuje rad među tisućama radnih procesa u više geografskih regija. Upotreba regija s replikama i čitanje toka promjena s nižim prioritetom štite promet Habitata osjetljiv na latenciju od pozadinskih radnih opterećenja za bilježenje promjena. U tako velikoj floti stalno dolazi do rušenja radnih procesa, problema sa spremnicima, pogrešaka u pohrani zakupa, nevaljanih konfiguracija i kvarova na odredištima. Povećali smo otpornost životnog ciklusa radnih procesa CDC-a i upravljanja zakupima, izolirali kvarove između tokova te ugradili zaštitne mehanizme za promjene konfiguracije i uvođenje novih verzija. Upotrebljavamo redove za neisporučive poruke kako trajne pogreške u isporuci ne bi blokirale obradu poruka iza njih. Regionalne prekide rada prevladavamo prebacivanjem procesa čitanja na druge regije sustava Cosmos. Pri našim razmjerima morali smo čak izmijeniti Azureov SDK za CDC kako bi učinkovitije bilježio kontrolne točke: grupiramo ih u memoriji i samo povremeno zapisujemo u trajnu pohranu.
Iako je interna upotreba sustava Azure Cosmos DB u Habitatu složena, njegova je glavna vrijednost oduvijek bila skrivanje infrastrukturnih detalja od razvojnih inženjera proizvoda radi bržeg razvoja. Isto vrijedi i za našu platformu CDC.
Malen tim uspio je podržati brzorastuću platformu za pohranu tako što je namjerno zadržao uzak opseg API-ja za pohranu, nastavio skalirati servis u Pythonu i dao prednost najhitnijim inženjerskim izazovima. Najprije smo se usredotočili na pouzdanost za kritičan promet proizvoda, zatim na performanse čitanja za korisnike diljem svijeta, a na kraju na operativnu učinkovitost pri velikim razmjerima. Taj je pristup omogućio brz rast i nove slučajeve upotrebe uz poboljšanje pouzdanosti, performansi i brzine razvoja proizvoda.
Kako bismo skalirali Habitat i pohranu razgovora za sljedeću milijardu korisnika, moramo riješiti izazov replikacije podataka u našoj infrastrukturi u još većim razmjerima. Da bismo to pravodobno riješili, razvijamo vlastiti sustav mrežne pohrane eksabajtnih razmjera, optimiziran za tipove podataka Habitata koji zauzimaju mnogo prostora. Taj sustav u razvoju kombinira jezgru RocksDB Cloud iz Rockseta s replikacijom temeljenom na Raftu. Implementira isti dokumentni model kao Azure Cosmos DB, ali upotrebljava razdvojenu pohranu i fizičku replikaciju kako bi smanjio potreban kapacitet flash memorije, uz niži vršni QPS.
Ako vas zanima rad na ovakvim projektima podatkovne infrastrukture koji pomiču granice, pogledajte naša otvorena radna mjesta.


