Meer ontwikkelaars behoort dit oor databasisse te weet

Let wel. vertaal.: Jaana Dogan is 'n ervare ingenieur by Google wat tans werk aan waarneembaarheid van die maatskappy se produksiedienste wat in Go geskryf is. In hierdie artikel, wat groot gewildheid onder die Engelssprekende gehoor verwerf het, het sy in 17 punte belangrike tegniese besonderhede versamel rakende DBBS'e (en soms verspreide stelsels in die algemeen) wat nuttig is om te oorweeg vir ontwikkelaars van groot/veeleisende toepassings.

Meer ontwikkelaars behoort dit oor databasisse te weet

Die oorgrote meerderheid rekenaarstelsels hou tred met hul toestand en vereis gevolglik 'n soort databergingstelsel. Ek het oor 'n lang tydperk kennis oor databasisse opgedoen, langs die pad ontwerpfoute gemaak wat gelei het tot dataverlies en onderbrekings. In stelsels wat groot volumes inligting verwerk, lê databasisse in die hart van die stelselargitektuur en dien dit as 'n sleutelelement in die keuse van die optimale oplossing. Ten spyte van die feit dat baie aandag aan die werk van die databasis gegee word, is die probleme wat toepassingsontwikkelaars probeer voorsien, dikwels net die punt van die ysberg. In hierdie reeks artikels deel ek 'n paar idees wat nuttig sal wees vir ontwikkelaars wat nie in hierdie veld gespesialiseer is nie.

  1. Jy is gelukkig as die netwerk 99,999% van die tyd nie probleme veroorsaak nie.
  2. SUUR beteken baie verskillende dinge.
  3. Elke databasis het sy eie meganismes om konsekwentheid en isolasie te verseker.
  4. Optimistiese blokkering kom tot die redding wanneer dit moeilik is om die gewone een te handhaaf.
  5. Daar is ander afwykings behalwe vuil leeswerk en dataverlies.
  6. Die databasis en die gebruiker stem nie altyd saam oor die optrede nie.
  7. Skerwing op toepassingsvlak kan buite die toepassing geskuif word.
  8. Outo-inkrementering kan gevaarlik wees.
  9. Ou data kan nuttig wees en hoef nie gesluit te word nie.
  10. Vervormings is tipies vir enige tydbronne.
  11. Vertraging het baie betekenisse.
  12. Prestasievereistes moet vir 'n spesifieke transaksie geëvalueer word.
  13. Geneste transaksies kan gevaarlik wees.
  14. Transaksies moet nie gekoppel wees aan aansoekstaat nie.
  15. Navraagbeplanners kan jou baie vertel oor databasisse.
  16. Aanlyn migrasie is moeilik, maar moontlik.
  17. 'n Beduidende toename in die databasis behels 'n toename in onvoorspelbaarheid.

Ek wil graag vir Emmanuel Odeke, Rein Henrichs en andere bedank vir hul terugvoer oor 'n vorige weergawe van hierdie artikel.

Jy is gelukkig as die netwerk 99,999% van die tyd nie probleme veroorsaak nie.

Die vraag bly oor hoe betroubaar moderne netwerktegnologieë is en hoe gereeld stelsels af is as gevolg van netwerkfoute. Inligting oor hierdie kwessie is skaars en navorsing word dikwels oorheers deur groot organisasies met gespesialiseerde netwerke, toerusting en personeel.

Met 'n beskikbaarheidskoers van 99,999% vir Spanner (Google se wêreldwyd verspreide databasis), beweer Google dat slegs 7,6% probleme hou verband met die netwerk. Terselfdertyd noem die maatskappy sy gespesialiseerde netwerk die "hoofpilaar" van hoë beskikbaarheid. Studie Bailis en Kingsbury, wat in 2014 uitgevoer is, daag een van die “wanopvattings oor verspreide rekenaars", wat Peter Deutsch in 1994 geformuleer het. Is die netwerk regtig betroubaar?

Omvattende navorsing buite reuse-maatskappye, wat vir die breër internet gedoen is, bestaan ​​eenvoudig nie. Daar is ook nie genoeg data van die groot rolspelers oor watter persentasie van hul kliënte se probleme netwerkverwant is nie. Ons is deeglik bewus van onderbrekings in die netwerkstapel van groot wolkverskaffers wat 'n hele deel van die internet vir etlike ure kan afneem bloot omdat dit hoëprofielgebeurtenisse is wat 'n groot aantal mense en maatskappye raak. Netwerkonderbrekings kan in baie meer gevalle probleme veroorsaak, selfs al is nie al daardie gevalle in die kollig nie. Kliënte van wolkdienste weet ook niks van die oorsake van probleme nie. As daar 'n mislukking is, is dit byna onmoontlik om dit toe te skryf aan 'n netwerkfout aan die diensverskaffer se kant. Vir hulle is derdepartydienste swart bokse. Dit is onmoontlik om die impak te bepaal sonder om 'n groot diensverskaffer te wees.

Gegewe wat die groot spelers oor hul stelsels rapporteer, is dit veilig om te sê jy is gelukkig as netwerkprobleme slegs 'n klein persentasie van potensiële stilstandprobleme uitmaak. Netwerkkommunikasie ly steeds onder alledaagse dinge soos hardewarefoute, topologieveranderings, administratiewe konfigurasieveranderinge en kragonderbrekings. Onlangs was ek verbaas om te hoor dat die lys van moontlike probleme bygevoeg is haaibyte (ja, jy het reg gehoor).

SUUR beteken baie verskillende dinge

Die akroniem ACID staan ​​vir Atomicity, Consistency, Isolation, Reliability. Hierdie eienskappe van transaksies is bedoel om hul geldigheid te verseker in die geval van mislukkings, foute, hardeware mislukkings, ens. Sonder ACID of soortgelyke skemas sal dit moeilik wees vir toepassingsontwikkelaars om te onderskei tussen waarvoor hulle verantwoordelik is en waarvoor die databasis verantwoordelik is. Die meeste relasionele transaksionele databasisse probeer om aan ACID te voldoen, maar nuwe benaderings soos NoSQL het aanleiding gegee tot baie databasisse sonder ACID-transaksies omdat dit duur is om te implementeer.

Toe ek die eerste keer die bedryf betree het, het ons tegniese hoof gepraat oor hoe relevant die ACID-konsep was. Om regverdig te wees, word ACID as 'n rowwe beskrywing eerder as 'n streng implementeringstandaard beskou. Vandag vind ek dit meestal nuttig omdat dit 'n spesifieke kategorie kwessies opper (en 'n reeks moontlike oplossings voorstel).

Nie elke DBBS voldoen aan ACID nie; Terselfdertyd verstaan ​​databasisimplementerings wat ACID ondersteun die stel vereistes anders. Een van die redes waarom ACID-implementerings onduidelik is, is as gevolg van die baie afwegings wat gemaak moet word om ACID-vereistes te implementeer. Skeppers kan hul databasisse as ACID-geskik aanbied, maar die interpretasie van randgevalle kan dramaties verskil, asook die meganisme vir die hantering van "onwaarskynlike" gebeurtenisse. Ontwikkelaars kan ten minste 'n hoëvlakbegrip kry van die ingewikkeldhede van basisimplementerings om 'n behoorlike begrip van hul spesiale gedrag en ontwerp-afwegings te kry.

Die debat oor of MongoDB aan ACID-vereistes voldoen, duur voort selfs ná die vrystelling van weergawe 4. MongoDB word vir 'n lang tyd nie ondersteun nie aanteken, hoewel data by verstek nie meer as een keer elke 60 sekondes op skyf toegewy is nie. Stel jou die volgende scenario voor: 'n aansoek plaas twee skrywes (w1 en w2). MongoDB stoor w1 suksesvol, maar w2 gaan verlore as gevolg van 'n hardewarefout.

Meer ontwikkelaars behoort dit oor databasisse te weet
Diagram wat die scenario illustreer. MongoDB crash voordat dit data na skyf kan skryf

Om tot skyf te verbind is 'n duur proses. Deur gereelde verbintenisse te vermy, verbeter ontwikkelaars opnameprestasie ten koste van betroubaarheid. MongoDB ondersteun tans aanteken, maar vuil skryfwerk kan steeds data-integriteit beïnvloed, aangesien logs by verstek elke 100 ms vasgelê word. Dit wil sê, 'n soortgelyke scenario is steeds moontlik vir logs en die veranderinge wat daarin aangebied word, hoewel die risiko baie laer is.

Elke databasis het sy eie konsekwentheid en isolasiemeganismes

Van die ACID-vereistes spog konsekwentheid en isolasie met die grootste aantal verskillende implementerings omdat die reeks afwykings wyer is. Daar moet gesê word dat konsekwentheid en isolasie redelik duur funksies is. Hulle vereis koördinasie en verhoog mededinging vir datakonsekwentheid. Die kompleksiteit van die probleem neem aansienlik toe wanneer dit nodig is om die databasis horisontaal oor verskeie datasentrums te skaal (veral as hulle in verskillende geografiese streke geleë is). Dit is baie moeilik om 'n hoë vlak van konsekwentheid te bereik, aangesien dit ook beskikbaarheid verminder en netwerksegmentering verhoog. Vir 'n meer algemene verduideliking van hierdie verskynsel raai ek jou aan om na te verwys CAP-stelling. Dit is ook opmerklik dat toepassings klein hoeveelhede inkonsekwentheid kan hanteer, en programmeerders kan die nuanses van die probleem goed genoeg verstaan ​​om bykomende logika in die toepassing te implementeer om inkonsekwentheid te hanteer sonder om swaar op die databasis staat te maak om dit te hanteer.

DBBS'e bied dikwels verskillende vlakke van isolasie. Toepassingsontwikkelaars kan die mees doeltreffende een kies op grond van hul voorkeure. Lae isolasie maak voorsiening vir verhoogde spoed, maar verhoog ook die risiko van 'n datawedloop. Hoë isolasie verminder hierdie waarskynlikheid, maar vertraag werk en kan lei tot mededinging, wat sal lei tot sulke remme in die basis dat mislukkings begin.

Meer ontwikkelaars behoort dit oor databasisse te weet
Hersiening van bestaande sameloopmodelle en verwantskappe tussen hulle

Die SQL-standaard definieer slegs vier isolasievlakke, hoewel daar in teorie en praktyk baie meer is. Jepson.io bied 'n uitstekende oorsig van bestaande gelyktydige modelle. Byvoorbeeld, Google Spanner waarborg eksterne serialiseerbaarheid met kloksinchronisasie, en hoewel dit 'n strenger isolasielaag is, word dit nie in standaard isolasielae gedefinieer nie.

Die SQL-standaard noem die volgende isolasievlakke:

  • serialiseerbaar (strengste en duurste): Serialiseerbare uitvoering het dieselfde effek as sommige opeenvolgende transaksie-uitvoering. Opeenvolgende uitvoering beteken dat elke daaropvolgende transaksie eers begin nadat die vorige een voltooi is. Daar moet kennis geneem word dat die vlak serialiseerbaar dikwels geïmplementeer as sogenaamde momentopname-isolasie (byvoorbeeld in Oracle) as gevolg van verskille in interpretasie, hoewel momentopname-isolasie self nie in die SQL-standaard verteenwoordig word nie.
  • Herhaalbare leeswerk: Onverbonde rekords in die huidige transaksie is beskikbaar vir die huidige transaksie, maar veranderinge gemaak deur ander transaksies (soos nuwe rye) nie sigbaar nie.
  • Lees toegewyd: Onverbonde data is nie beskikbaar vir transaksies nie. In hierdie geval kan transaksies slegs toegewyde data sien, en fantoomlesings kan voorkom. As 'n transaksie nuwe rye invoeg en verbind, sal die huidige transaksie dit kan sien wanneer navraag gedoen word.
  • Lees onverbonde (mins streng en duur vlak): Vuillesings word toegelaat, transaksies kan onverbonde veranderinge sien wat deur ander transaksies gemaak is. In die praktyk kan hierdie vlak nuttig wees vir rowwe skattings, soos navrae COUNT(*) op die tafel.

Vlak serialiseerbaar verminder die risiko van dataresies, terwyl dit die duurste is om te implementeer en die hoogste mededingende las op die stelsel tot gevolg het. Ander isolasievlakke is makliker om te implementeer, maar verhoog die waarskynlikheid van dataresies. Sommige DBBS'e laat jou toe om 'n pasgemaakte isolasievlak te stel, ander het sterk voorkeure en nie alle vlakke word ondersteun nie.

Ondersteuning vir isolasievlakke word dikwels in 'n gegewe DBBS geadverteer, maar slegs 'n noukeurige studie van die gedrag daarvan kan onthul wat werklik aan die gebeur is.

Meer ontwikkelaars behoort dit oor databasisse te weet
Hersiening van gelyktydige anomalieë op verskillende isolasievlakke vir verskillende DBBS'e

Martin Kleppmann in sy projek Hermitage Vergelyk verskillende isolasievlakke, praat oor gelyktydige afwykings en of die databasis in staat is om aan 'n bepaalde isolasievlak te voldoen. Kleppmann se navorsing wys hoe verskillend databasisontwikkelaars oor isolasievlakke dink.

Optimistiese blokkering kom tot die redding wanneer dit moeilik is om die gewone een te handhaaf.

Blokkering kan baie duur wees, nie net omdat dit mededinging in die databasis verhoog nie, maar ook omdat dit vereis dat die toepassingsbedieners voortdurend aan die databasis koppel. Netwerksegmentering kan eksklusiewe sluitsituasies vererger en lei tot dooiepunte wat moeilik is om te identifiseer en op te los. In gevalle waar eksklusiewe sluiting nie geskik is nie, help optimistiese sluiting.

Optimistiese slot is 'n metode waarin wanneer 'n string gelees word, dit die weergawe, kontrolesom of tyd van laaste wysiging in ag neem. Dit laat jou toe om te verseker dat daar geen verandering in atoomweergawe is voordat jy 'n inskrywing verander nie:

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

In hierdie geval, die opdatering van die tabel products sal nie uitgevoer word as 'n ander bewerking voorheen veranderinge aan hierdie ry gemaak het nie. As geen ander bewerkings op hierdie ry uitgevoer is nie, sal die verandering vir een ry plaasvind en ons kan sê dat die opdatering suksesvol was.

Daar is ander afwykings behalwe vuil leeswerk en dataverlies

Wat datakonsekwentheid betref, is die fokus op die potensiaal vir wedrentoestande wat tot vuil leeswerk en dataverlies kan lei. Data-afwykings stop egter nie daar nie.

Een voorbeeld van sulke afwykings is opnamevervorming (skryf skewe). Distorsies is moeilik om op te spoor omdat daar gewoonlik nie aktief daarna gesoek word nie. Hulle is nie te wyte aan vuil leeswerk of dataverlies nie, maar aan oortredings van logiese beperkings wat op die data geplaas word.

Kom ons oorweeg byvoorbeeld 'n moniteringstoepassing wat vereis dat een operateur te alle tye in diens is:

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;

In die bogenoemde situasie sal 'n rekordkorrupsie voorkom as beide transaksies suksesvol gepleeg word. Alhoewel daar geen vuil leeswerk of dataverlies was nie, is die integriteit van die data in die gedrang gebring: nou word twee mense terselfdertyd as opgeroep beskou.

Serialiseerbare isolasie, skema-ontwerp of databasisbeperkings kan help om skryfkorrupsie uit te skakel. Ontwikkelaars moet sulke afwykings tydens ontwikkeling kan identifiseer om dit in produksie te vermy. Terselfdertyd is opnamevervormings uiters moeilik om in die kodebasis te soek. Veral in groot stelsels, wanneer verskillende ontwikkelingspanne verantwoordelik is vir die implementering van funksies gebaseer op dieselfde tabelle en nie saamstem oor die besonderhede van datatoegang nie.

Die databasis en die gebruiker stem nie altyd saam oor wat om te doen nie

Een van die sleutelkenmerke van databasisse is die waarborg van uitvoeringsbevel, maar hierdie bevel self is dalk nie deursigtig vir die sagteware-ontwikkelaar nie. Databasisse voer transaksies uit in die volgorde wat hulle ontvang word, nie in die volgorde wat programmeerders beoog nie. Die volgorde van transaksies is moeilik om te voorspel, veral in hoogs gelaaide parallelle stelsels.

Tydens ontwikkeling, veral wanneer daar met nie-blokkerende biblioteke gewerk word, kan swak styl en lae leesbaarheid gebruikers laat glo dat transaksies opeenvolgend uitgevoer word, terwyl dit in werklikheid in enige volgorde in die databasis kan aankom.

Met die eerste oogopslag, in die program hieronder, word T1 en T2 opeenvolgend genoem, maar as hierdie funksies nie blokkeer nie en gee dit onmiddellik die resultaat in die vorm terug belofte, dan sal die volgorde van oproepe bepaal word deur die oomblikke toe hulle die databasis betree het:

resultaat1 = T1() // werklike resultate is beloftes
resultaat2 = T2()

As atomisiteit vereis word (dit wil sê, óf alle bewerkings moet voltooi óf geaborteer word) en volgorde saak maak, dan moet bewerkings T1 en T2 binne 'n enkele transaksie uitgevoer word.

Skerwing op toepassingsvlak kan buite die toepassing geskuif word

Sharding is 'n metode om 'n databasis horisontaal te partisioneer. Sommige databasisse kan data outomaties horisontaal verdeel, terwyl ander nie, of nie baie goed daarmee is nie. Wanneer data-argitekte/-ontwikkelaars in staat is om presies te voorspel hoe toegang tot data verkry sal word, kan hulle horisontale partisies in gebruikersruimte skep in plaas daarvan om hierdie werk na die databasis te delegeer. Hierdie proses word "toepassingsvlakversplintering" genoem (toepassingsvlak-sharing).

Ongelukkig skep hierdie naam dikwels die wanopvatting dat sharding in toepassingsdienste woon. Trouens, dit kan as 'n aparte laag voor die databasis geïmplementeer word. Afhangende van datagroei en skema-iterasies, kan verdelingsvereistes redelik kompleks word. Sommige strategieë kan baat vind by die vermoë om te herhaal sonder om toepassingbedieners te herontplooi.

Meer ontwikkelaars behoort dit oor databasisse te weet
'n Voorbeeld van 'n argitektuur waarin toepassingsbedieners van die versplinteringsdiens geskei word

Deur versplintering na 'n aparte diens te skuif, brei die vermoë uit om verskillende versplinteringstrategieë te gebruik sonder dat dit nodig is om toepassings te herontplooi. Vites is 'n voorbeeld van so 'n skeringstelsel op die toepassingsvlak. Vitess bied horisontale sharding vir MySQL en stel kliënte in staat om daarmee te koppel via die MySQL-protokol. Die stelsel segmenteer die data in verskillende MySQL-nodusse wat niks van mekaar weet nie.

Outo-inkrementering kan gevaarlik wees

AUTOINCREMENT is 'n algemene manier om primêre sleutels te genereer. Daar is dikwels gevalle waar databasisse as ID-opwekkers gebruik word, en die databasis bevat tabelle wat ontwerp is om identifiseerders te genereer. Daar is verskeie redes waarom die generering van primêre sleutels met outo-inkrementering ver van ideaal is:

  • In 'n verspreide databasis is outo-inkrementering 'n ernstige probleem. Om 'n ID te genereer, word 'n globale slot vereis. In plaas daarvan kan u 'n UUID genereer: dit vereis nie interaksie tussen verskillende databasisnodusse nie. Outo-inkrementering met slotte kan lei tot twis en die werkverrigting op insetsels in verspreide situasies aansienlik verminder. Sommige DBMS'e (byvoorbeeld MySQL) kan spesiale konfigurasie en meer noukeurige aandag vereis om meester-meester-replikasie behoorlik te organiseer. En dit is maklik om foute te maak wanneer u konfigureer, wat tot opnamefoute sal lei.
  • Sommige databasisse het partisiealgoritmes gebaseer op primêre sleutels. Opeenvolgende ID's kan lei tot onvoorspelbare warm kolle en verhoogde las op sommige partisies terwyl ander ledig bly.
  • 'n Primêre sleutel is die vinnigste manier om toegang tot 'n ry in 'n databasis te kry. Met beter maniere om rekords te identifiseer, kan opeenvolgende ID's die belangrikste kolom in tabelle verander in 'n nuttelose kolom gevul met betekenislose waardes. Daarom, waar moontlik, kies asseblief 'n wêreldwye unieke en natuurlike primêre sleutel (bv. gebruikersnaam).

Voordat jy op 'n benadering besluit, oorweeg die impak van outo-inkrementerende ID's en UUID's op indeksering, partisionering en verdeling.

Ou data kan nuttig wees en vereis nie sluiting nie

Multiversion Concurrency Control (MVCC) implementeer baie van die konsekwentheidsvereistes wat kortliks hierbo bespreek is. Sommige databasisse (byvoorbeeld Postgres, Spanner) gebruik MVCC om transaksies te “voer” met momentopnames—ouer weergawes van die databasis. Oomblikkietransaksies kan ook gerangskik word om konsekwentheid te verseker. Wanneer vanaf 'n ou momentopname gelees word, word verouderde data gelees.

Die lees van effens verouderde data kan nuttig wees, byvoorbeeld wanneer ontledings uit die data gegenereer word of benaderde totale waardes bereken word.

Die eerste voordeel van die werk met verouderde data is lae latensie (veral as die databasis oor verskillende geografiese gebiede versprei is). Die tweede is dat leesalleen-transaksies sluitvry is. Dit is 'n beduidende voordeel vir toepassings wat baie lees, solank hulle verouderde data kan hanteer.

Meer ontwikkelaars behoort dit oor databasisse te weet
Die toepassingsbediener lees data van die plaaslike replika wat 5 sekondes verouderd is, selfs al is die nuutste weergawe beskikbaar aan die ander kant van die Stille Oseaan

DBBS'e suiwer outomaties ouer weergawes uit en laat jou in sommige gevalle toe om dit op versoek te doen. Byvoorbeeld, Postgres laat gebruikers toe om te doen VACUUM op versoek, en voer ook gereeld hierdie bewerking outomaties uit. Spanner bestuur 'n vullisverwyderaar om ontslae te raak van kiekies ouer as een uur.

Enige tyd bronne is onderhewig aan vervorming

Die bes bewaarde geheim in rekenaarwetenskap is dat alle tydsberekening API's lieg. Trouens, ons masjiene weet nie die presiese huidige tyd nie. Rekenaars bevat kwartskristalle wat vibrasies genereer wat gebruik word om tyd te hou. Hulle is egter nie akkuraat genoeg nie en kan voor/agter wees op die presiese tyd. Die skof kan 20 sekondes per dag bereik. Daarom moet die tyd op ons rekenaars periodiek met die netwerk een gesinchroniseer word.

NTP-bedieners word vir sinchronisasie gebruik, maar die sinchronisasieproses self is onderhewig aan netwerkvertragings. Selfs sinchronisering met 'n NTP-bediener in dieselfde datasentrum neem 'n geruime tyd. Dit is duidelik dat werk met 'n publieke NTP-bediener kan lei tot selfs groter vervorming.

Atoomhorlosies en hul GPS-eweknieë is beter om die huidige tyd te bepaal, maar hulle is duur en vereis komplekse opstelling, dus kan hulle nie op elke motor geïnstalleer word nie. As gevolg hiervan gebruik datasentrums 'n gelaagde benadering. Atoom- en/of GPS-horlosies wys die presiese tyd, waarna dit deur sekondêre bedieners na ander masjiene uitgesaai word. Dit beteken dat elke masjien 'n sekere afwyking van die presiese tyd sal ervaar.

Die situasie word vererger deur die feit dat toepassings en databasisse dikwels op verskillende masjiene geleë is (indien nie in verskillende datasentrums nie). Dus, die tyd sal verskil nie net op DB nodusse versprei oor verskillende masjiene. Dit sal ook anders wees op die toepassingsbediener.

Google TrueTime neem 'n heeltemal ander benadering. Die meeste mense glo dat Google se vordering in hierdie rigting verklaar word deur die banale oorgang na atoom- en GPS-horlosies, maar dit is slegs deel van die groot prentjie. Hier is hoe TrueTime werk:

  • TrueTime gebruik twee verskillende bronne: GPS en atoomhorlosies. Hierdie horlosies het nie-gekorreleerde mislukkingsmodusse. [sien bladsy 5 vir besonderhede hier - ongeveer. vertaal.), so hul gesamentlike gebruik verhoog betroubaarheid.
  • TrueTime het 'n ongewone API. Dit gee tyd terug as 'n interval met meetfout en onsekerheid daarin ingebou. Die werklike oomblik in tyd is iewers tussen die boonste en onderste grense van die interval. Spanner, Google se verspreide databasis, wag eenvoudig totdat dit veilig is om te sê dat die huidige tyd buite bereik is. Hierdie metode stel 'n mate van latensie in die stelsel in, veral as die onsekerheid oor die meesters hoog is, maar verseker korrektheid selfs in 'n wêreldwyd verspreide situasie.

Meer ontwikkelaars behoort dit oor databasisse te weet
Die Spanner-komponente gebruik TrueTime, waar TT.now() 'n interval terugstuur, so die Spanner slaap eenvoudig tot die punt waar dit met vertroue kan wees dat die huidige tyd 'n sekere punt verby is

Verminderde akkuraatheid in die bepaling van die huidige tyd beteken 'n toename in die duur van Spanner-bewerkings en 'n afname in werkverrigting. Dit is hoekom dit belangrik is om die hoogste moontlike akkuraatheid te handhaaf, al is dit onmoontlik om 'n heeltemal akkurate horlosie te verkry.

Vertraging het baie betekenisse

As jy 'n dosyn kenners vra oor wat 'n vertraging is, sal jy waarskynlik verskillende antwoorde kry. In DBMS word latency dikwels "databasislatency" genoem en is anders as wat deur die kliënt waargeneem word. Die feit is dat die kliënt die som van die netwerkvertraging en die databasisvertraging waarneem. Die vermoë om die tipe latensie te isoleer is van kritieke belang wanneer groeiende probleme ontfout word. Wanneer jy metrieke insamel en vertoon, probeer altyd om albei tipes dop te hou.

Prestasievereistes moet vir 'n spesifieke transaksie geëvalueer word

Soms word die prestasie-eienskappe van 'n DBBS en sy beperkings gespesifiseer in terme van skryf/lees deurset en latensie. Dit bied 'n algemene oorsig van sleutelstelselparameters, maar wanneer die werkverrigting van 'n nuwe DBBS geëvalueer word, is 'n baie meer omvattende benadering om kritieke bedrywighede afsonderlik te evalueer (vir elke navraag en/of transaksie). Voorbeelde:

  • Skryf deurset en latensie wanneer 'n nuwe ry in tabel X ingevoeg word (met 50 miljoen rye) met gespesifiseerde beperkings en ryopvulling in verwante tabelle.
  • Vertraging in die vertoon van vriende van vriende van 'n sekere gebruiker wanneer die gemiddelde aantal vriende 500 is.
  • Vertraging in die herwinning van die top 100 inskrywings uit 'n gebruiker se geskiedenis wanneer die gebruiker 500 ander gebruikers volg met X inskrywings per uur.

Evaluering en eksperimentering kan sulke kritieke gevalle insluit totdat jy vol vertroue is dat die databasis aan die prestasievereistes voldoen. 'n Soortgelyke reël neem ook hierdie uiteensetting in ag wanneer vertragingsmaatstawwe versamel word en SLO's bepaal word.

Wees bewus van hoë kardinaliteit wanneer statistieke vir elke bewerking versamel word. Gebruik logboeke, gebeurtenisversameling of verspreide opsporing om hoëkragontfoutingsdata te verkry. In die artikel "Wil jy latency ontfout?» jy kan jouself vertroud maak met vertraagdefout-metodologieë.

Geneste transaksies kan gevaarlik wees

Nie elke DBBS ondersteun geneste transaksies nie, maar wanneer dit wel gebeur, kan sulke transaksies onverwagte foute tot gevolg hê wat nie altyd maklik is om op te spoor nie (dit wil sê, dit behoort duidelik te wees dat daar 'n soort anomalie is).

U kan die gebruik van geneste transaksies vermy deur kliëntbiblioteke te gebruik wat dit kan opspoor en omseil. As geneste transaksies nie laat vaar kan word nie, neem spesiale sorg in die implementering daarvan om onverwagte situasies te vermy waar voltooide transaksies per ongeluk geaborteer word as gevolg van genestes.

Die inkapseling van transaksies in verskillende lae kan lei tot onverwagte geneste transaksies, en vanuit 'n kodeleesbaarheidsoogpunt kan dit dit moeilik maak om die skrywer se bedoelings te verstaan. Kyk na die volgende program:

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

Wat sal die uitset van bogenoemde kode wees? Sal dit beide transaksies terugrol, of net die binneste een? Wat gebeur as ons staatmaak op veelvuldige lae biblioteke wat die skepping van transaksies vir ons insluit? Sal ons sulke gevalle kan identifiseer en verbeter?

Stel jou 'n datalaag voor met veelvuldige bewerkings (bv. newAccount) is reeds in sy eie transaksies geïmplementeer. Wat gebeur as jy dit bestuur as deel van hoërvlak besigheidslogika wat binne sy eie transaksie loop? Wat sou die isolasie en konsekwentheid in hierdie geval wees?

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

In plaas daarvan om na antwoorde op sulke eindelose vrae te soek, is dit beter om geneste transaksies te vermy. Jou datalaag kan immers maklik hoëvlak-bewerkings uitvoer sonder om sy eie transaksies te skep. Daarbenewens is die besigheidslogika self in staat om 'n transaksie te begin, bewerkings daarop uit te voer, 'n transaksie te pleeg of te staak.

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.

Transaksies moet nie gekoppel wees aan aansoekstaat nie

Soms is dit aanloklik om toepassingstatus in transaksies te gebruik om sekere waardes te verander of navraagparameters aan te pas. Die kritieke nuanse om te oorweeg is die korrekte omvang van toepassing. Kliënte herbegin dikwels transaksies wanneer daar netwerkprobleme is. As die transaksie dan afhang van 'n toestand wat deur 'n ander proses verander word, kan dit die verkeerde waarde kies, afhangende van die moontlikheid van 'n datawedloop. Transaksies moet die risiko van datarastoestande in die aansoek in ag neem.

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

Bogenoemde transaksie sal die volgordenommer verhoog elke keer as dit uitgevoer word, ongeag die finale resultaat. As die toewysing misluk as gevolg van netwerkprobleme, sal die versoek met 'n ander volgordenommer uitgevoer word wanneer jy weer probeer.

Navraagbeplanners kan jou baie vertel oor 'n databasis

Navraagbeplanners bepaal hoe 'n navraag in 'n databasis uitgevoer sal word. Hulle ontleed ook versoeke en optimaliseer dit voordat hulle dit stuur. Beplanners kan slegs 'n paar moontlike ramings verskaf op grond van die seine tot hul beskikking. Byvoorbeeld, wat is die beste soekmetode vir die volgende navraag?

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

Die resultate kan op twee maniere opgespoor word:

  • Volle tafelskandering: Jy kan na elke inskrywing in die tabel kyk en artikels met 'n bypassende outeurnaam terugstuur, en dit dan bestel.
  • Indeksskandering: Jy kan 'n indeks gebruik om bypassende ID's te vind, daardie rye te kry en dit dan te bestel.

Die navraagbeplanner se taak is om te bepaal watter strategie die beste is. Dit is die moeite werd om in ag te neem dat navraagbeplanners slegs beperkte voorspellingsvermoëns het. Dit kan lei tot slegte besluite. DBA's of ontwikkelaars kan dit gebruik om onderpresterende navrae te diagnoseer en te verfyn. Nuwe weergawes van die DBBS kan navraagbeplanners opstel, en selfdiagnose kan help wanneer die databasis opgedateer word as die nuwe weergawe tot prestasieprobleme lei. Stadige navraagloglêers, vertragingskwessieverslae of uitvoeringstydstatistieke kan help om navrae te identifiseer wat geoptimaliseer moet word.

Sommige maatstawwe wat deur die navraagbeplanner aangebied word, kan onderhewig wees aan geraas (veral wanneer latensie of SVE-tyd geskat word). 'n Goeie toevoeging tot skeduleerders is gereedskap om die uitvoeringspad op te spoor en na te spoor. Hulle laat jou toe om sulke probleme te diagnoseer (ongelukkig, nie alle DBBS'e verskaf sulke gereedskap nie).

Aanlyn migrasie is moeilik, maar moontlik

Aanlynmigrasie, regstreekse migrasie of intydse migrasie beteken om van een databasis na 'n ander te beweeg sonder stilstand of datakorrupsie. Regstreekse migrasie is makliker om uit te voer as die oorgang binne dieselfde DBMS/enjin plaasvind. Die situasie word meer ingewikkeld wanneer dit nodig is om na 'n nuwe DBBS te skuif met verskillende prestasie- en skemavereistes.

Daar is verskillende aanlyn migrasiemodelle. Hier is een van hulle:

  • Aktiveer dubbelinskrywing in beide databasisse. Die nuwe databasis het op hierdie stadium nie al die data nie, maar aanvaar slegs die nuutste data. Sodra jy seker is hiervan, kan jy aanbeweeg na die volgende stap.
  • Aktiveer lees vanaf beide databasisse.
  • Stel die stelsel op sodat lees en skryf hoofsaaklik op die nuwe databasis uitgevoer word.
  • Hou op om na die ou databasis te skryf terwyl jy voortgaan om data daaruit te lees. Op hierdie stadium is die nuwe databasis nog sonder data. Hulle moet van die ou databasis gekopieer word.
  • Die ou databasis is leesalleen. Kopieer die ontbrekende data van die ou databasis na die nuwe een. Nadat die migrasie voltooi is, skakel die paaie na die nuwe databasis oor, en stop die ou een en vee dit uit die stelsel uit.

Vir bykomende inligting, beveel ek aan om te kontak Artikel, wat Stripe se migrasiestrategie uiteensit gebaseer op hierdie model.

'n Beduidende toename in die databasis behels 'n toename in onvoorspelbaarheid

Die groei van die databasis lei tot onvoorspelbare probleme wat verband hou met die omvang daarvan. Hoe meer ons weet van die interne struktuur van 'n databasis, hoe beter kan ons voorspel hoe dit sal skaal. Sommige oomblikke is egter steeds onmoontlik om te voorsien.
Soos die basis groei, kan vorige aannames en verwagtinge rakende datavolume en netwerkbandwydtevereistes verouderd raak. Dit is wanneer die vraag ontstaan ​​van groot ontwerpopknappings, grootskaalse operasionele verbeterings, heroorweging van ontplooiings, of migrasie na ander DBBS'e om potensiële probleme te vermy.

Maar moenie dink dat uitstekende kennis van die interne struktuur van die bestaande databasis die enigste ding is wat nodig is nie. Nuwe skale sal nuwe onbekendes meebring. Onvoorspelbare pynpunte, oneweredige dataverspreiding, onverwagte bandwydte en hardeware kwessies, steeds toenemende verkeer en nuwe netwerksegmente sal jou dwing om jou databasisbenadering, datamodel, ontplooiingsmodel en databasisgrootte te heroorweeg.

...

Toe ek daaraan begin dink het om hierdie artikel te publiseer, was daar reeds vyf meer items op my oorspronklike lys. Toe kom 'n groot aantal nuwe idees oor wat anders gedek kan word. Daarom raak die artikel aan die minste ooglopende probleme wat maksimum aandag verg. Dit beteken egter nie dat die onderwerp uitgeput is nie en ek sal nie meer daarna terugkeer in my toekomstige materiaal nie en sal nie veranderinge aan die huidige een aanbring nie.

PS

Lees ook op ons blog:

Bron: will.com

Voeg 'n opmerking