Rohkem arendajaid peaks seda andmebaaside kohta teadma

Märge. tõlge: Jaana Dogan on Google'i kogenud insener, kes tegeleb hetkel Go-s kirjutatud ettevõtte tootmisteenuste jälgitavuse kallal. Selles ingliskeelse publiku seas suure populaarsuse saavutanud artiklis kogus ta 17 punktina kokku olulised tehnilised üksikasjad DBMS-ide (ja mõnikord ka hajutatud süsteemide kohta üldiselt), mida on kasulik kaaluda suurte/nõudlike rakenduste arendajatel.

Rohkem arendajaid peaks seda andmebaaside kohta teadma

Valdav enamus arvutisüsteeme jälgib oma olekut ja nõuab sellest tulenevalt mingit andmesalvestussüsteemi. Kogusin teadmisi andmebaaside kohta pika aja jooksul, tehes selle käigus vigu, mis viisid andmete kadumise ja katkestusteni. Süsteemides, mis töötlevad suuri teabemahtusid, on andmebaasid süsteemi arhitektuuri keskmes ja toimivad võtmeelemendina optimaalse lahenduse valimisel. Vaatamata sellele, et andmebaasi tööle pööratakse suurt tähelepanu, on probleemid, mida rakenduste arendajad püüavad ette näha, sageli vaid jäämäe veepealne osa. Selles artiklite sarjas jagan ideid, mis on kasulikud arendajatele, kes pole sellele valdkonnale spetsialiseerunud.

  1. Teil veab, kui 99,999% juhtudest võrk probleeme ei tekita.
  2. HAPE tähendab palju erinevaid asju.
  3. Igal andmebaasil on oma mehhanismid järjepidevuse ja eraldatuse tagamiseks.
  4. Optimistlik blokeerimine tuleb appi, kui tavapärast on raske säilitada.
  5. Peale räpase lugemise ja andmete kadumise on ka muid kõrvalekaldeid.
  6. Andmebaas ja kasutaja ei ole alati tegevussuunas ühel meelel.
  7. Rakenduse tasemel jagamist saab rakendusest väljapoole teisaldada.
  8. Automaatne suurendamine võib olla ohtlik.
  9. Vananenud andmed võivad olla kasulikud ja neid ei pea lukustama.
  10. Moonutused on tüüpilised mis tahes ajaallikatele.
  11. Viivitusel on palju tähendusi.
  12. Toimivusnõudeid tuleks hinnata konkreetse tehingu puhul.
  13. Pesastatud tehingud võivad olla ohtlikud.
  14. Tehingud ei tohiks olla seotud rakenduse olekuga.
  15. Päringuplaneerijad võivad teile andmebaaside kohta palju öelda.
  16. Interneti-ränne on keeruline, kuid võimalik.
  17. Andmebaasi märkimisväärne suurenemine toob kaasa ettearvamatuse suurenemise.

Tahaksin tänada Emmanuel Odeke, Rein Henrichsi ja teisi tagasiside eest selle artikli varasemale versioonile.

Teil veab, kui 99,999% juhtudest võrk probleeme ei tekita.

Jääb küsimus, kui usaldusväärsed on kaasaegsed võrgutehnoloogiad ja kui sageli on süsteemid võrgutõrgete tõttu maas. Teavet selle küsimuse kohta on vähe ja uurimistöös domineerivad sageli suured organisatsioonid, millel on spetsialiseerunud võrgustikud, seadmed ja personal.

Kuna Spanneri (Google'i ülemaailmselt hajutatud andmebaas) saadavusmäär on 99,999%, väidab Google, et ainult 7,6% probleemid on seotud võrguga. Samal ajal nimetab ettevõte oma spetsialiseeritud võrku kõrge kättesaadavuse "põhisambaks". Uuring Bailis ja Kingsbury, mis viidi läbi 2014. aastal, esitab väljakutse üheleväärarusaamad hajutatud andmetöötluse kohta", mille Peter Deutsch sõnastas 1994. aastal. Kas võrk on tõesti usaldusväärne?

Laiema Interneti jaoks läbiviidud põhjalikud uuringud väljaspool hiiglaslikke ettevõtteid lihtsalt puuduvad. Samuti ei ole suurematelt tegijatelt piisavalt andmeid selle kohta, mitu protsenti nende klientide probleemidest on võrguga seotud. Oleme hästi teadlikud suurte pilveteenuse pakkujate võrguvirna katkestustest, mis võivad terve tüki Internetist mitmeks tunniks maha võtta lihtsalt seetõttu, et tegemist on kõrgetasemeliste sündmustega, mis mõjutavad paljusid inimesi ja ettevõtteid. Võrgukatkestused võivad põhjustada probleeme paljudel juhtudel, isegi kui kõik need juhtumid pole tähelepanu keskpunktis. Ka pilveteenuste kliendid ei tea probleemide põhjustest midagi. Kui esineb rike, on seda peaaegu võimatu seostada teenusepakkujapoolse võrguveaga. Nende jaoks on kolmanda osapoole teenused mustad kastid. Mõju on võimatu hinnata ilma suure teenusepakkujata.

Arvestades seda, mida suured mängijad oma süsteemide kohta teatavad, võib kindlalt öelda, et teil veab, kui võrguprobleemid moodustavad vaid väikese protsendi võimalikest seisakuprobleemidest. Võrguside kannatab endiselt selliste igapäevaste asjade all nagu riistvararikked, topoloogia muutused, halduskonfiguratsiooni muudatused ja elektrikatkestused. Hiljuti sain üllatusena teada, et võimalike probleemide loetelu lisati hai hammustab (jah, sa kuulsid õigesti).

HAPE tähendab palju erinevaid asju

Akronüüm ACID tähistab Atomicity, Consistency, Isolation, Reliability. Need tehingute omadused on mõeldud nende kehtivuse tagamiseks rikete, vigade, riistvaratõrgete jms korral. Ilma ACID-i või sarnaste skeemideta oleks rakenduste arendajatel raske vahet teha, mille eest nad vastutavad ja mille eest andmebaas vastutab. Enamik relatsiooniliste tehingute andmebaase üritab olla ACID-ühilduv, kuid uued lähenemisviisid, nagu NoSQL, on loonud palju andmebaase ilma ACID-tehinguteta, kuna nende rakendamine on kallis.

Kui ma tööstusesse esimest korda sisenesin, rääkis meie tehniline juht sellest, kui asjakohane oli ACID-kontseptsioon. Ausalt öeldes peetakse ACID-d pigem ligikaudseks kirjelduseks kui rangeks rakendusstandardiks. Täna leian, et see on enamasti kasulik, kuna see tõstatab konkreetse kategooria probleeme (ja pakub välja erinevaid võimalikke lahendusi).

Mitte iga DBMS ei ole ACID-ühilduv; Samal ajal mõistavad ACID-i toetavad andmebaasirakendused nõuete kogumit erinevalt. Üks põhjusi, miks ACID-i juurutused on ebaühtlased, on tingitud paljudest kompromissidest, mida ACID-i nõuete rakendamiseks tuleb teha. Loojad võivad esitada oma andmebaase ACID-ühilduvatena, kuid servajuhtumite tõlgendus võib dramaatiliselt erineda, nagu ka "ebatõenäoliste" sündmuste käsitlemise mehhanism. Vähemalt saavad arendajad omandada kõrgetasemelise arusaamise baasrakenduste keerukusest, et saada õige arusaam nende erikäitumisest ja disaini kompromissidest.

Arutelu selle üle, kas MongoDB vastab ACID-i nõuetele, jätkub ka pärast versiooni 4 väljaandmist. MongoDB-d pole pikka aega toetatud metsaraie, kuigi vaikimisi sisestati andmed kettale mitte rohkem kui üks kord 60 sekundi jooksul. Kujutage ette järgmist stsenaariumi: rakendus postitab kaks kirjutist (w1 ja w2). MongoDB salvestab edukalt w1, kuid w2 kaob riistvararikke tõttu.

Rohkem arendajaid peaks seda andmebaaside kohta teadma
Stsenaariumi illustreeriv diagramm. MongoDB jookseb kokku enne, kui suudab andmeid kettale kirjutada

Kettale sidumine on kallis protsess. Vältides sagedasi kohustusi, parandavad arendajad salvestusjõudlust töökindluse arvelt. MongoDB toetab praegu logimist, kuid määrdunud kirjutamine võib siiski mõjutada andmete terviklikkust, kuna logid jäädvustatakse vaikimisi iga 100 ms järel. See tähendab, et logide ja neis esitatud muudatuste puhul on sarnane stsenaarium endiselt võimalik, kuigi risk on palju väiksem.

Igal andmebaasil on oma järjepidevus ja isolatsioonimehhanismid

ACID-i nõuetest on järjepidevus ja isolatsioon kõige rohkem erinevaid rakendusi, kuna kompromisside valik on laiem. Peab ütlema, et järjepidevus ja isolatsioon on üsna kallid funktsioonid. Need nõuavad kooskõlastamist ja suurendavad konkurentsi andmete järjepidevuse nimel. Probleemi keerukus suureneb oluliselt, kui on vaja andmebaasi horisontaalselt skaleerida mitme andmekeskuse vahel (eriti kui need asuvad erinevates geograafilistes piirkondades). Kõrge järjepidevuse saavutamine on väga keeruline, kuna see vähendab ka kättesaadavust ja suurendab võrgu segmenteeritust. Selle nähtuse üldisema selgituse saamiseks soovitan teil viidata CAP teoreem. Samuti väärib märkimist, et rakendused saavad hakkama väikeste ebaühtlustega ning programmeerijad mõistavad probleemi nüansse piisavalt hästi, et rakendada rakenduses täiendavat loogikat ebakõlade käsitlemiseks, ilma et nad selle käsitlemisel andmebaasile väga tugineksid.

DBMS-id pakuvad sageli erinevat isolatsioonitaset. Rakenduste arendajad saavad oma eelistuste põhjal valida kõige tõhusama. Madal isolatsioon võimaldab suurendada kiirust, kuid suurendab ka andmevõistluse ohtu. Kõrge isolatsioon vähendab seda tõenäosust, kuid aeglustab tööd ja võib kaasa tuua konkurentsi, mis toob kaasa sellised pidurid aluses, et algavad tõrked.

Rohkem arendajaid peaks seda andmebaaside kohta teadma
Olemasolevate samaaegsusmudelite ja nendevaheliste suhete ülevaade

SQL-standard määratleb ainult neli isolatsioonitaset, kuigi teoorias ja praktikas on neid palju rohkem. Jepson.io pakub suurepärast ülevaadet olemasolevatest samaaegsusmudelitest. Näiteks Google Spanner garanteerib välise serialiseeritavuse koos kella sünkroonimisega ja kuigi see on rangem isolatsioonikiht, ei ole see standardsetes isolatsioonikihtides määratletud.

SQL-standard mainib järgmisi isolatsioonitasemeid:

  • Serialiseeritav (kõige rangem ja kallim): serialiseeritaval täitmisel on sama mõju kui mõnel järjestikusel tehingute täitmisel. Järjestikune täitmine tähendab, et iga järgmine tehing algab alles pärast eelmise sooritamist. Tuleb märkida, et tase Serialiseeritav tõlgenduserinevuste tõttu rakendatakse seda sageli nn snapshot isolationina (näiteks Oracle'is), kuigi hetktõmmise isoleerimist ennast SQL-standardis ei esindata.
  • Korduv lugemine: praeguse tehingu sidumata kirjed on praegusele tehingule saadaval, kuid muude tehingute tehtud muudatused (nt uued read) pole näha.
  • Lugege pühendunud: sidumata andmed pole tehingute jaoks saadaval. Sel juhul näevad tehingud ainult seotud andmeid ja võib esineda fantoomlugemisi. Kui tehing lisab ja kinnitab uusi ridu, näeb praegune tehing neid päringu korral.
  • Lugege pühendumata (kõige vähem range ja kulukas tase): Lubatud on määrdunud lugemised, tehingud võivad näha muude tehingute poolt tehtud muudatusi. Praktikas võib see tase olla kasulik ligikaudsete hinnangute (nt päringute) jaoks COUNT(*) laua peal.

Tase Serialiseeritav minimeerib andmejooksude riski, olles samal ajal kõige kallim rakendada ja mille tulemuseks on suurim konkurentsikoormus süsteemile. Teisi isolatsioonitasemeid on lihtsam rakendada, kuid see suurendab andmejooksude tõenäosust. Mõned DBMS-id võimaldavad teil määrata kohandatud isolatsioonitaseme, teistel on tugevad eelistused ja kõiki tasemeid ei toetata.

Teatud DBMS-is reklaamitakse sageli isolatsioonitasemete toetust, kuid ainult selle käitumise hoolikas uurimine võib paljastada, mis tegelikult toimub.

Rohkem arendajaid peaks seda andmebaaside kohta teadma
Samaaegsuse anomaaliate ülevaade erinevatel isolatsioonitasemetel erinevatel DBMS-idel

Martin Kleppmann oma projektis Hermitage Võrdleb erinevaid isolatsioonitasemeid, räägib samaaegsuse anomaaliatest ja sellest, kas andmebaas suudab kinni pidada kindlast isolatsioonitasemest. Kleppmanni uurimus näitab, kui erinevalt mõtlevad andmebaasi arendajad isolatsioonitasemetest.

Optimistlik blokeerimine tuleb appi, kui tavapärast on raske säilitada.

Blokeerimine võib olla väga kulukas, mitte ainult seetõttu, et see suurendab konkurentsi andmebaasis, vaid ka seetõttu, et see nõuab rakendusserveritelt pidevat andmebaasiga ühenduse loomist. Võrgu segmenteerimine võib teravdada eksklusiivseid lukustusolukordi ja viia ummikseisuni, mida on raske tuvastada ja lahendada. Juhtudel, kui eksklusiivne lukustus ei sobi, aitab optimistlik lukustus.

Optimistlik lukk on meetod, mille puhul ta võtab stringi lugemisel arvesse selle versiooni, kontrollsummat või viimase muutmise aega. See võimaldab teil enne kirje muutmist tagada, et aatomiversiooni ei muudeta:

UPDATE products
SET name = 'Telegraph receiver', version = 2
WHERE id = 1 AND version = 1

Sel juhul tabeli värskendamine products ei tehta, kui mõni muu toiming on selles real varem muudatusi teinud. Kui sellel real muid toiminguid ei tehtud, toimub ühe rea muudatus ja võib öelda, et värskendamine õnnestus.

Peale räpase lugemise ja andmete kadumise on ka muid kõrvalekaldeid

Andmete järjepidevuse osas keskendutakse võimalikele võistlustingimustele, mis võivad põhjustada määrdunud lugemisi ja andmete kadumist. Andmeanomaaliad ei piirdu aga sellega.

Üks näide sellistest kõrvalekalletest on salvestamise moonutused (kirjutus viltu). Moonutusi on raske tuvastada, kuna neid tavaliselt aktiivselt ei otsita. Need ei ole tingitud määrdunud lugemistest või andmete kadumisest, vaid andmetele seatud loogiliste piirangute rikkumisest.

Näiteks vaatleme seirerakendust, mis nõuab, et üks operaator oleks kogu aeg valves:

BEGIN tx1;                      BEGIN tx2;
SELECT COUNT(*)
FROM operators
WHERE oncall = true;
0                               SELECT COUNT(*)
                                FROM operators
                                WHERE oncall = TRUE;
                                0
UPDATE operators                UPDATE operators
SET oncall = TRUE               SET oncall = TRUE
WHERE userId = 4;               WHERE userId = 2;
COMMIT tx1;                     COMMIT tx2;

Ülaltoodud olukorras tekib rekordkorruptsioon, kui mõlemad tehingud on edukalt sooritatud. Kuigi määrdunud lugemisi ega andmete kadumist ei esinenud, oli andmete terviklikkus ohus: nüüd loetakse kaks inimest korraga valves olevaks.

Serialiseeritav isoleerimine, skeemi kujundamine või andmebaasipiirangud võivad aidata kirjutuskahjustusi kõrvaldada. Arendajad peavad suutma sellised kõrvalekalded arenduse käigus tuvastada, et neid tootmises vältida. Samas on salvestusmoonutusi koodibaasist äärmiselt keeruline otsida. Eriti suurtes süsteemides, kui erinevad arendusmeeskonnad vastutavad samade tabelite alusel funktsioonide juurutamise eest ega lepi kokku andmetele juurdepääsu spetsiifikas.

Andmebaas ja kasutaja ei ole alati ühel meelel, mida teha

Andmebaaside üks põhiomadusi on täitmiskorralduse garantii, kuid see tellimus ise ei pruugi olla tarkvaraarendaja jaoks läbipaistev. Andmebaasid teostavad tehinguid nende laekumise järjekorras, mitte programmeerijate kavandatud järjekorras. Tehingute järjekorda on raske ennustada, eriti suure koormusega paralleelsüsteemides.

Arendamise ajal, eriti mitteblokeerivate raamatukogudega töötades, võib halb stiil ja vähene loetavus panna kasutajad uskuma, et tehinguid teostatakse järjestikku, kuigi tegelikult võivad need jõuda andmebaasi suvalises järjekorras.

Esmapilgul kutsutakse allolevas programmis T1 ja T2 järjestikku, kuid kui need funktsioonid ei blokeeri ja tagastavad tulemuse kohe kujul lubadus, siis määratakse kõnede järjekord nende andmebaasi sisenemise hetkede järgi:

tulemus1 = T1() // tegelikud tulemused on lubadused
tulemus2 = T2()

Kui on vaja aatomilisust (st kõik toimingud tuleb lõpetada või katkestada) ja järjestus on oluline, tuleb toimingud T1 ja T2 sooritada ühe tehinguga.

Rakenduse tasemel jagamist saab rakendusest väljapoole teisaldada

Jagamine on meetod andmebaasi horisontaalseks jaotamiseks. Mõned andmebaasid suudavad andmeid automaatselt horisontaalselt poolitada, samas kui teised ei saa või ei ole selles väga head. Kui andmearhitektid/arendajad suudavad täpselt ennustada, kuidas andmetele ligi pääsetakse, saavad nad selle töö andmebaasile delegeerimise asemel luua kasutajaruumis horisontaalsed partitsioonid. Seda protsessi nimetatakse "rakenduse tasemel jagamiseks" (rakenduse tasemel jagamine).

Kahjuks tekitab see nimi sageli eksiarvamuse, et sharding elab rakendusteenustes. Tegelikult saab seda rakendada eraldi kihina andmebaasi ees. Sõltuvalt andmete kasvust ja skeemi iteratsioonidest võivad jagamisnõuded muutuda üsna keerukaks. Mõned strateegiad võivad kasu saada võimalusest itereerida ilma rakendusservereid ümber paigutamata.

Rohkem arendajaid peaks seda andmebaaside kohta teadma
Näide arhitektuurist, milles rakendusserverid on jagamisteenusest eraldatud

Jaotuse teisaldamine eraldi teenusesse laiendab võimalust kasutada erinevaid jagamisstrateegiaid, ilma et oleks vaja rakendusi ümber paigutada. Vitess on näide sellisest jagamissüsteemist rakenduse tasemel. Vitess pakub MySQL-i horisontaalset jaotust ja võimaldab klientidel sellega MySQL-protokolli kaudu ühenduse luua. Süsteem segmenteerib andmed erinevatesse MySQL-i sõlmedesse, mis ei tea üksteisest midagi.

Automaatne suurendamine võib olla ohtlik

AUTOMAATNE KASUTAMINE on tavaline viis primaarvõtmete genereerimiseks. Sageli on juhtumeid, kus ID-generaatoritena kasutatakse andmebaase ja andmebaas sisaldab identifikaatorite genereerimiseks mõeldud tabeleid. On mitmeid põhjuseid, miks primaarvõtmete genereerimine automaatse suurendamise abil pole kaugeltki ideaalne:

  • Hajutatud andmebaasis on automaatne suurendamine tõsine probleem. ID genereerimiseks on vaja globaalset lukku. Selle asemel saate luua UUID-i: see ei nõua erinevate andmebaasisõlmede vahelist suhtlust. Lukkudega automaatne suurendamine võib hajutatud olukordades põhjustada tülisid ja oluliselt vähendada sisendite jõudlust. Mõned DBMS-id (nt MySQL) võivad vajada spetsiaalset konfigureerimist ja hoolikamat tähelepanu, et ülem-ülemine replikatsioon õigesti korraldada. Ja konfigureerimisel on lihtne teha vigu, mis põhjustavad salvestamisel tõrkeid.
  • Mõnel andmebaasil on primaarvõtmetel põhinevad partitsioonialgoritmid. Järjestikused ID-d võivad põhjustada ettearvamatuid levialasid ja suurendada mõne partitsiooni koormust, samas kui teised jäävad jõude.
  • Primaarvõti on kiireim viis andmebaasi reale juurde pääseda. Kirjete tuvastamise paremate viisidega võivad järjestikused ID-d muuta tabelite kõige olulisema veeru kasutuks veeruks, mis on täidetud mõttetute väärtustega. Seetõttu valige võimaluse korral globaalselt unikaalne ja loomulik primaarvõti (nt kasutajanimi).

Enne lähenemise otsustamist kaaluge ID-de ja UUID-de automaatse suurendamise mõju indekseerimisele, partitsioonidele ja jagamisele.

Vananenud andmed võivad olla kasulikud ega vaja lukustamist

Multiversioon Concurrency Control (MVCC) rakendab paljusid järjepidevuse nõudeid, millest oli lühidalt eespool juttu. Mõned andmebaasid (nt Postgres, Spanner) kasutavad MVCC-d tehingute "toitmiseks" hetktõmmistega – andmebaasi vanemate versioonidega. Snapshot tehinguid saab ka järjepidevuse tagamiseks järjestada. Vanast hetktõmmisest lugemisel loetakse aegunud andmeid.

Veidi aegunud andmete lugemine võib olla kasulik näiteks andmete põhjal analüütika genereerimisel või ligikaudsete koondväärtuste arvutamisel.

Pärandandmetega töötamise esimene eelis on madal latentsusaeg (eriti kui andmebaas on jaotatud erinevates geograafilistes piirkondades). Teine on see, et kirjutuskaitstud tehingud on lukuvabad. See on märkimisväärne eelis rakenduste jaoks, mis loevad palju, kui nad saavad hakkama aegunud andmetega.

Rohkem arendajaid peaks seda andmebaaside kohta teadma
Rakenduseserver loeb andmeid kohalikust koopiast, mis on 5 sekundit aegunud, isegi kui uusim versioon on saadaval teisel pool Vaikst ookeani

DBMS-id puhastavad automaatselt vanemad versioonid ja mõnel juhul võimaldavad teil seda nõudmisel teha. Näiteks Postgres võimaldab kasutajatel seda teha VACUUM nõudmisel ja teeb seda toimingut ka perioodiliselt automaatselt. Spanner juhib prügikogujat, et vabaneda üle ühe tunni vanustest piltidest.

Kõik ajaallikad võivad olla moonutatud

Arvutiteaduse kõige paremini hoitud saladus on see, et kõik ajastuse API-d valetavad. Tegelikult ei tea meie masinad täpset praegust aega. Arvutid sisaldavad kvartskristalle, mis tekitavad vibratsiooni, mida kasutatakse aja hoidmiseks. Need pole aga piisavalt täpsed ja võivad täpsest ajast ees/maha jääda. Vahetus võib ulatuda 20 sekundini päevas. Seetõttu tuleb meie arvutites olevat aega perioodiliselt võrguga sünkroonida.

Sünkroonimiseks kasutatakse NTP-servereid, kuid sünkroonimisprotsess ise on seotud võrguviivitustega. Isegi samas andmekeskuses oleva NTP-serveriga sünkroonimine võtab veidi aega. On selge, et avaliku NTP-serveriga töötamine võib põhjustada veelgi suuremaid moonutusi.

Praeguse kellaaja määramiseks sobivad paremini aatomkellad ja nende GPS-i analoogid, kuid need on kallid ja nõuavad keerukat seadistamist, mistõttu ei saa neid igale autole paigaldada. Seetõttu kasutavad andmekeskused mitmetasandilist lähenemist. Aatom- ja/või GPS-kellad näitavad täpset kellaaega, mille järel edastatakse see sekundaarsete serverite kaudu teistele masinatele. See tähendab, et igal masinal on teatud nihe täpsest ajast.

Olukorda raskendab asjaolu, et rakendused ja andmebaasid asuvad sageli erinevates masinates (kui mitte erinevates andmekeskustes). Seega ei erine aeg mitte ainult erinevate masinate vahel jaotatud DB-sõlmedes. See on erinev ka rakendusserveris.

Google TrueTime kasutab täiesti teistsugust lähenemist. Enamik inimesi usub, et Google'i edu selles suunas on seletatav banaalse üleminekuga aatom- ja GPS-kelladele, kuid see on vaid osa suurest pildist. TrueTime töötab järgmiselt.

  • TrueTime kasutab kahte erinevat allikat: GPS-i ja aatomkellasid. Nendel kelladel on mittekorreleeruvad rikkerežiimid. [üksikasju vt lk 5 siin - u. tõlge.), mistõttu nende ühine kasutamine suurendab töökindlust.
  • TrueTime'il on ebatavaline API. See tagastab aja intervallina, millesse on sisse ehitatud mõõtmisviga ja ebakindlus. Tegelik ajahetk on kuskil intervalli ülemise ja alumise piiri vahel. Google'i hajutatud andmebaas Spanner lihtsalt ootab, kuni võib kindlalt väita, et praegune kellaaeg on vahemikust väljas. See meetod lisab süsteemi teatud latentsusaega, eriti kui määramatus masteritel on suur, kuid tagab korrektsuse ka globaalselt hajutatud olukorras.

Rohkem arendajaid peaks seda andmebaaside kohta teadma
Mutrivõtme komponendid kasutavad TrueTime'i, kus TT.now() tagastab intervalli, nii et mutrivõti lihtsalt magab hetkeni, mil võib olla kindel, et praegune aeg on teatud punktist möödas.

Praeguse aja määramise täpsuse vähenemine tähendab mutrivõtme toimingute kestuse pikenemist ja jõudluse vähenemist. Seetõttu on oluline säilitada võimalikult suur täpsus, isegi kui täiesti täpset kella pole võimalik saada.

Viivitusel on palju tähendusi

Kui küsite kümnekonnalt eksperdilt, mis on hilinemine, saate tõenäoliselt erinevaid vastuseid. DBMS-is nimetatakse latentsust sageli "andmebaasi latentsusajaks" ja see erineb kliendi tajutavast. Fakt on see, et klient jälgib võrgu viivituse ja andmebaasi viivituse summat. Võimalus eristada latentsusaega on kasvavate probleemide silumisel kriitilise tähtsusega. Mõõdikute kogumisel ja kuvamisel püüdke alati mõlemal tüübil silma peal hoida.

Toimivusnõudeid tuleks hinnata konkreetse tehingu puhul

Mõnikord on DBMS-i jõudlusnäitajad ja selle piirangud täpsustatud kirjutamise/lugemise läbilaskevõime ja latentsusaega. See annab üldise ülevaate peamistest süsteemiparameetritest, kuid uue DBMS-i jõudluse hindamisel on palju põhjalikum lähenemine kriitiliste toimingute eraldi hindamine (iga päringu ja/või tehingu kohta). Näited:

  • Kirjutage läbilaskevõime ja latentsus, kui sisestate tabelisse X uue rea (50 miljoni reaga) koos määratud piirangute ja ridade täidisega seotud tabelites.
  • Teatud kasutaja sõprade sõprade kuvamise viivitus, kui keskmine sõprade arv on 500.
  • Viiteaeg kasutaja ajaloost 100 populaarseima kirje hankimisel, kui kasutaja jälgib 500 teist kasutajat X kirjega tunnis.

Hindamine ja katsetamine võivad hõlmata selliseid kriitilisi juhtumeid, kuni olete kindel, et andmebaas vastab jõudlusnõuetele. Sarnane rusikareegel võtab seda jaotust arvesse ka latentsusmõõdikute kogumisel ja SLO-de määramisel.

Iga toimingu kohta mõõdikute kogumisel pidage meeles suurt kardinaalsust. Kasutage suure võimsusega silumisandmete saamiseks logisid, sündmuste kogumist või hajutatud jälgimist. Artiklis "Kas soovite latentsust siluda?» saate end kurssi viia viitsilumise metoodikatega.

Pesastatud tehingud võivad olla ohtlikud

Mitte kõik DBMS-id ei toeta pesastatud tehinguid, kuid kui need toetavad, võivad sellised tehingud põhjustada ootamatuid vigu, mida pole alati lihtne tuvastada (st peaks olema ilmne, et tegemist on mingi anomaaliaga).

Saate vältida pesastatud tehingute kasutamist, kasutades klienditeeke, mis suudavad neid tuvastada ja neist mööda minna. Kui pesastatud tehingutest ei saa loobuda, olge nende rakendamisel eriti ettevaatlik, et vältida ootamatuid olukordi, kus lõpetatud tehingud katkevad kogemata pesastatud tehingute tõttu.

Tehingute kapseldamine erinevatesse kihtidesse võib põhjustada ootamatuid pesastatud tehinguid ning koodi loetavuse seisukohalt võib see raskendada autori kavatsuste mõistmist. Heitke pilk järgmisele programmile:

with newTransaction():
   Accounts.create("609-543-222")
   with newTransaction():
       Accounts.create("775-988-322")
       throw Rollback();

Mis on ülaltoodud koodi väljund? Kas see tühistab mõlemad tehingud või ainult sisemise? Mis juhtub, kui toetume mitmele teegikihile, mis kapseldavad meie jaoks tehingute loomise? Kas suudame selliseid juhtumeid tuvastada ja parandada?

Kujutage ette mitme toiminguga andmekihti (nt. newAccount) on tema enda tehingutes juba rakendatud. Mis juhtub, kui käivitate need osana kõrgema taseme äriloogikast, mis töötab oma tehingu raames? Milline oleks sel juhul eraldatus ja järjepidevus?

function newAccount(id string) {
  with newTransaction():
      Accounts.create(id)
}

Selle asemel, et sellistele lõpututele küsimustele vastuseid otsida, on parem vältida pesastatud tehinguid. Lõppude lõpuks saab teie andmekiht hõlpsasti teostada kõrgetasemelisi toiminguid ilma oma tehinguid loomata. Lisaks on äriloogika ise võimeline tehingut algatama, sellega toiminguid tegema, tehingut sooritama või katkestama.

function newAccount(id string) {
   Accounts.create(id)
}
// In main application:
with newTransaction():
   // Read some data from database for configuration.
   // Generate an ID from the ID service.
   Accounts.create(id)
   Uploads.create(id) // create upload queue for the user.

Tehingud ei tohiks olla seotud rakenduse olekuga

Mõnikord on kiusatus teatud väärtuste muutmiseks või päringu parameetrite muutmiseks kasutada tehingutes rakenduse olekut. Kriitiline nüanss, mida tuleb arvesse võtta, on õige kohaldamisala. Sageli taaskäivitavad kliendid võrguprobleemide korral tehinguid. Kui tehing sõltub olekust, mida mõni muu protsess muudab, võib see sõltuvalt andmejooksu võimalusest valida vale väärtuse. Tehingute tegemisel tuleb rakenduses arvestada andmevõistluse tingimustega seotud riskiga.

var seq int64
with newTransaction():
    newSeq := atomic.Increment(&seq)
    Entries.query(newSeq)
    // Other operations...

Ülaltoodud tehing suurendab järjenumbrit iga kord, kui see sooritatakse, olenemata lõpptulemusest. Kui sidumine ebaõnnestub võrguprobleemide tõttu, täidetakse uuesti proovimisel taotlus teise järjenumbriga.

Päringuplaneerijad võivad teile andmebaasi kohta palju öelda

Päringuplaneerijad määravad, kuidas päring andmebaasis täidetakse. Samuti analüüsivad nad taotlusi ja optimeerivad neid enne saatmist. Planeerijad saavad nende käsutuses olevate signaalide põhjal esitada vaid mõned võimalikud hinnangud. Näiteks milline on parim otsingumeetod järgmise päringu jaoks?

SELECT * FROM articles where author = "rakyll" order by title;

Tulemusi saab hankida kahel viisil:

  • Täielik tabeli skaneerimine: saate vaadata iga tabeli kirjet ja tagastada artikleid sobiva autorinimega ning seejärel tellida.
  • Indeksi skannimine: Saate kasutada indeksit sobivate ID-de leidmiseks, nende ridade hankimiseks ja seejärel järjestamiseks.

Päringuplaneerija ülesanne on kindlaks teha, milline strateegia on parim. Tasub arvestada, et päringuplaneerijatel on ainult piiratud ennustamisvõimalused. See võib viia halbade otsusteni. DBA-d või arendajad saavad neid kasutada kehvasti toimivate päringute diagnoosimiseks ja täpsustamiseks. DBMS-i uued versioonid võivad konfigureerida päringuplaneerijaid ja enesediagnostika võib aidata andmebaasi värskendamisel, kui uus versioon põhjustab jõudlusprobleeme. Aeglased päringulogid, latentsusprobleemide aruanded või täitmisaja statistika võivad aidata tuvastada optimeerimist vajavaid päringuid.

Mõned päringuplaneerija esitatud mõõdikud võivad olla müra all (eriti latentsusaja või protsessori aja hindamisel). Hea täiendus ajakavadele on täitmistee jälgimise ja jälgimise tööriistad. Need võimaldavad teil selliseid probleeme diagnoosida (paraku ei paku kõik DBMS-id selliseid tööriistu).

Interneti-ränne on keeruline, kuid võimalik

Veebimigratsioon, reaalajas migratsioon või reaalajas migratsioon tähendab liikumist ühest andmebaasist teise ilma seisakute või andmete kahjustamiseta. Reaalajas migratsiooni on lihtsam teostada, kui üleminek toimub samas DBMS-is/mootoris. Olukord muutub keerulisemaks, kui on vaja üle minna uuele DBMS-ile, millel on erinevad jõudlus- ja skeeminõuded.

Internetis on erinevaid migratsioonimudeleid. Siin on üks neist:

  • Luba kahekordne sisestus mõlemas andmebaasis. Uues andmebaasis ei ole praeguses etapis kõiki andmeid, vaid see aktsepteerib ainult uusimaid andmeid. Kui olete selles kindel, võite liikuda järgmise sammu juurde.
  • Luba lugemine mõlemast andmebaasist.
  • Seadistage süsteem nii, et lugemine ja kirjutamine toimuks peamiselt uues andmebaasis.
  • Lõpetage vanasse andmebaasi kirjutamine ja jätkake sealt andmete lugemist. Praeguses etapis on uues andmebaasis veel mõned andmed puudu. Need tuleks kopeerida vanast andmebaasist.
  • Vana andmebaas on kirjutuskaitstud. Kopeerige puuduvad andmed vanast andmebaasist uude. Kui migratsioon on lõppenud, lülitage teed uude andmebaasi, peatage vana ja kustutage see süsteemist.

Lisainfo saamiseks soovitan ühendust võtta siit, mis kirjeldab Stripe'i sellel mudelil põhinevat migratsioonistrateegiat.

Andmebaasi märkimisväärne suurenemine toob kaasa ettearvamatuse suurenemise

Andmebaasi kasv toob kaasa selle ulatusega seotud ettearvamatuid probleeme. Mida rohkem me teame andmebaasi sisemisest struktuurist, seda paremini saame ennustada, kuidas see skaleerub. Mõnda hetke on siiski võimatu ette näha.
Baasi kasvades võivad varasemad oletused ja ootused andmemahu ja võrgu ribalaiuse nõuete kohta vananeda. See on siis, kui võimalike probleemide vältimiseks kerkib üles küsimus suurtest konstruktsiooni ümberehitustest, suuremahulistest töötäiustustest, juurutuste ümbermõtestamisest või migratsioonist teistele DBMS-idele.

Kuid ärge arvake, et olemasoleva andmebaasi sisemise struktuuri suurepärane tundmine on ainus asi, mis on vajalik. Uued kaalud toovad endaga kaasa uusi tundmatuid. Ettearvamatud valupunktid, ebaühtlane andmete jaotus, ootamatud ribalaiuse ja riistvaraprobleemid, pidevalt kasvav liiklus ja uued võrgusegmendid sunnivad teid oma andmebaasi lähenemisviisi, andmemudelit, juurutusmudelit ja andmebaasi suurust uuesti läbi mõtlema.

...

Kui ma selle artikli avaldamise peale mõtlema hakkasin, oli minu algses loendis juba viis üksust. Siis tuli tohutu arv uusi ideid selle kohta, mida veel saab katta. Seetõttu puudutab artikkel kõige vähem ilmselgeid probleeme, mis nõuavad maksimaalset tähelepanu. See aga ei tähenda, et teema oleks ammendunud ja ma oma tulevastes materjalides selle juurde enam ei pöördu ega tee praeguses muudatusi.

PS

Loe ka meie blogist:

Allikas: www.habr.com

Lisa kommentaar