Sparti internetinės saugyklos plėtra daugiau nei milijardui „ChatGPT“ naudotojų (II dalis)
Kaip optimizavome „Azure Cosmos DB“ savo programų duomenų saugojimo platformoje „Habitat“, kad atlaikytume precedento neturintį augimą.
Visiems „OpenAI“ produktams reikia greitos ir patikimos prieigos prie duomenų, kurią užtikrina mūsų saugojimo platforma „Habitat“. Ji turi per milisekundes atsakyti daugiau nei 1 milijardui naudotojų 40 geografinių regionų. Mūsų infrastruktūrai teko neeilinis iššūkis: atlaikyti spartų augimą ir palaikyti naujus naudojimo atvejus, kartu toliau gerinant patikimumą, našumą ir produktų kūrėjų darbo spartą. Norėdami jį įveikti, turėjome iš naujo apgalvoti savo operatyviosios duomenų saugojimo platformos architektūrą ir eksploatavimą. Nuolat vertinome kompromisus, laikydamiesi tokios sekos: pirmiausia užtikrinti pakankamą patikimumą kritiškai svarbiam produktų srautui, tada – pakankamą spartą naudotojams visame pasaulyje, o galiausiai – sklandų veikimą milžinišku mastu.
Šioje dviejų dalių straipsnių serijoje pasakojame, kaip „Habitat“ iš paprastos klientinės bibliotekos ir duomenų bazės išaugo į visame pasaulyje paskirstytą saugojimo platformą, teikiančią prieigą prie daugiau nei 500 petabaitų duomenų. I dalyje aptarėme „Habitat“ raidą nuo „Python“ kliento iki tarnybos. Taip pat aprašėme metodus, kurie leido išplėsti „Python“ pagrindu veikiančią tarnybą gerokai daugiau, nei daugelis laikytų praktiškai įmanoma.
Šiame įraše, II dalyje, pasakojame, kaip plėtėme pagrindinį saugojimo komponentą – „Azure Cosmos DB“. Glaudžiai bendradarbiaudami su „Azure“ komanda, sukūrėme praktišką kelių klientų aptarnavimo sprendimą, pagrįstą bendrai valdomais konteineriais ir užtikrinantį puikų skaitymo našumą milžinišku pasauliniu mastu.
01 pav. · Kas yra „Habitat“?
Internetinės saugyklos platforma
„Habitat“ – mūsų sukurta internetinės saugyklos platforma, kad OpenAI produktai galėtų greitai ir patikimai pasiekti reikiamą informaciją.
- Užklausa
- Atsakas
- Pakeitimai (CDC)
Įmonėms augant, infrastruktūros komandos dažnai pereina nuo vieno kliento sistemų prie kelių klientų sistemų. Vieno kliento architektūra, kai kiekviena už produkto sritį atsakinga komanda prižiūri savo sistemą, sumažina gedimų poveikio mastą, leidžia aiškiai apibrėžti atsakomybę ir izoliuoti užduotis. Augant komandoms ir produktų sričių skaičiui, tokių sistemų eksploatavimas brangsta. Vieno kliento architektūroje kiekviena produkto komanda pati atsako už pajėgumų planavimą, todėl dažnai skiriama gerokai per daug išteklių.
O kelių klientų architektūroje valdymas patikimas centralizuotai duomenų bazių komandai, turinčiai daugiau žinių ir patirties skirstant išteklius. Tačiau kelių klientų architektūra sukelia savų problemų, pavyzdžiui, triukšmingų kaimynų: vienas klientas sunaudoja neįprastai didelę išteklių dalį kitų klientų sąskaita.
Kurdami „Habitat“, turėjome pasverti visus šiuos kompromisus, kad sukurtume patikimą ir efektyvią didelio masto saugojimo sistemą. Šiandien „Habitat“ yra kelių klientų duomenų bazių sluoksnis, kuriuo naudojasi daugelis „OpenAI“ produktų. Tačiau iki to nuėjome ratą: nuo vieno bendro „Azure Cosmos DB“ konteinerio perėjome prie atskirų vienam klientui skirtų saugojimo konteinerių, o vėliau grįžome prie bendro konteinerio kaip numatytojo pasirinkimo. Kelių klientų aptarnavimo „Habitat“ platformoje istorija dar tik prasideda: palaikome daug naudojimo atvejų, tačiau investicijas į šią sritį galėjome atidėti, kur tik įmanoma pasitelkdami integruotas „Azure Cosmos DB“ bazines priemones.
Prieš pasakodami apie savo kelią su „Azure Cosmos DB“, pateiksime kelis pagrindinius dalykus:
„Azure Cosmos DB“ paskyra apibrėžia konteinerių rinkinį ir replikavimo politiką
Kiekvienam konteineriui skiriamas tam tikras pralaidumas, matuojamas užklausų vienetais per sekundę (RU/s)
Kiekviename konteineryje duomenys saugomi įprastai skaidant juos pagal nurodytą loginio skaidinio raktą; kiekvienam tokiam raktui taikomos dokumentacijoje nurodytos saugojimo talpos ir pralaidumo ribos
„Azure Cosmos DB“ paskirsto loginių skaidinių raktus tarp mažesnio skaičiaus fizinių skaidinių. Šie dalijami į kelis fizinius skaidinius, kai saugomų duomenų kiekis viršija slenkstį arba kai konteineriui reikia daugiau fizinių skaidinių, kad išlaikytų skirtą pralaidumą
Iš pradžių praleisdavome visą klientų apkrovą, tikėdamiesi, kad deklaruota 10 tūkst. RU/s riba vienam loginio skaidinio raktui užtikrins atgalinį srauto ribojimą. Pradžioje kiekvienoje paskyroje taip pat naudojome tik vieną numatytąjį „Azure Cosmos DB“ konteinerį. Tai veikė gana gerai, tačiau dėl kelių priežasčių kilo problemų:
Dėl ankstyvų API projektavimo sprendimų leidome klientams tiesiogiai pasirinkti loginio skaidinio raktą. Todėl skirtingi produktų naudojimo atvejai dažnai susikerta ties įprastais skaidinių raktais, tokiais kaip user_id ar workspace_id. Kadangi šiems naudojimo atvejams buvo taikomi bendri „Azure Cosmos DB“ limitai tiems patiems loginių skaidinių raktams, tokia architektūra ribojo bendrą konkrečiam naudotojui prieinamą pralaidumą.
Prieš pereidami prie „Habitat“ ir „Azure Cosmos DB“, plėsdami „Postgres“ dažnai susidurdavome su viena problema: daugybė užklausų iš itin aktyvios organizacijos ar pagal itin dažnai naudojamą raktą – kai vienas klientas sukurdavo neproporcingai didelę apkrovą – galėjo sutrikdyti visą duomenų bazę. Bendromis pastangomis daug darbo skyrėme tokių raktų duomenims kaupti podėlyje ir laikino išskirtinio leidimo mechanizmui taikyti, kai duomenų podėlyje nerandama, kad dėl to kylanti apkrova neperkrautų pagrindinės duomenų bazės.
Figure 02a · Logical partition key limits
Different clients, the same partition key
Nors dokumentacijoje nurodytos duomenų dydžio ir pralaidumo ribos taikomos loginių skaidinių raktams, iš tikrųjų jos įgyvendinamos fizinio skaidinio lygmeniu. Praktiškai tai reiškia, kad loginiai skaidiniai negali pasiekti 10 000 RU/s. Jie dalijasi fizinio skaidinio limitais su visais kitais tame pačiame fiziniame skaidinyje esančiais loginių skaidinių raktais.
Dėl to triukšmingi kaimynai galėjo paveikti daug nesusijusių loginių skaidinių raktų: nišinių produkto funkcijų duomenis apdorojančios užduotys trikdė pagrindinius prisijungimo ir registracijos procesus.
Figure 02b · Noisy neighbors
Different users, the same physical partition
Konkretaus fizinio skaidinio pralaidumo riba taip pat kinta – ji priklauso nuo bendro „Azure Cosmos DB“ konteineriui skirto pralaidumo. Konteineriui skirtas pralaidumas maždaug tolygiai paskirstomas jo fiziniams skaidiniams.
Augant duomenų kiekiui, fiziniai skaidiniai dalijami, todėl bendras jų skaičius didėja, o bendras skirtas pralaidumas lieka nepakitęs. Taigi, augant duomenų kiekiui, faktinė vieno skaidinio pralaidumo riba mažėja.
Tais atvejais, kai saugome daugiausia duomenų, panašių į dvejetainius objektus, atsiranda toks gedimo scenarijus: vien saugomų duomenų augimas sumažina aktyvioms užduotims prieinamą pralaidumą, nors užklausų dažnis ir naudojimas nesikeičia.
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.
Atskiri konteineriai padeda iš dalies išspręsti skaidinių raktų limitų ir triukšmingų kaimynų problemas. Kiekvienam atskiram konteineriui galima skirti nepriklausomus fizinius skaidinius. Tuomet triukšmingais kaimynais gali tapti ar skaidinių raktų erdvėje persidengti tik tame pačiame konteineryje vykdomos skirtingos užduotys. Kita vertus, naujų konteinerių parengimas reikalauja papildomo darbo – kiekvieno jų pajėgumus reikia planuoti atskirai. Todėl konteinerius norime kurti tik ten, kur juos prasminga atskirti pagal tarnybą ar naudojimo atvejį.
Svarbiausiems naujiems naudojimo atvejams, kuriems reikėjo griežto izoliavimo, pradėjome naudoti atskirus „Azure Cosmos DB“ konteinerius. Kartu naudojome scenarijų, kuris sprendė silpnų skaidinių problemą, derindamas kiekvienam konteineriui skirtą bendrą pralaidumą su jo fizinių skaidinių skaičiumi. Taip iš esmės išvengėme visų anksčiau patirtų problemų.
Tačiau pradėjome nuo numatytojo konteinerio, todėl daugelis senesnių kritiškai svarbių naudojimo atvejų, deja, liko jame, kol nebuvo perkelti jų duomenys. Siekdami apsaugoti kritines tarnybas, kurios vis dar naudojo duomenis bendrame numatytajame konteineryje, dažnai patardavome komandoms naujoms tarnyboms ar svarbioms produkto funkcijoms kurti atskirus konteinerius. Mums plečiantis, numatytojo konteinerio apkrova augo, daugėjo ir incidentų produkcinėje aplinkoje. Pradėjome skirti konteinerius kiekvienai naujai tarnybai ar didelei produkto funkcijai vien tam, kad apsaugotume numatytąjį konteinerį nuo papildomos apkrovos.
Tai padėjo išvengti daugelio visos svetainės veikimo sutrikimų – jų poveikis apsiribodavo atskirų funkcijų ar tarnybų veikimo pablogėjimu. Tačiau ilgainiui papildomas naujų konteinerių parengimo darbas tapo našta:
Senajame bendrame numatytajame konteineryje bet kurio naujo naudojimo atvejo augimas nuo 0 iki 1 mln. užklausų per sekundę (QPS) vargu ar būtų smarkiai pakeitęs bendrą naudojimą. Tačiau izoliuotame konteineryje naujo naudojimo atvejo augimas nuo 0 iki 1 mln. QPS galėjo reikšti 1 000 kartų didesnę apkrovą, palyginti su pradiniu lygiu, susidariusiu tik dėl vidinio produkto naudojimo.
Naudodamos atskirus konteinerius, komandos turėjo nepamiršti iš anksto skirti jiems tiek pralaidumo, kiek tikimasi paleidžiant produktą. Produktų komandos dažnai įdiegdavo funkcijas į produkcinę aplinką pamiršusios iš anksto padidinti pajėgumus, o mes paleidimo dieną sėdėdavome kritinių incidentų koordinavimo susitikimuose ir paskutinę minutę bandydavome išplėsti konteinerius.
Taikydami šią konteinerių strategiją ir rinkdamiesi geresnį izoliavimą, prarandame vieną esminių kelių klientų sistemų privalumų – apkrovos išlyginimą derinant skirtingas užduotis.
Figure 03 · Lack of stable aggregate growth
The same workload, different headroom
1K RU/s during load testing → 1M RU/s at launch
Ilgainiui, stebint atskirų konteinerių naudojimą, taip pat reikėjo gerai išmanyti produktą ir žinoti, kada jo srautas keisis ar augs.
Galime pateikti paprastą valdymo sluoksnio scenarijų, kuris didina kiekvienam konteineriui skirtą pralaidumą pagal augimo tendencijas. Tačiau, nesant stabilaus bendros apkrovos augimo, norint tinkamai parinkti pajėgumus, į jų planavimą teko įtraukti iš esmės kiekvieną „OpenAI“ produktų komandą.
Organizacijai augant, šis metodas nebepasiteisino, nes skirtingos už tarnybas atsakingos komandos labai nevienodai rūpinosi savo „Azure Cosmos DB“ išteklių skyrimu.
Organizacijai augant, šias eksploatavimo problemas spręsti darėsi vis sunkiau. Nesant vienos centrinės planavimu besirūpinančios komandos, daugelis komandų planavo prastai. Todėl galiausiai vėl pasukome kelių klientų sprendimo link ir glaudžiai bendradarbiavome su „Azure“ komanda, kad bendro naudojimo architektūroje išspręstume pradines problemas:
Pirmiausia ribojant dažniausiai naudojamų raktų užklausas, triukšmingiems kaimynams neleidžiama išnaudoti viso konkretaus fizinio skaidinio pralaidumo. Taip sumažinamas triukšmingo kaimyno poveikis, kai vienas aktyvus raktas gali sutrikdyti visą svetainę.
Užklausų skirstymu į lygius pagrįsta QoS taip pat neleidžia foninėms užduotims, pavyzdžiui, masiniam įrašų įterpimui ar duomenų išgavimui, išnaudoti viso konkretaus fizinio skaidinio pralaidumo. Šių užduočių užklausoms suteikiamas žemesnis prioritetas, todėl jos ribojamos pirmiausia. Taip išvengiama aukštesnio prioriteto interaktyvių užklausų, aptarnaujančių galutinius naudotojus, ribojimo.
„Azure Cosmos DB“ jau turėjo režimą be serverių, kuris būtų išsprendęs silpnų skaidinių problemą, kilusią naudojant iš anksto skirto pralaidumo režimą. Tačiau jis turėjo didelį trūkumą: pajėgumai buvo didinami tik pagal saugomų duomenų kiekį, o RU naudojimas vienam fiziniam skaidiniui buvo ribojamas iki 5 tūkst. RU/s. Tai būtų išsprendę silpnų skaidinių problemą, bet neleidę plėsti daug RU reikalaujančių naudojimo atvejų.
„Azure Cosmos DB“ komanda mums sukūrė patobulintą režimą be serverių, leidžiantį kiekvieno fizinio skaidinio pralaidumą didinti iki 10 tūkst. RU/s. Be skaidymo pagal saugomų duomenų kiekį, jame atsirado skaidymas pagal RU naudojimą, todėl nebereikėjo rankiniu būdu stebėti ir didinti konteinerių pajėgumų.
Šie pakeitimai leido grįžti prie vieno bendro konteinerio. Taip gerokai sumažėjo produktų komandų poreikis iš anksto ar nuolat planuoti pajėgumus, o užduočių izoliavimas išliko. Per nuo to laiko praėjusius mėnesius nepatyrėme nė vieno incidento dėl išteklių skyrimo ar triukšmingų kaimynų, nors produktų kūrimas spartėjo.
Įmonėms pasiekus „OpenAI“ mastą, valdomosios paslaugos tampa mažiau „valdomos“. Daugelis užduočių debesijos teikėjo infrastruktūroje tampa išskirtiniais atvejais. „OpenAI“ tapus viena didžiausių „Azure Cosmos DB“ naudotojų, sėkmingam eksploatavimui prireikė kitokio darbo modelio: bendrų bandymų, bendrų stebėsenos skydelių, tiesioginių inžinierių bendravimo kanalų ir bendros atsakomybės už gedimų scenarijus, atsirandančius tik mūsų mastu. Šiandien didžiausioje mūsų „Azure Cosmos DB“ paskyroje saugoma dešimtys petabaitų duomenų ir apdorojama daugiau nei 20 mln. užklausų per sekundę. Mūsų žiniomis, esame vienintelė įmonė, įdiegusi „Azure Cosmos DB“ tokiu mastu.
2024 m. pabaigoje įvykęs regioninis sutrikimas aiškiai parodė, kodėl šis bendradarbiavimas būtinas. Tuo metu pagrindiniame vienos didžiausių mūsų „Azure Cosmos DB“ paskyrų „Azure“ regione nutrūko elektros tiekimas. Per dėl to vykusį perjungimą į atsarginį regioną supratome, kad didžiausioms paskyroms toks perjungimas užtruktų kelias valandas. Tokio masto proceso nebuvo išbandžiusi nei mūsų, nei „Azure Cosmos DB“ komanda.
Maždaug po mėnesio, grąžindami šias paskyras į pradinį regioną, sukėlėme dar vieną rimtą sutrikimą. Staigus jungčių antplūdis į pradinį regioną perkrovė jo „Azure Cosmos DB“ šliuzą. Dėl šliuzo režimu veikiančio „Azure Cosmos DB“ kliento perjungimo logikos ypatybės visi klientai iškart užmezgė jungtis ir pradėjo siųsti užklausas į pradinį regioną, nors į jį buvo grįžusi tik dalis fizinių skaidinių.
Per kiekvieną sutrikimą tiek „OpenAI“, tiek „Azure“ taikė savo incidentų valdymo procesus: nustatė kelias pagrindines priežastis ir įdiegė pataisas. Tačiau šie sutrikimai buvo platesnės sisteminės problemos požymiai – mūsų ir „Azure Cosmos DB“ komandų darbo bei testavimo būdai buvo nepakankamai suderinti. Iš pradžių valdomosios paslaugos leido sparčiai judėti pirmyn ir susitelkti į verslo tikslus. Mastui išaugus, valdomosios paslaugos tampa mažiau valdomos ir reikalauja glaudaus bendradarbiavimo su teikėju visais lygmenimis – nuo projektavimo iki eksploatavimo.
Šiandien „Habitat“ ir „Azure“ inžinierių komandos kartu stebi kiekvieną „Habitat“ sluoksnį – nuo mūsų tarnybų iki „Azure Cosmos DB“ fizinio saugojimo sluoksnių. Eksploatuojame produkcinės aplinkos dydžio, bet ne produkcinę „Azure Cosmos DB“ paskyrą ir joje bandome pakeitimus. Kartu testuojame ir tobuliname SDK bei nustatome geriausią „Azure Cosmos DB“ paskyrų plėtimo ir pajėgumų parinkimo praktiką. Mūsų inžinieriai gali tiesiogiai susisiekti vieni su kitais per „Teams“, o prireikus net tiesiogiai iškviesti budinčius specialistus, neperėję visų pagalbos lygių.
Per pastaruosius metus bendromis pastangomis gerokai patobulinome „Azure Cosmos DB“ valdymo sluoksnio ir šliuzo galimybes plėstis. Šliuze įdiegėme apsaugą nuo perkrovos ir įvairių „Azure Cosmos DB“ metaduomenų podėlį, kad apsaugotume metaduomenų skaidinį. Naudodami jungčių telkinius ir dažniau pakartotinai naudodami jungtis, sumažinome daugybės mūsų „Python“ procesų „habitat-service“ sukeliamą apkrovą. Kur įmanoma, susijusias užduotis perkėlėme į tą pačią vietą, o kritines užduotis atskyrėme nuo foninių, naudodami skirtingus VPC.
Toks glaudus inžinerinis bendradarbiavimas buvo itin svarbus „Azure Cosmos DB“ stabilumui užtikrinti per pastaruosius metus. Bet kuriai pakankamai didelei ar svarbiai sistemai reikia tokio komandinio darbo: atsisakyti griežtų atsakomybės ribų ir bendradarbiauti nepaisant organizacinių barjerų.
Kaip minėjome I dalyje, mūsų pagrindinis principas – pirmiausia užtikrinti, kad sistema veiktų, tada ją paspartinti, o galiausiai sumažinti sąnaudas. Pirmiausia patikimumas, tada našumas, galiausiai efektyvumas. „Habitat“ tapo kritiškai svarbia „OpenAI“ infrastruktūra, todėl svarbiausias prioritetas buvo užtikrinti jos patikimumą. 2025 m. sistemai stabilizavusis, o „OpenAI“ plečiantis visame pasaulyje, kita kliūtimi naudotojams ir produktų komandoms tapo delsa.
Skaičiavimo ir saugojimo ištekliai dažnai buvo skirtinguose regionuose, todėl užklausų tarp regionų išvengti nebuvo įmanoma.
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.
Skaičiavimo ir saugojimo išteklių geografinės vietos pateiktos tik iliustraciniais tikslais.
Delsa labai skyrėsi priklausomai nuo to, kur buvo saugomi duomenys ir kur apdorojama užklausa. Siekdami paspartinti „Habitat“ užklausas, produktų kūrėjai naudojo papildomą podėlį kliento pusėje, grupavo užklausas, mažino skaitymo ir rašymo į duomenų bazę operacijų skaičių ir, kur tik įmanoma, perkėlė darbus už kritinio vykdymo kelio ribų. Nors taip atsirado įdomių produktų projektavimo sprendimų, atsparesnių duomenų bazės sutrikimams, produktai tapo sudėtingesni, o jų tobulinimas sulėtėjo. Vadinasi, nepasiekėme „Habitat“ tikslo – sudaryti sąlygas greitai kurti produktus, nesigilinant į duomenų bazės veikimą.
2026 m. tam skiriame daug dėmesio ir parengėme kelių lygių strategiją skaitymo operacijų, kurios sudaro daugiau nei 90 % „Habitat“ užklausų, našumui optimizuoti:
Naudotojams, turintiems duomenų saugojimo vietos reikalavimų, turime kelias „Azure Cosmos DB“ paskyras skirtinguose „Azure“ regionuose visame pasaulyje. Net ir tiems naudotojams, kurie neturi griežtų duomenų saugojimo vietos reikalavimų, duomenų saugojimas netoliese pagerina naudojimosi patirtį, nes sumažėja delsa.
Praktiškai, išskyrus duomenų saugojimo vietos reikalavimų atvejus, negalime to taikyti plačiai, nes duomenų išdėstymą riboja fiziniai debesijos pajėgumai. Mūsų duomenų rinkiniai tokie dideli, kad daugelyje regionų nepakanka milžiniškos saugojimo talpos, reikalingos proporcingai jų naudotojų srauto daliai.
Regionuose, kuriuose riboti duomenų centrų pajėgumai, elektros tiekimas ar aušinimas, kartais tenka rinktis: rezervuoti pajėgumus saugyklai tame pačiame regione ir sumažinti „Habitat“ delsą ar panaudoti juos papildomiems užklausų apdorojimo skaičiavimams, o saugojimo užklausas nukreipti toliau.
Todėl duomenų išdėstymo sprendimai dažnai yra produkto poreikių nulemtas kompromisas tarp A) delsos optimizavimo skirtingiems produktams ir naudotojų grupėms ir B) turimų saugojimo bei skaičiavimo pajėgumų.
Užduotims, kurioms delsa ypač svarbi, pavyzdžiui, kiekvienai užklausai reikalingiems autentifikavimo metaduomenims gauti, mažiname užklausos ir atsako kelionės laiką (RTT) tarp skaičiavimo išteklių ir „Habitat“, naudodami plačiai replikuojamas „Azure Cosmos DB“ paskyras su daug antrinių regionų. Kai kurių paskyrų duomenys replikuojami į visus 40 „Azure“ regionų, kuriuose apdorojame srautą, kitų – bent į vieną regioną kiekviename žemyne.
Anksčiau nei norėjome turėjome į „Habitat“ įdiegti klientams nepastebimą duomenų perkėlimo ir maršrutizavimo sluoksnį, kad galėtume perkelti duomenų rinkinius tarp paskyrų su skirtingomis replikavimo topologijomis.
Tačiau ir šį metodą galiausiai riboja pajėgumai, todėl jį taikome tik keliems specialiai atrinktiems duomenų rinkiniams.
„Habitat“ apkrovoje aiškiai vyrauja skaitymo operacijos: programos nuolat gauna nustatymus, būseną ir kitas savybes. Neproporcingai didelę srauto dalį sukuria palyginti nedidelis dažnai naudojamų tipų darbinis duomenų rinkinys. Todėl sistemai ypač tinka paskirstytas podėlis. Podėlis pagerina našumą ir vieno regiono infrastruktūroje, tačiau dirbant keliuose regionuose jo nauda dar didesnė, nes jis gali „paslėpti“ tarpregioninę delsą.
Į „Habitat“ integravome paskirstyto šoninio podėlio sluoksnį. Jis saugo neseniai naudotų objektų ir ryšių kopijas „Valkey“ serveriuose, esančiuose mūsų infrastruktūroje netoli naudotojų užklausų apdorojimo vietų. Paprastai tokiuose podėliuose naudojamas galiojimo laikas (TTL), kuriuo derinama duomenų radimo podėlyje dalis ir jų pasenimas. Trumpas TTL sumažina duomenų pasenimą, tačiau susilpnina podėlio naudą: įrašai greitai nustoja galioti, todėl juos reikia dažniau gauti iš naujo. Ilgesnis TTL padidina duomenų radimo podėlyje dalį, tačiau pasenę duomenys pateikiami ilgiau, todėl prastėja naudotojų patirtis, o produkto elgsena tampa nenuspėjama.
Kitas būdas – aiškiai anuliuoti podėlio įrašus, kai programa atlieka tų pačių pagrindinių duomenų rašymo operacijas. Tai gerokai padidina podėlio duomenų aktualumą, tačiau tinkamai įgyvendinti šį metodą gali būti sunku. Be to, lieka įvairių išimtinių situacijų, pavyzdžiui, dalinių gedimų, dėl kurių podėlyje išlieka pasenę duomenys. Diegimas keliuose regionuose šias problemas dar sustiprina: tarpregioniniai tinklai mažiau patikimi, o podėlio atnaujinimas lenktyniauja su pagrindinės saugyklos replikavimu. Papildomai taikant TTL galima apriboti didžiausią duomenų pasenimą, tačiau išlieka tas pats anksčiau aptartas kompromisas dėl TTL.
Pasirinkome pažangesnį įrašų anuliavimo metodą, sekdami tokių sistemų kaip „Meta“ TAO pavyzdžiu. Integruotas „Habitat“ podėlis naudoja duomenų pakeitimų fiksavimą (CDC) per „Azure Cosmos DB“ pakeitimų srautą. Taip įrašų anuliavimas per kelias sekundes išplatinamas visame pasaulyje, duomenys dažnai randami podėlyje, bet retai būna pasenę. Mūsų infrastruktūroje veikianti tarnyba apdoroja šį pakeitimų srautą ir, atnaujinus pagrindinius duomenis, anuliuoja atitinkamus vietinių podėlių įrašus. Todėl kitą kartą skaitant šių duomenų podėlyje nerandama ir į jį įkeliama naujausia jų versija.
Taip pat gerokai sumažinome delsą pašalinę papildomas apdorojimo sąnaudas pačioje „Habitat“ tarnyboje: perrašėme kodą „Rust“ kalba, kuri veikia našiau už pradinę „Python“ versiją.
Visi šie pakeitimai sumažino bendrą pasaulinę skaitymo delsos p50 reikšmę nuo maždaug 120 ms iki maždaug 10 ms – nuo šių metų pradžios, kai ėmėme daugiau dėmesio skirti našumui, šis rodiklis pagerėjo 12 kartų.
Figure 05 · Improving performance at a global scale
p50 latency for reads
Three major design changes improved read latency
Nors podėlis gerokai sumažino delsos medianą, lėčiausioms užklausoms vis dar reikia gauti jame nesančius duomenis iš pagrindinės saugyklos, dažnai – iš tolimų regionų. Atsirandant daugiau pajėgumų ir mums gerinant saugojimo efektyvumą, planuojame spręsti esminę problemą: nuo pat pradžių saugoti duomenis arčiau vietos, iš kurios jie bus pasiekiami.
Patikimas ir plečiamas CDC, perduodantis duomenų bazės pakeitimus tolesnėms sistemoms, yra svarbus ne tik „Habitat“ podėlio strategijai. Kas sekundę tūkstančiuose konteinerių ir milijonuose jų skaidinių fiksuojami milijonai pakeitimų perduodami per daugiau nei šimtą „Kafka“ temų. Jie taip pat palaiko galiausiai suderinamus antrinius indeksus, duomenų perkėlimo grandines, foninę analitiką ir kitas realiuoju laiku veikiančias produktų funkcijas. Mūsų pagrindinei infrastruktūrai plečiantis visame pasaulyje, stebėti eilučių pakeitimus darėsi vis sudėtingiau. Jei klientas nori užregistruoti atgalinio iškvietimo funkciją, vykdomą kaskart pasikeitus jo tipo eilutėms, pirmiausia, be kita ko, turi nustatyti, kuriose „Cosmos“ paskyrose ir konteineriuose yra jo duomenys ir kuris CDC tarnybos dieginys atitinkamuose regionuose stebi tuos konteinerius. Taip pat reikia tinkamai parinkti CDC vykdymo procesų, „Kafka“ ir savo duomenų gavėjo pajėgumus. Mūsų CDC platformos tikslas – paslėpti visą šį sudėtingumą nuo produktų kūrėjų ir suteikti paprastą sąsają: klientai užregistruoja funkciją, kurią nori iškviesti pasikeitus jų eilutėms, o visa infrastruktūra ir jos plėtra pasirūpiname mes.
Vidinis valdymo sluoksnis nuolat užtikrina, kad būtų fiksuojami visų reikiamų konteinerių pakeitimai, parenka „Cosmos“ regionus, iš kurių skaityti, ir efektyviai paskirsto darbą tūkstančiams vykdymo procesų keliuose geografiniuose regionuose. Replikų regionų naudojimas ir žemesnio prioriteto pakeitimų srauto skaitymo užklausos apsaugo delsai jautrų „Habitat“ srautą nuo foninių pakeitimų fiksavimo užduočių apkrovos. Tokio dydžio infrastruktūroje nuolat pasitaiko vykdymo procesų strigčių, konteinerių problemų, laikinų išskirtinių leidimų saugyklos klaidų, netinkamų konfigūracijų ir paskirties sistemų gedimų. Sustiprinome CDC vykdymo procesų gyvavimo ciklo ir laikinų išskirtinių leidimų valdymą, izoliavome skirtingų srautų gedimus ir įdiegėme apsaugos priemones konfigūracijos keitimui bei naujų versijų diegimui. Naudojame nepristatytų pranešimų eiles, kad nuolatinės pristatymo klaidos neužblokuotų visos eilės. Regioninius sutrikimus atlaikome perjungdami skaitymo procesus į kitus „Cosmos“ regionus. Dėl mūsų masto net teko keisti „Azure“ CDC SDK, kad kontroliniai taškai būtų saugomi efektyviau: kaupiami atmintyje paketais ir tik periodiškai įrašomi į saugyklą.
Nors „Habitat“ viduje „Azure Cosmos DB“ naudojama sudėtingai, platformos vertė visada buvo ta pati – paslėpti infrastruktūros detales nuo produktų kūrėjų ir taip paspartinti jų darbą. Mūsų CDC platforma nėra išimtis.
Nedidelė komanda sugebėjo prižiūrėti sparčiai augančią saugojimo platformą, sąmoningai ribodama saugojimo API apimtį, toliau plėsdama „Python“ tarnybą ir pirmiausia spręsdama skubiausius inžinerinius iššūkius. Pirmiausia susitelkėme į kritiškai svarbaus produktų srauto patikimumą, tada – į skaitymo našumą naudotojams visame pasaulyje, o galiausiai – į efektyvų eksploatavimą dideliu mastu. Šis požiūris leido sparčiai augti ir palaikyti naujus naudojimo atvejus, kartu gerinant patikimumą, našumą ir produktų kūrimo spartą.
Kad galėtume išplėsti „Habitat“ ir pokalbių saugyklą kitam milijardui naudotojų, turime išspręsti duomenų replikavimo visoje infrastruktūroje dar didesniu mastu sunkumus. Ruošdamiesi tam, savo jėgomis kuriame specialią eksabaitų masto operatyviojo duomenų saugojimo sistemą, optimizuotą didelės apimties „Habitat“ duomenų tipams. Šioje dar kuriamoje sistemoje „Rockset“ sukurtas „RocksDB Cloud“ branduolys derinamas su „Raft“ pagrįstu replikavimu. Joje įgyvendinamas toks pat dokumentų modelis kaip „Azure Cosmos DB“, tačiau naudojamas nuo skaičiavimo atskirtas saugojimas ir fizinis replikavimas. Tai sumažina reikiamą „flash“ atminties talpą, tačiau kartu sumažėja didžiausias užklausų skaičius per sekundę.
Jei norėtumėte prisidėti prie tokių duomenų infrastruktūros projektų, skirtų priešakinių technologijų mastui, peržiūrėkite mūsų darbo pasiūlymus.


