Duomenų bazės mastelio supratimo vadovas

Internete yra daugybė straipsnių, aprašančių duomenų bazės mastelio keitimo modelius, tačiau dažniausiai tai yra išsklaidyti straipsniai - tik metodai, kurie apibrėžiami atsitiktinai, be didelio konteksto. Manau, kad jie nėra apibrėžti žingsnis po žingsnio ir neaptarinėkite, kada pasirinkti mastelio parinktį, kurios mastelio parinktys yra praktiškai įmanomos ir kodėl.

Todėl planuoju kai kuriuos metodus išsamiai aptarti būsimuose straipsniuose. Pradėdamas jaučiu, kad geriau, jei žingsnis po žingsnio aptariu tam tikro konteksto metodus savaip. Šis straipsnis yra aukšto lygio straipsnis - čia išsamiau neaptarsiu mastelio keitimo technikos, bet pateiksiu apžvalgą. Taigi pradėkime.

Atvejo analizė

Tarkime, kad sukūrėte startuolį, kuris siūlo pasidalijimą pigiomis kainomis. Iš pradžių, kai pradedate, taikote į miestą ir po pradinės reklamos vargu ar turite dešimtis klientų.

Jūs išsaugote visus klientus, keliones, vietas, užsakymų duomenis ir klientų kelionių istoriją toje pačioje duomenų bazėje arba greičiausiai vienoje fizinėje mašinoje. Nėra jokio įmantraus talpyklos ar didelių duomenų perdavimo, kad būtų galima išspręsti problemas, nes jūsų programa yra labai nauja. Šiuo metu tai puikiai tinka jūsų naudojimo atvejui, nes klientų yra labai nedaug, o jūsų sistema vargu ar užsisakys 1 kelionę per 5 minutes, pavyzdžiui.

Bet laikui bėgant, daugiau žmonių pradeda registruotis jūsų sistemoje, nes jūs esate pigiausia paslauga rinkoje ir jūsų reklama bei skelbimai. Pradėsite rezervuoti, tarkime, 10 užsakymų per minutę, o pamažu skaičius padidės iki 20, 30 užsakymų per minutę.

Šiuo metu suprantate, kad sistema pradėjo veikti prastai: API vėlavimas labai išaugo, o kai kurie sandoriai pateko į aklavietę arba badauja ir galiausiai nepavyksta. Programai reaguoti reikia daugiau laiko, sukeldama klientų nepasitenkinimą. Ką galite padaryti, kad išspręstumėte problemą?

1 modelis - užklausų optimizavimas ir ryšių telkinio diegimas:

Pirmasis sprendimas, kuris ateina į galvą, yra tai, kad talpykloje dažnai naudojami ne dinamiški duomenys, tokie kaip rezervavimo istorija, mokėjimų istorija, vartotojų profiliai ir pan. Bet po šio programų sluoksnio talpyklos jūs negalite išspręsti API delsos problemos, atskleidžiančios dinaminius duomenis, pvz., Dabartinę vairuotojo vietą ar artimiausias kabinas tam tikram klientui ar dabartines kelionės išlaidas tam tikru momentu po kelionės pradžios.

Jūs nustatote, kad jūsų duomenų bazė tikriausiai yra smarkiai normalizuota, todėl įveskite keletą nereikalingų stulpelių (šie stulpeliai dažnai rodomi užklausose WHEREarba JOIN ONįtraukiami į klausimus) labai naudojamose lentelėse dėl denormalizavimo. Tai sumažina prisijungimo užklausas, suskirsto didelę užklausą į kelias mažesnes užklausas ir jų rezultatus įtraukia į programos sluoksnį.

Kitas lygiagretus optimizavimas, kurį galite padaryti, yra duomenų bazės ryšių koregavimas. Duomenų bazės kliento bibliotekos ir išorinės bibliotekos yra prieinamos beveik visomis programavimo kalbomis. Galite naudoti ryšių telkinio bibliotekas talpinti duomenų bazių ryšius arba konfigūruoti ryšio telkinio dydį pačioje duomenų bazės valdymo sistemoje.

Bet kokio tinklo ryšio sukūrimas yra brangus, nes tam reikia tam tikro pirmyn ir atgal ryšio tarp kliento ir serverio. Jungčių sujungimas gali padėti optimizuoti jungčių skaičių. Ryšių telkinio bibliotekos gali padėti jums sudaryti daugkartinį ryšį - ta pati duomenų bazės jungtis gali naudoti kelios programų gijos. Pažiūrėsiu, ar vėliau galėsiu išsamiai paaiškinti jungčių kaupimą atskirame straipsnyje.

Matuokite savo API vėlavimą ir suraskite tikriausiai 20–50% ar daugiau sumažintą vėlavimą. Tai yra geras optimizavimas šiuo metu.

Dabar padidinote savo verslą dar vienam miestui, prisiregistruoja daugiau klientų, pamažu pradedate užsisakyti 80–100 užsakymų per minutę. Jūsų sistema negali apdoroti šios skalės. Vėlgi matote, kad API vėlavimas padidėjo, duomenų bazės sluoksnis pasidavė, tačiau šį kartą jokia užklausos optimizacija neduoda reikšmingo našumo. Jūs patikrinate sistemos metriką, pastebite, kad vietos diske yra beveik pilna, procesorius užimtas 80% laiko, RAM užpildoma labai greitai.

2 modelis - vertikalus mastelio keitimas arba padidinimas:

Išnagrinėję visą sistemos metriką, žinote, kad nėra kito paprasto sprendimo, o ne atnaujinti sistemos aparatinę įrangą. Jūs atnaujinate savo RAM dydį 2 kartus, vietos diske atnaujinkite, tarkime, 3 kartus ar daugiau. Tai vadinama vertikaliu mastelio keitimu arba sistemos didinimu. Jūs informuojate savo infrastruktūros komandą, paslaugų teikėjų komandą ar trečiųjų šalių duomenų centro agentus, kad jie atnaujintų jūsų kompiuterį.

Bet kaip sukonfigūruoti vertikalų mastelį?

Skiriate didesnę mašiną. Vienas iš būdų yra ne perkelti duomenis rankiniu būdu iš senos mašinos, o nustatyti naują mašiną kaip replicaesamą mašiną ( primary) - padaryti laikiną primary replicakonfigūraciją. Tegul replikacija vyksta natūraliai. Atlikus atkūrimą, paaukštinkite naują mašiną kaip pagrindinę, o senesnę - neprisijungę. Kadangi tikimasi, kad didesnė mašina pateiks visas užklausas, visa mašina bus skaitoma / rašoma.

Saunus. Jūsų sistema vėl veikia ir veikia su didesniu našumu.

Jūsų verslui sekasi labai gerai, todėl nusprendėte išplėsti dar 3 miestus - iš viso dirbate 5 miestuose. Srautas yra 3 kartus didesnis nei anksčiau, tikimasi, kad atliksite maždaug 300 užsakymų per minutę. Dar nepasiekus šio tikslo rezervavimo, vėl pasiekiate našumo krizę, duomenų bazės rodyklės dydis atmintyje labai auga, ją reikia nuolat prižiūrėti, lentelių nuskaitymas su indeksu tampa lėtesnis nei bet kada. Jūs apskaičiuojate mašinos didinimo išlaidas, bet neįsitikinote. Ką tu darai dabar?

3 modelis - komandos užklausos atsakomybės atskyrimas (CQRS):

Jūs nustatote, kad didelė mašina negali apdoroti visų read/writeužklausų. Be to, daugeliu atvejų bet kuriai įmonei reikalingi sandoriai writedėl readoperacijų, bet ne dėl operacijų. Jums taip pat gerai yra šiek tiek nenuoseklių ar uždelstų readoperacijų, ir jūsų verslas taip pat neturi problemų. Jūs matote galimybę, kur būtų gera parinktis atskirti fizines mašinas readir writeoperacijas. Tai suteiks galimybę atskiroms mašinoms atlikti daugiau read/writeoperacijų.

Dabar paimsite dar dvi dideles mašinas ir nustatysite jas replicapagal dabartinę mašiną. Duomenų bazės replikacija pasirūpins duomenų paskirstymu iš primarymašinų į replicamašinas. Jūs naršote visas perskaitytas užklausas (užklausa ( Q) į CQRS) į kopijas - bet kuri replicagali pateikti bet kokią skaitymo užklausą, jūs naršote visas rašymo užklausas (komanda ( C) į CQRS) primary. Replikacija gali būti mažai atsilikusi, tačiau, atsižvelgiant į jūsų verslo naudojimo atvejį, tai puiku.

Dauguma vidutinio masto startuolių, kurie kasdien aptarnauja kelis šimtus tūkstančių užklausų, gali išgyventi sukūrę pirminę kopiją, jei jie periodiškai archyvuoja senesnius duomenis.

Dabar skalę skirstote į dar 2 miestus, matote, kad primarynegalite apdoroti visų writeužklausų. Daugelis writeužklausų vėluoja. Be to, atsilikimas tarp primaryir replicakartais paveikia klientus ir vairuotojus, kai pasibaigia kelionė, klientas sėkmingai moka vairuotojui, tačiau vairuotojas nemato mokėjimo, nes kliento veikla yra writeprašymas, patenkantis į primary, o vairuotojo veikla yra readprašymas kad eina į vieną iš kopijų. Jūsų sistema yra tokia lėta, kad vairuotojas negali matyti mokėjimo bent pusę minutės - apmaudu tiek vairuotojui, tiek klientui. Kaip tai išspręsti?

4 modelis - daugybinis pirminis replikavimas

Jūs labai gerai pritaikėte primary-replicakonfigūraciją, bet dabar jums reikia daugiau rašymo našumo. Gali būti, kad būsite pasirengę šiek tiek kompromisuoti, jei atliksite readprašymą. Kodėl neišplatinus prašymo rašyti replicataip pat?

Be multi-primarykonfigūracijos, visi aparatai gali dirbti tiek primary& replica. Galite galvoti multi-primaryapie mašinų ratą A->B->C->D->A. Bgali pakartoti duomenis iš A, Cgali pakartoti duomenis iš B, Dgali pakartoti duomenis iš C, Agali pakartoti duomenis iš D. Duomenis galite rašyti į bet kurį mazgą, o skaitydami duomenis galite perduoti užklausą visiems mazgams, kas atsakys, grąžins. Visuose mazguose bus ta pati duomenų bazės schema, tas pats lentelių rinkinys, rodyklė ir kt. Taigi jūs turite įsitikinti, kad idtos pačios lentelės mazguose nėra susidūrimo , kitaip transliavimo metu keli mazgai grąžins skirtingus tos pačios informacijos duomenis id.

Paprastai geriau naudoti UUIDarba GUIDID. Dar vienas šios technikos trūkumas yra tai, kad readužklausos gali būti neefektyvios, nes tai reiškia užklausų transliavimą ir teisingo rezultato gavimą - iš esmės „scatter collect“ metodas.

Dabar jūs padidinsite dar 5 miestus ir jūsų sistemai vėl skaudės. Manoma, kad per sekundę atliksite maždaug 50 užklausų. Jums labai reikia apdoroti daugybę tuo pačiu metu pateiktų užklausų. Kaip to pasiekti?

5 modelis - skaidymas:

Jūs žinote, kad jūsų locationduomenų bazė yra kažkas, kuris tampa didelis writeir readsrautas. Tikriausiai write:readsantykis yra 7:3. Tai daro didelį spaudimą esamoms duomenų bazėms. Į locationlentelėse kelis pirminius duomenis, pavyzdžiui longitude, latitude, timestamp, driver id, trip idir tt Ji neturi daug padaryti su vartotojo kelionėms, naudotojo duomenis, mokėjimo duomenis ir tt Ką apie atskiriant locationstalai atskiroje duomenų bazės? O kaip įdėti tą duomenų bazę į atskiras mašinas su tinkama primary-replicaar multi-primarykonfigūracija?

Tai vadinama duomenų skaidymu pagal funkcionalumą. Įvairi duomenų bazė gali talpinti duomenis, suskirstytus pagal skirtingas funkcijas, jei reikia, rezultatas gali būti kaupiamas galiniame sluoksnyje. Naudodamiesi šia technika, galite sutelkti dėmesį į tų funkcijų, kurios reikalauja didelių read/writeužklausų, mastelį . Nors užpakalinis arba programos sluoksnis turi prisiimti atsakomybę, kad prireikus būtų galima sujungti rezultatus, todėl tikriausiai bus daugiau kodo pakeitimų.

Dabar įsivaizduokite, kad išplėtėte savo verslą iš viso 20 savo šalies miestų ir planuojate netrukus išsiplėsti į Australiją. Didėjančiai programos paklausai reikia vis greitesnio atsakymo. Nė vienas iš aukščiau nurodytų metodų dabar negali jums padėti iki kraštutinumų. Turite išplėsti savo sistemą taip, kad plečiantis į kitas šalis / regionus ne visada reikės dažnai keisti inžinerijos ar architektūros. Kaip tu tai padarai?

6 modelis - horizontalus mastelis:

Jūs daug ieškote „Google“, daug skaitote, kaip kitos įmonės išsprendė šį klausimą - ir priėjote išvadą, kad reikia keisti mastelį horizontaliai. Paskiriate tarkim 50 mašinų - visos turi tą pačią duomenų bazės schemą, kurioje savo ruožtu yra tas pats lentelių rinkinys. Visos mašinos turi tik dalį duomenų.

Kadangi visose duomenų bazėse yra tas pats lentelių rinkinys, sistemą galite suprojektuoti taip, kad ten būtų duomenų lokalizacija, t. visi susiję duomenys patenka į tą pačią mašiną. Kiekviena mašina gali turėti savo kopijas, jos gali būti naudojamos atstatant gedimą. Kiekviena iš duomenų bazių vadinama shard. Fizinė mašina gali turėti vieną ar kelias shards- tai priklauso nuo jūsų dizaino, kaip norite. Turite nuspręsti sharding keytaip, kad vienas sharding keyvisada nurodytų tą pačią mašiną. Taigi galite įsivaizduoti daugybę mašinų, kuriose visi susiję duomenys yra laikomi tame pačiame lentelių rinkinyje, read/writetos pačios eilutės ar tų pačių išteklių rinkinių užklausos tame pačiame duomenų bazės įrenginyje.

Skaldyti apskritai sunku - bent jau tai sako skirtingų kompanijų inžinieriai. Bet kai aptarnaujate milijonus ar milijardus prašymų, turite priimti tokį griežtą sprendimą.

shardingKitame įraše aptarsiu išsamiau, todėl sulaikysiu pagundą plačiau aptarti šiame įraše.

Kadangi jūs turite skaldos vietą, esate įsitikinę, kad galite išplėsti mastelį į daugelį šalių. Jūsų verslas taip išaugo, kad investuotojai verčia jus išplėsti verslą žemynuose. Čia vėl matai kažkokią problemą. API vėlavimas vėl. Jūsų paslauga teikiama JAV, o žmonės iš Vietnamo sunkiai važiuoja knygomis. Kodėl? Ką tu dėl to darai?

7 modelis - duomenų centro išmanusis skaidinys:

Jūsų verslas auga Amerikoje, Pietų Azijoje ir keliose Europos šalyse. Jūs kasdien atliekate milijonus užsakymų, o milijardai užklausų patenka į jūsų serverį. Sveikiname - tai pats didžiausias momentas jūsų verslui.

Bet kadangi programos prašymai turi keliauti per žemynus per šimtus ar tūkstančius interneto serverių, atsiranda vėlavimas. O srauto paskirstymas duomenų centruose? Singapūre galite įsteigti duomenų centrą, kuris tvarkys visas užklausas iš Pietų Azijos, duomenų centras Vokietijoje gali tvarkyti visas užklausas iš Europos šalių, o Kalifornijos duomenų centras gali tvarkyti visas JAV užklausas.

Taip pat įgalinate kryžminio duomenų centro replikavimą, kuris padeda atkurti avariją. Taigi, jei Kalifornijos duomenų centras atkartoja Singapūro duomenų centrą, tuo atveju, jei Kalifornijos duomenų centras sugenda dėl elektros energijos ar natūralios nelaimės, visos JAV užklausos gali grįžti į Singapūro duomenų centrą ir pan.

Ši mastelio keitimo technika yra naudinga, kai turite milijonus klientų, kuriuos reikia aptarnauti visose šalyse, ir negalite sutikti su duomenų praradimu, visada turite išlaikyti sistemos prieinamumą.

Tai yra keletas bendrų žingsnių po žingsnio duomenų bazės mastelio keitimo metodų. Nors dauguma inžinierių neturi pakankamai galimybių įgyvendinti šiuos metodus, tačiau kaip visumą geriau gauti platesnę idėją apie tokią sistemą, kuri ateityje gali padėti geriau suprojektuoti sistemą ir architektūrą.

Kituose savo straipsniuose pabandysiu išsamiai aptarti kai kurias sąvokas. Jei norite, nedvejodami duokite atitinkamų atsiliepimų apie šį įrašą.

Straipsnis iš pradžių buvo paskelbtas vidutinėje autoriaus paskyroje: //medium.com/@kousiknath/understanding-database-scaling-patterns-ac24e5223522