Verkkotallennuksen nopea skaalaus yli miljardille ChatGPT‑käyttäjälle (osa II)
Näin optimoimme Azure Cosmos DB:n Habitat-sovellustallennusalustassamme vastaamaan ennennäkemättömään kasvuun.
Kaikki OpenAI:n tuotteet tarvitsevat nopean ja luotettavan pääsyn tietoihin. Sen tarjoaa Habitat-tallennusalustamme. Sen on vastattava millisekunneissa yli miljardille käyttäjälle 40 maantieteellisellä alueella. Infrastruktuurimme kohtasi poikkeuksellisen haasteen: sen piti tukea räjähdysmäistä kasvua ja uusia käyttötapauksia sekä samalla parantaa luotettavuutta, suorituskykyä ja tuotekehittäjien työskentelynopeutta. Haasteen ratkaiseminen vaati verkkopalvelujen tallennusalustamme suunnittelun ja käytön uudelleenarviointia. Arvioimme jatkuvasti kompromisseja seuraavassa järjestyksessä: ensin riittävä luotettavuus tuotteiden kriittiselle liikenteelle, sitten riittävä nopeus maailmanlaajuiselle käyttäjäkunnalle ja lopuksi sujuva toiminta valtavassa mittakaavassa.
Tässä kaksiosaisessa sarjassa kerromme, kuinka kehitimme Habitatin yksinkertaisesta asiakaskirjastosta ja tietokannasta maailmanlaajuisesti hajautetuksi tallennusalustaksi, joka palvelee yli 500 petatavun tietomäärää. Osa I keskittyi Habitatin kehitykseen Python-asiakasohjelmasta palveluksi. Siinä käsiteltiin myös tekniikoita, joiden avulla venytimme Python-pohjaisen palvelun rajoja paljon pidemmälle kuin moni pitäisi käytännöllisenä.
Tässä sarjan toisessa osassa käymme läpi, miten skaalasimme taustalla toimivan tallennuskomponentin eli Azure Cosmos DB:n. Tiiviissä yhteistyössä Azure-tiimin kanssa löysimme toimivan monivuokrausratkaisun: yhdessä hallinnoidut kontit, jotka tarjoavat erinomaisen lukusuorituskyvyn valtavassa, maailmanlaajuisessa mittakaavassa.
Kuva 01 · Mikä Habitat on?
Verkkotallennusalusta
Habitat on rakentamamme verkkotallennusalusta, jonka avulla OpenAI-tuotteet saavat tarvitsemansa tiedot nopeasti ja luotettavasti.
- Pyyntö
- Vastaus
- Muutokset (CDC)
Yritysten kasvaessa infrastruktuuritiimit siirtyvät usein yhden vuokralaisen järjestelmistä monivuokrajärjestelmiin. Yksivuokrauksessa jokaisesta tuotealueesta vastaava tiimi ylläpitää omaa järjestelmäänsä. Tämä rajaa häiriöiden vaikutuksia, selkeyttää vastuualueita ja eristää työkuormat toisistaan. Tiimien ja tuotealueiden lisääntyessä tällaisen järjestelyn ylläpito kallistuu. Yksivuokraus tekee jokaisesta tuotetiimistä vastuullisen kapasiteettisuunnittelusta ja johtaa usein merkittävään resurssien ylimitoitukseen.
Monivuokrauksessa hallinta puolestaan kuuluu keskitetylle tietokantatiimille, jolla on enemmän tietoa ja kokemusta resurssien varaamisesta. Monivuokraus tuo kuitenkin omat ongelmansa, kuten häiritsevät naapurit: yksi vuokralainen kuluttaa poikkeuksellisen suuren osan resursseista muiden kustannuksella.
Habitatissa jouduimme punnitsemaan kaikkia näitä kompromisseja, jotta pystyimme suunnittelemaan luotettavan ja tehokkaan tallennusjärjestelmän suureen mittakaavaan. Nykyään Habitat on monivuokrainen tietokantakerros monille OpenAI:n tuotteille. Matkamme teki kuitenkin täyden kierroksen: yhdestä monivuokraisesta Azure Cosmos DB -kontista siirryimme vuokralaiskohtaisiin taustakontteihin ja lopulta takaisin monivuokraiseen konttiin oletusratkaisuna. Habitatin monivuokraus on meillä vielä alkutaipaleella. Tuemme lukuisia käyttötapauksia, mutta olemme voineet lykätä lisäpanostuksia tälle alueelle hyödyntämällä Azure Cosmos DB:n sisäänrakennettuja perustoimintoja aina kun mahdollista.
Ennen kuin käymme läpi Azure Cosmos DB -matkaamme, muutama perustieto:
Azure Cosmos DB -tili määrittää säilöjoukon ja replikointikäytännön
Kullekin säilölle varataan tietty suoritusteho pyyntöyksikköinä sekunnissa (RU/s)
Kunkin kontin tiedot tallennetaan tavanomaiseen tapaan osittamalla ne määritetyn loogisen osioavaimen mukaan. Tallennustilalle ja suoritusteholle on dokumentoidut rajat kutakin loogista osioavainta kohden.
Azure Cosmos DB jakaa loogiset osioavaimet pienempään määrään taustalla olevia fyysisiä osioita. Se jakaa osion useaksi fyysiseksi osioksi, kun tallennusmäärä ylittää kynnysarvon tai kun kontti tarvitsee lisää fyysisiä osioita varatun suoritustehon ylläpitämiseen.
Aluksi päästimme kaiken asiakaskuorman läpi ja luotimme siihen, että ilmoitettu loogisen osioavaimen 10 000 RU/s:n raja loisi vastapaineen. Käytimme alkuvaiheessa myös vain yhtä Azure Cosmos DB -oletussäilöä kullakin tilillä. Tämä toimi riittävän hyvin, mutta osoittautui ongelmalliseksi muutamasta syystä:
Varhaisten API-valintojen vuoksi annoimme loogisen osioavaimen valinnan suoraan asiakasohjelmien tehtäväksi. Tämän seurauksena yleisesti käytetyt osioavaimet, kuten user_id ja workspace_id, törmäävät usein toisiinsa eri tuotteiden käyttötapauksissa. Koska nämä käyttötapaukset jakoivat samojen loogisten osioavainten Azure Cosmos DB -rajat, rakenne rajoitti yksittäisen käyttäjän kokonaissuoritustehoa.
Ennen siirtymistä Habitatiin ja Azure Cosmos DB:hen kohtasimme Postgresin skaalauksessa usein saman ongelman: erittäin kuormittavan organisaation tai avaimen runsaat pyynnöt saattoivat kaataa koko tietokannan. Yksi vuokralainen siis tuotti suhteettoman suuren kuorman. Teimme paljon yhteistä työtä näiden avainten välimuistittamiseksi ja määräaikaisten varausten lisäämiseksi välimuistihutien käsittelyyn, jotta hudeista syntyvä kuorma ei ylikuormittaisi taustalla olevaa tietokantaa.
Figure 02a · Logical partition key limits
Different clients, the same partition key
Vaikka dokumentoidut tietomäärä- ja suoritustehorajat koskevat loogisia osioavaimia, rajat pannaan todellisuudessa täytäntöön fyysisen osion tasolla. Käytännössä tämä tarkoittaa, etteivät loogiset osiot yllä tasolle 10 000 RU/s. Sen sijaan ne jakavat fyysisen osion rajat kaikkien muiden samaan fyysiseen osioon sijoitettujen loogisten osioavainten kanssa.
Näin häiritsevät naapurit pääsivät vaikuttamaan moniin toisistaan riippumattomiin loogisiin osioavaimiin: kapean käyttäjäryhmän tuoteominaisuuksien tietoja käsittelevät työkuormat häiritsivät kirjautumisen ja rekisteröitymisen kaltaisia ydintoimintoja.
Figure 02b · Noisy neighbors
Different users, the same physical partition
Myös yksittäisen fyysisen osion suoritustehoraja vaihtelee Azure Cosmos DB -kontille varatun kokonaissuoritustehon mukaan. Kontille varattu suoritusteho jaetaan suunnilleen tasan sen fyysisten osioiden kesken.
Tietomäärän kasvaessa fyysiset osiot jakautuvat. Osioiden kokonaismäärä kasvaa, mutta varattu kokonaissuoritusteho pysyy ennallaan. Tämän seurauksena osiokohtainen todellinen suoritustehoraja pienenee tietomäärän kasvaessa.
Eniten tallennustilaa vaativissa, blob-tyyppisissä käyttötapauksissamme tämä aiheuttaa ongelmatilanteen, jossa pelkkä tallennusmäärän kasvu pienentää aktiivisten työkuormien käytettävissä olevaa suoritustehoa, vaikka pyyntömäärät ja käyttö pysyvät vakaina.
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.
Erilliset kontit auttavat ratkaisemaan osan näistä osioavainrajoista ja häiritsevien naapurien ongelmista. Kullekin erilliselle kontille voidaan osoittaa omat itsenäiset fyysiset osionsa. Tällöin vain saman kontin työkuormat voivat häiritä toisiaan tai käyttää päällekkäisiä osioavaimia. Uusien konttien käyttöönotosta syntyy kuitenkin lisätyötä: jokainen kontti vaatii oman kapasiteettisuunnittelunsa. Siksi haluamme luoda kontteja vain palvelujen tai käyttötapausten luonteville rajoille.
Aloimme käyttää erillisiä Azure Cosmos DB -kontteja kaikkein kriittisimpiin uusiin käyttötapauksiin, jotka edellyttivät vahvaa eristystä. Lisäksi otimme heikkojen osioiden hallintaan komentosarjan, joka sovitti kunkin kontin varatun kokonaissuoritustehon sen fyysisten osioiden määrään. Yhdessä nämä keinot ratkaisivat pääosin kaikki kohtaamamme ongelmat.
Koska olimme kuitenkin aloittaneet oletuskontilla, monet vanhat kriittiset käyttötapaukset jäivät valitettavasti siihen, ellei tietoja siirretty erikseen. Suojataksemme jaetun oletuskontin tiedoista yhä riippuvaisia kriittisiä palveluja neuvoimme tiimejä usein luomaan erilliset kontit uusille palveluille tai merkittäville tuoteominaisuuksille. Toimintamme kasvaessa oletuskontin kuormitus lisääntyi, samoin tuotantohäiriöiden määrä. Aloimme luoda oman kontin jokaiselle uudelle palvelulle tai suurelle tuoteominaisuudelle vain suojataksemme oletuskonttia lisäkuormalta.
Näin vältimme monet koko sivuston käyttökatkot ja rajasimme vaikutukset yksittäisten ominaisuuksien tai palvelujen toimintahäiriöihin. Lopulta uusien konttien käyttöönoton lisätyö kuitenkin alkoi näkyä:
Vanhassa jaetussa oletuskontissa yksittäisen uuden käyttötapauksen kasvu nollasta miljoonaan kyselyyn sekunnissa (QPS) ei todennäköisesti muuttanut kokonaiskäyttöä merkittävästi. Eristetyssä kontissa sama kasvu nollasta miljoonaan QPS:ään saattoi kuitenkin tarkoittaa 1 000-kertaista kuormaa pelkästä sisäisestä koekäytöstä syntyneeseen lähtötasoon nähden.
Erilliskontteja käyttävien tiimien piti nyt muistaa varata konteilleen etukäteen julkaisussa odotettu suoritusteho. Tuotetiimit julkaisivat usein ominaisuutensa tuotantoon mutta unohtivat skaalata kapasiteetin ennakkoon. Niinpä istuimme julkaisupäivänä vakavien häiriöiden tilannehuoneissa yrittämässä kasvattaa kontteja viime hetkellä.
Työkuormien yhdistäminen on monivuokrajärjestelmien keskeinen etu, jonka menetämme tässä konttistrategiassa paremman eristyksen vastineeksi.
Figure 03 · Lack of stable aggregate growth
The same workload, different headroom
1K RU/s during load testing → 1M RU/s at launch
Ajan myötä myös erilliskonttien käytön seuranta vaati syvällistä tuotetuntemusta siitä, milloin liikenne muuttuisi tai kasvaisi.
Voimme tarjota yksinkertaisen hallintatason komentosarjan, joka kasvattaa kullekin kontille varattua suoritustehoa kasvutrendien mukaan. Ilman tasaista kokonaiskasvua oikea skaalaus kuitenkin edellytti käytännössä jokaisen OpenAI:n tuotetiimin osallistumista kapasiteettisuunnitteluun.
Tämä ei skaalautunut organisaation tasolla, sillä palveluista vastaavat tiimit huolehtivat Azure Cosmos DB -resurssiensa varaamisesta hyvin vaihtelevalla tarkkuudella.
Organisaation kasvaessa näiden operatiivisten ongelmien hallinta vaikeutui. Kun suunnittelusta ei vastannut yksi keskitetty tiimi, moni tiimi suunnitteli puutteellisesti. Päädyimme siksi siirtymään takaisin monivuokraratkaisuun. Teimme tiivistä yhteistyötä Azure-tiimin kanssa korjataksemme alkuperäiset monivuokrausongelmamme jaettuun käyttöön perustuvalla rakenteella:
Rajoittamalla ensin kuormittavimpia avaimia estämme häiritseviä naapureita kuluttamasta kaikkea fyysisen osion käytettävissä olevaa suoritustehoa. Näin pienennämme vaikutuksia, joita yksittäinen kuormittava avain voi aiheuttaa koko sivustolle.
Myös pyyntöjen luokitteluun perustuva QoS estää eräajokuormia, kuten massalisäyksiä tai tietopoimintoja, käyttämästä fyysisen osion koko suoritustehoa. Annamme näiden työkuormien pyynnöille alemman prioriteetin, jolloin niitä rajoitetaan ensin. Näin loppukäyttäjiä palvelevia korkeamman prioriteetin vuorovaikutteisia pyyntöjä ei tarvitse rajoittaa.
Azure Cosmos DB:ssä oli jo palvelimeton tila, joka olisi ratkaissut varatun kapasiteetin tilassa ilmenneen heikkojen osioiden ongelman. Siinä oli kuitenkin merkittävä haitta: se skaalautui vain tallennustilan käytön mukaan ja rajoitti RU-käytön tasolle 5 000 RU/s fyysistä osiota kohden. Tämä olisi ratkaissut heikkojen osioiden ongelman mutta estänyt meitä skaalaamasta paljon pyyntöyksiköitä kuluttavia käyttötapauksia.
Azure Cosmos DB -tiimi rakensi meille parannetun palvelimettoman tilan, jossa jokainen fyysinen osio pystyi skaalautumaan tasolle 10 000 RU/s. Se toi tallennustilan käyttöön perustuvan jakamisen rinnalle RU-käyttöön perustuvan jakamisen. Näin saatoimme lopettaa konttien manuaalisen seurannan ja skaalauksen.
Näiden muutosten ansiosta olemme voineet palata yhteen jaettuun konttiin. Se on huomattavasti keventänyt tuotetiimien ennakoivaa ja jatkuvaa kapasiteettisuunnittelua ja samalla säilyttänyt työkuormien eristyksen. Sen jälkeisinä kuukausina meillä ei ole ollut yhtään kapasiteetin varaamiseen tai häiritseviin naapureihin liittyvää häiriötä, vaikka tuotekehitys on kiihtynyt.
Kun yritykset kasvavat OpenAI:n kokoluokkaan, hallinnoidut palvelut eivät enää ole yhtä valmiiksi ”hallinnoituja”. Monista työkuormista tulee poikkeustapauksia pilvipalveluntarjoajan infrastruktuurissa. Kun OpenAI:sta tuli yksi Azure Cosmos DB:n suurimmista käyttäjistä, onnistunut operointi vaati uuden toimintatavan: yhteisiä testejä ja koontinäyttöjä, suoria yhteyksiä kehittäjien välillä sekä yhteisvastuuta vikatilanteista, joita ilmenee vain meidän mittakaavassamme. Nykyään suurin Azure Cosmos DB -tilimme tallentaa kymmeniä petatavuja tietoa ja palvelee yli 20 miljoonaa kyselyä sekunnissa. Tietääksemme olemme ainoa yritys, joka on ottanut Azure Cosmos DB:n käyttöön tässä mittakaavassa.
Loppuvuonna 2024 alueellinen käyttökatko osoitti selvästi, miksi tämä yhteistyö oli välttämätöntä. Sähkökatko osui tuolloin yhden suurimman Azure Cosmos DB -tilimme ensisijaiseen Azure-alueeseen. Katkosta seuranneessa vikasietosiirtymässä havaitsimme, että suurimpien tiliemme siirtäminen toissijaiselle alueelle veisi useita tunteja. Meidän tiimimme tai Azure Cosmos DB -tiimi ei ollut testannut tätä meidän mittakaavassamme.
Noin kuukautta myöhemmin aiheutimme uuden vakavan käyttökatkon palauttaessamme tilejä alkuperäiselle alueelle. Yhteyksien vyöry alkuperäiselle alueelle ylikuormitti sen Azure Cosmos DB -yhdyskäytävän. Yhdyskäytävätilassa toimivan Azure Cosmos DB -asiakasohjelman vikasietokäsittelyn erikoisuus sai kaikki asiakasohjelmat muodostamaan heti yhteydet alkuperäiseen alueeseen ja lähettämään sinne pyyntöjä, vaikka vasta osa fyysisistä osioista oli siirtynyt takaisin.
Jokaisessa katkossa sekä OpenAI että Azure kävivät läpi häiriönhallintaprosessinsa. Tunnistimme useita juurisyitä ja otimme korjauksia käyttöön. Katkot olivat kuitenkin oire laajemmasta, järjestelmällisestä ongelmasta tiimimme ja Azure Cosmos DB -tiimin toiminta- ja testaustapojen yhteensopivuudessa. Aluksi hallinnoidut palvelut auttoivat meitä etenemään nopeasti ja keskittymään liiketoiminnan tavoitteisiin. Mittakaavan kasvaessa hallinnoidut palvelut vaativat enemmän omaa työtä ja tiivistä yhteistyötä palveluntarjoajan kanssa kaikilla tasoilla suunnittelusta operointiin.
Nykyään Habitatin ja Azuren kehitystiimit valvovat yhdessä Habitatin jokaista kerrosta omista palvelukerroksistamme Azure Cosmos DB:n fyysisiin tallennuskerroksiin asti. Ajamme ja testaamme muutoksia Azure Cosmos DB -tilillä, joka vastaa kooltaan tuotantoa mutta ei ole tuotantokäytössä. Testaamme ja kehitämme SDK:ita yhdessä sekä määritämme parhaat käytännöt Azure Cosmos DB -tiliemme skaalaamiseen ja mitoitukseen. Kehittäjämme ovat suoraan yhteydessä toisiinsa Teamsissa. Olemme jopa mahdollistaneet toistemme suoran hälyttämisen ilman tukitasojen läpikäyntiä.
Viime vuoden aikana olemme tehneet laajasti yhteistyötä Azure Cosmos DB:n hallintatason ja yhdyskäytävän skaalautuvuuden parantamiseksi. Olemme lisänneet yhdyskäytävään kuormitussuojauksen ja Azure Cosmos DB:n metatietojen välimuistituksen metatieto-osion suojaamiseksi. Olemme myös vähentäneet Python-pohjaisten habitat-service-prosessiemme aiheuttamaa kuormitusta yhteyspooleilla ja tehostamalla yhteyksien uudelleenkäyttöä, sijoittaneet työkuormia samalle alueelle mahdollisuuksien mukaan sekä eristäneet kriittiset työkuormat eräajokuormista erillisiin VPC-verkkoihin.
Näin tiivis yhteiskehitys on ollut ratkaisevaa Azure Cosmos DB -ympäristömme vakaudelle viime vuoden aikana. Jokainen riittävän suuri tai kriittinen järjestelmä vaatii tällaista yhteistyötä: vastuualueiden välisten siilojen purkamista ja toimintaa yli organisaatiorajojen.
Kuten osassa I kerroimme, perusajatuksemme on: ensin toimivaksi, sitten nopeaksi ja lopuksi edulliseksi. Ensin luotettavuus, sitten suorituskyky ja lopuksi tehokkuus. Habitatista oli tullut OpenAI:lle kriittistä infrastruktuuria, joten tärkeintä oli ensin tehdä siitä luotettava. Kun järjestelmä vakautui vuonna 2025 ja OpenAI laajeni maailmanlaajuisesti, viiveestä tuli seuraava käyttäjiä ja tuotetiimejä rajoittava tekijä.
Laskenta- ja tallennuskapasiteetti sijaitsivat usein eri alueilla, joten alueiden välisiä pyyntöjä ei voitu välttää.
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.
Laskennan ja tallennuksen maantieteelliset sijainnit ovat vain havainnollistavia.
Viive vaihteli suuresti sen mukaan, mihin tiedot oli tallennettu ja missä pyyntö käsiteltiin. Habitat-pyyntöjen nopeuttamiseksi tuotekehittäjät lisäsivät asiakaspuolen välimuistitusta, eräyttivät pyyntöjä, minimoivat tietokannan luku- ja kirjoitusoperaatioita sekä siirsivät työtä pois kriittiseltä polulta aina kun mahdollista. Tämä johti kiinnostaviin tuoteratkaisuihin, jotka sietivät tietokantaongelmia paremmin, mutta myös monimutkaisti tuotteita ja hidasti niiden kehityskierroksia. Emme siis saavuttaneet Habitatin tavoitetta: mahdollistaa nopea tuotekehitys ilman tietokannan tuntemuksen tarvetta.
Tämä on ollut tärkeä painopisteemme vuonna 2026. Olemme kehittäneet monitasoisen strategian lukujen suorituskyvyn optimointiin, sillä lukupyynnöt muodostavat yli 90 % Habitatin pyynnöistä:
Meillä on useita Azure Cosmos DB -tilejä eri Azure-alueilla ympäri maailmaa niitä käyttäjiä varten, joilla on tietojen sijaintipaikkaa koskevia vaatimuksia. Vaikka käyttäjällä ei olisi ehdottomia tietojen sijaintipaikkaa koskevia vaatimuksia, tietojen sijoittaminen hänen lähelleen parantaa käyttökokemusta pienentämällä viivettä.
Käytännössä emme pysty toteuttamaan tätä laajasti muissa kuin tietojen sijaintipaikkaan liittyvissä käyttötapauksissa, sillä pilven fyysinen kapasiteetti rajoittaa sijoittelua. Tietoaineistomme ovat niin suuria, ettei monilla alueilla ole niiden käyttäjäliikenneosuutta vastaavaa valtavaa tallennuskapasiteettia.
Alueilla, joilla datakeskuskapasiteettia, sähköä tai jäähdytystä on rajallisesti, joudumme joskus suoraan valitsemaan: varaammeko kapasiteettia paikalliseen tallennukseen ja pienennämme Habitatin viivettä vai käytämmekö sen pyyntöjä palvelevan laskennan lisäämiseen ja ohjaamme tallennuspyynnöt kauemmas?
Sijoituspäätökset ovatkin usein tuotetason kompromisseja kahden asian välillä: A) viiveen optimointi eri tuotteille ja käyttäjäryhmille sekä B) tallennus- ja laskentakapasiteetin määrä.
Viivekriittisimmissä työkuormissa, kuten joka pyynnössä tarvittavissa todennuksen metatiedoissa, lyhennämme laskennan ja Habitatin välistä edestakaista viivettä (RTT) käyttämällä laajasti replikoituja Azure Cosmos DB -tilejä, joilla on lukuisia toissijaisia alueita. Osa tileistä replikoi kaikkiin 40 Azure-alueeseen, joilla palvelemme liikennettä, ja osa vähintään yhteen alueeseen joka mantereella.
Olemme joutuneet rakentamaan Habitatiin käyttäjälle läpinäkyvän tiedonsiirto- ja reitityskerroksen toivottua aiemmin, jotta voimme siirtää tietoaineistoja replikointitopologialtaan erilaisten tilien välillä.
Kapasiteetti rajoittaa kuitenkin lopulta tätäkin lähestymistapaa, joten käytämme sitä vain muutamiin tarkoin valittuihin tietoaineistoihin.
Habitatin työkuormat ovat hyvin lukupainotteisia: sovellukset hakevat jatkuvasti asetuksia, tilatietoja ja muita ominaisuuksia. Suhteettoman suuri osa liikenteestä kohdistuu verrattain pieneen, usein käytettyjen tietotyyppien työjoukkoon. Siksi järjestelmä soveltuu erityisen hyvin hajautettuun välimuistitukseen. Välimuistitus parantaa suorituskykyä jo yhden alueen infrastruktuurissa, mutta hyöty kertautuu alueiden välillä, sillä sen avulla voidaan ”piilottaa” alueiden välinen viive.
Olemme integroineet Habitatiin hajautetun lookaside-välimuistikerroksen. Se tallentaa kopion äskettäin käytetyistä objekteista ja niiden välisistä yhteyksistä Valkey-palvelimille, jotka on sijoitettu infrastruktuurissamme lähelle käyttäjäpyyntöjen käsittelypaikkaa. Tällaisissa välimuisteissa käytetään yleensä elinaikaa (TTL), jolla tasapainotetaan osumaprosenttia ja tietojen vanhentuneisuutta. Lyhyt TTL vähentää vanhentuneisuutta mutta heikentää välimuistituksen hyötyä: tiedot poistuvat välimuistista nopeasti, joten ne on haettava useammin uudelleen. Pidempi TTL parantaa osumaprosenttia, mutta vanhentuneita tietoja tarjoillaan pidempään. Tämä heikentää käyttökokemusta ja tekee tuotteen toiminnasta arvaamatonta.
Toinen tapa on mitätöidä välimuistitiedot erikseen aina, kun sovellus kirjoittaa samoja taustalla olevia tietoja. Tämä parantaa välimuistin ajantasaisuutta huomattavasti, mutta sen oikea toteutus voi olla vaikeaa. Siihen liittyy myös poikkeustapauksia, kuten osittaisia virheitä, joiden vuoksi välimuisti jää vanhentuneeksi. Usean alueen käyttöönotot pahentavat ongelmia: alueiden väliset verkkoyhteydet ovat epäluotettavampia, ja välimuistin sekä taustatallennuksen replikoinnin välille syntyy kilpailutilanteita. TTL:n lisääminen tähän rajaa vanhentuneisuuden enimmäiskeston, mutta sama edellä kuvattu TTL-kompromissi säilyy.
Olemme valinneet kehittyneemmän mitätöintitavan Metan TAO:n kaltaisten järjestelmien jalanjäljissä. Habitatin integroitu välimuisti käyttää muutostietojen poimintaa (CDC) Azure Cosmos DB:n muutossyötteen kautta. Se välittää mitätöinnit maailmanlaajuisesti sekunneissa, jolloin osumaprosentti pysyy korkeana ja tiedot ajantasaisina. Infrastruktuurimme palvelu lukee tätä muutossyötettä ja mitätöi paikallisten välimuistien tietoja, kun taustalla olevat tiedot päivittyvät. Seuraava lukupyyntö aiheuttaa tällöin välimuistihudin, ja välimuistiin haetaan tietojen uusin versio.
Olemme myös pienentäneet viivettä huomattavasti vähentämällä itse Habitat-palvelun lisäkuormaa: kirjoitimme koodin uudelleen Rustilla, joka on alkuperäistä Python-toteutusta suorituskykyisempi.
Yhdessä nämä muutokset ovat laskeneet maailmanlaajuisen lukujen p50-viiveen noin 120 ms:sta noin 10 ms:iin. Luvut ovat siis nopeutuneet 12-kertaisiksi sen jälkeen, kun aloimme keskittyä suorituskykyyn aiemmin tänä vuonna.
Figure 05 · Improving performance at a global scale
p50 latency for reads
Three major design changes improved read latency
Vaikka välimuistitus on pienentänyt mediaaniviivettä merkittävästi, hitaimmat pyynnöt edellyttävät yhä tietojen hakemista välimuistin sijaan taustatallennuksesta, usein kaukaisilta alueilta. Kun saamme lisää kapasiteettia käyttöön ja parannamme tallennustehokkuutta, aiomme ratkaista perustavamman haasteen: tietojen sijoittamisen jo alun perin lähemmäs niiden käyttöpaikkaa.
Luotettava ja skaalautuva CDC eli tietokantamuutosten välittäminen jatkokäsittelyjärjestelmiin on kriittinen osa muutakin kuin Habitatin välimuististrategiaa. Tuhansista säilöistä ja miljoonista säilöosioista poimitaan miljoonia muutoksia sekunnissa. Ne kulkevat yli sadan Kafka-aiheen kautta ja tukevat myös viiveellä yhdenmukaistuvia toissijaisia indeksejä, tiedonsiirtoputkia, eräajoanalytiikkaa ja muita reaaliaikaisia tuoteominaisuuksia. Taustainfrastruktuurimme laajentuessa maailmanlaajuiseksi rivimuutosten kuuntelu on monimutkaistunut jatkuvasti. Jos asiakasohjelma haluaa rekisteröidä takaisinkutsun aina tietyn tyyppisten rivien muuttuessa, sen on ensin selvitettävä muun muassa, millä Cosmos-tileillä ja missä konteissa tiedot ovat sekä mikä CDC-palvelun käyttöönotto kuuntelee kyseisiä säilöjä kullakin alueella. Lisäksi CDC-palvelun käsittelijät, Kafka ja kuluttaja on skaalattava oikein. CDC-alustamme tavoitteena on piilottaa tämä kaikki tuotekehittäjiltä ja tarjota yksinkertainen rajapinta: asiakasohjelma rekisteröi funktion, jota kutsutaan sen rivien muuttuessa, ja me hoidamme taustatoteutuksen ja skaalauksen.
Sisäinen hallintataso varmistaa jatkuvasti, että muutokset poimitaan kaikista tarvittavista konteista, valitsee luettavat Cosmos-alueet ja jakaa työn tehokkaasti tuhansille käsittelijöille useilla maantieteellisillä alueilla. Replika-alueiden käyttö ja syötteen lukujen matalampi prioriteetti suojaavat viiveherkkää Habitat-liikennettä taustalla tehtävän poiminnan kuormalta. Näin suuressa ympäristössä ilmenee jatkuvasti käsittelijöiden kaatumisia, säilöongelmia, varausvaraston virheitä, virheellisiä määrityksiä ja kohdejärjestelmien häiriöitä. Vahvistimme CDC-käsittelijöiden elinkaaren ja varausten hallintaa, eristimme tietovirtojen häiriöt toisistaan ja rakensimme suojauksia määritysmuutoksiin ja käyttöönottoihin. Käytämme toimittamattomien viestien jonoja, jotta pysyvät toimitusvirheet eivät tuki koko jonoa. Selviämme alueellisista käyttökatkoista siirtämällä lukijat vaihtoehtoisille Cosmos-alueille. Mittakaavamme vuoksi olemme joutuneet muuttamaan jopa Azuren CDC SDK:ta. Tehostimme sen tarkistuspistetoteutusta eräyttämällä tarkistuspisteet muistiin ja tallentamalla ne pysyvästi vain määräajoin.
Vaikka Habitatin sisäinen Azure Cosmos DB:n käyttö on monimutkaista, sen arvolupaus on aina ollut infrastruktuurin yksityiskohtien piilottaminen tuotekehittäjiltä tuotekehityksen nopeuttamiseksi. Sama pätee CDC-alustaamme.
Pieni tiimi pystyi tukemaan nopeasti kasvavaa tallennusalustaa pitämällä tallennus-API:n tarkoituksella suppeana, jatkamalla Python-palvelun skaalausta ja priorisoimalla kiireellisimmät tekniset haasteet. Keskityimme ensin tuotteiden kriittisen liikenteen luotettavuuteen, sitten maailmanlaajuisen käyttäjäkunnan lukusuorituskykyyn ja lopuksi operatiiviseen tehokkuuteen suuressa mittakaavassa. Tämä lähestymistapa mahdollisti nopean kasvun ja uudet käyttötapaukset sekä paransi luotettavuutta, suorituskykyä ja tuotekehityksen nopeutta.
Jotta voimme skaalata Habitatin ja keskustelujen tallennuksen seuraavalle miljardille käyttäjälle, meidän on ratkaistava tietojemme replikoinnin haasteet koko infrastruktuurissamme entistä suuremmassa mittakaavassa. Ennakoimme tätä rakentamalla itse räätälöityä, eksatavuluokan verkkotallennusjärjestelmää, joka on optimoitu Habitatin suurikokoisille tietotyypeille. Tämä kehitteillä oleva järjestelmä yhdistää Rocksetin RocksDB Cloud -ytimen Raft-pohjaiseen replikointiin. Se toteuttaa saman dokumenttimallin kuin Azure Cosmos DB mutta käyttää laskennasta eriytettyä tallennusta ja fyysistä replikointia vähentääkseen tarvittavaa flash-kapasiteettia. Vastineeksi kyselyjen enimmäismäärä sekunnissa on pienempi.
Jos haluat työskennellä tällaisten tietoinfrastruktuurihankkeiden parissa edistyneen tekoälyn mittakaavassa, tutustu avoimiin työpaikkoihimme.


