Mear ûntwikkelders moatte dit witte oer databases

Noat. transl.: Jaana Dogan is in betûfte yngenieur by Google dy't op it stuit wurket oan observabiliteit fan 'e produksjetsjinsten fan it bedriuw skreaun yn Go. Yn dit artikel, dat grutte populariteit krige ûnder it Ingelsktalige publyk, sammele se yn 17 punten wichtige technyske details oangeande DBMS's (en soms ferspraat systemen yn it algemien) dy't nuttich binne om te beskôgjen foar ûntwikkelders fan grutte/easkende applikaasjes.

Mear ûntwikkelders moatte dit witte oer databases

De grutte mearderheid fan kompjûtersystemen hâldt har steat by en fereaskje dêrtroch wat soarte fan gegevensopslachsysteem. Ik sammele kennis oer databases oer in lange perioade fan tiid, lâns it meitsjen fan ûntwerpflaters dy't liede ta gegevensferlies en ûnderbrekkingen. Yn systemen dy't grutte folumes fan ynformaasje ferwurkje, lizze databases yn it hert fan 'e systeemarsjitektuer en fungearje as in wichtich elemint by it kiezen fan de optimale oplossing. Nettsjinsteande it feit dat goed omtinken wurdt jûn oan it wurk fan 'e databank, binne de problemen dy't applikaasje-ûntwikkelders besykje te antisipearjen faaks gewoan it tip fan' e iisberch. Yn dizze searje artikels diel ik guon ideeën dy't nuttich sille wêze foar ûntwikkelders dy't net spesjalisearre binne op dit fjild.

  1. Jo binne gelok as 99,999% fan 'e tiid it netwurk gjin problemen feroarsaket.
  2. ACID betsjut in protte ferskillende dingen.
  3. Elke databank hat syn eigen meganismen foar it garandearjen fan gearhing en isolemint.
  4. Optimistysk blokkearjen komt ta de rêding as it dreech is om de gewoane te behâlden.
  5. D'r binne oare anomalies neist smoarge lêzen en gegevensferlies.
  6. De databank en de brûker binne it net altyd iens oer de gong fan saken.
  7. Sharding op applikaasjenivo kin bûten de applikaasje ferpleatst wurde.
  8. Autoincrementing kin gefaarlik wêze.
  9. Stale gegevens kinne nuttich wêze en hoege net beskoattele te wurden.
  10. Ferfoarmings binne typysk foar boarnen fan elke tiid.
  11. Fertraging hat in protte betsjuttingen.
  12. Prestaasjeeasken moatte wurde evaluearre foar in spesifike transaksje.
  13. Nested transaksjes kinne gefaarlik wêze.
  14. Transaksjes moatte net wurde bûn oan tapassing tastân.
  15. Queryplanners kinne jo in protte fertelle oer databases.
  16. Online migraasje is lestich, mar mooglik.
  17. In signifikante ferheging fan 'e database bringt in tanimming fan ûnfoarspelberens mei.

Ik wol Emmanuel Odeke, Rein Henrichs en oaren betankje foar harren feedback op in eardere ferzje fan dit artikel.

Jo binne gelok as 99,999% fan 'e tiid it netwurk gjin problemen feroarsaket.

De fraach bliuwt oer hoe betrouber moderne netwurktechnologyen binne en hoe faak systemen falle troch netwurkflaters. Ynformaasje oer dit probleem is min en ûndersyk wurdt faak dominearre troch grutte organisaasjes mei spesjalisearre netwurken, apparatuer en personiel.

Mei in beskikberensrate fan 99,999% foar Spanner (de wrâldwide ferspraat databank fan Google), beweart Google dat allinich 7,6% problemen binne relatearre oan it netwurk. Tagelyk neamt it bedriuw har spesjalisearre netwurk de "haadpylder" fan hege beskikberens. Studearje Bailis en Kingsbury, útfierd yn 2014, daagt ien fan 'e "misferstannen oer ferdield komputer", dy't Peter Deutsch formulearre yn 1994. Is it netwurk echt betrouber?

Wiidweidich ûndersyk bûten gigantyske bedriuwen, útfierd foar it bredere ynternet, bestiet gewoan net. D'r binne ek net genôch gegevens fan 'e grutte spilers oer hokker persintaazje fan' e problemen fan har klanten netwurkrelatearre is. Wy binne ús goed bewust fan ûnderbrekkingen yn 'e netwurkstapel fan grutte wolkproviders dy't in heule stik fan it ynternet foar ferskate oeren kinne ôfnimme, gewoan om't se heechprofyl eveneminten binne dy't in grut oantal minsken en bedriuwen beynfloedzje. Netwurkûnderbrekken kinne yn folle mear gefallen problemen feroarsaakje, sels as net al dy gefallen yn it fuotljocht steane. Klanten fan wolktsjinsten witte ek neat oer de oarsaken fan problemen. As der in flater is, is it hast ûnmooglik om it ta te skriuwen oan in netwurkflater oan 'e kant fan' e tsjinstferliener. Foar harren binne tsjinsten fan tredden swarte doazen. It is ûnmooglik om de ynfloed te beoardieljen sûnder in grutte tsjinstferliener te wêzen.

Sjoen wat de grutte spilers rapportearje oer har systemen, is it feilich om te sizzen dat jo gelok hawwe as netwurkswierrichheden mar in lyts persintaazje fan potinsjele downtime-problemen ferantwurdzje. Netwurkkommunikaasje lije noch fan sokke alledaagse dingen as hardware-mislukkingen, topologywizigingen, bestjoerlike konfiguraasjewizigingen en stroomûnderbrekken. Koartlyn wie ik ferrast om te learen dat de list mei mooglike problemen tafoege waard shark bites (ja, jo hawwe it goed heard).

ACID betsjut in protte ferskillende dingen

It akronym ACID stiet foar Atomicity, Consistency, Isolation, Reliability. Dizze eigenskippen fan transaksjes binne bedoeld om har jildichheid te garandearjen yn gefal fan mislearrings, flaters, hardwarefouten, ensfh. Sûnder ACID of ferlykbere skema's soe it lestich wêze foar applikaasje-ûntwikkelders om te ûnderskieden tusken wat se ferantwurdlik binne foar en wêr't de databank ferantwurdlik foar is. De measte relasjonele transaksjedatabases besykje ACID-konform te wêzen, mar nije oanpakken lykas NoSQL hawwe in protte databases sûnder ACID-transaksjes oanlieding jûn, om't se djoer binne om te ymplementearjen.

Doe't ik foar it earst yn 'e yndustry kaam, spruts ús technyske lead oer hoe relevant it ACID-konsept wie. Om earlik te wêzen, wurdt ACID beskôge as in rûge beskriuwing ynstee fan in strikte ymplemintaasjestandert. Hjoed fyn ik it meast nuttich om't it in spesifike kategory fan problemen opropt (en in ferskaat oan mooglike oplossingen suggerearret).

Net elke DBMS is ACID-kompatibel; Tagelyk begripe database-ymplemintaasjes dy't ACID stypje de set easken oars. Ien fan 'e redenen wêrom't ACID-ymplemintaasjes patchy binne, komt troch de protte ôfwikselingen dy't moatte wurde makke om ACID-easken út te fieren. Makkers meie har databases presintearje as ACID-kompatibel, mar de ynterpretaasje fan rânegefallen kin dramatysk ferskille, lykas it meganisme foar it behanneljen fan "ûnwierskynlike" eveneminten. Op syn minst kinne ûntwikkelders in begryp op heech nivo krije fan 'e yngewikkeldheden fan basisymplementaasjes om in goed begryp te krijen fan har spesjale gedrach en ôfwikselingen foar ûntwerp.

It debat oer de fraach oft MongoDB foldocht oan ACID-easken giet troch, sels nei de frijlitting fan ferzje 4. MongoDB is in lange tiid net stipe logging, hoewol't standert gegevens waarden tawijd oan skiif net mear as ien kear elke 60 sekonden. Stel jo it folgjende senario foar: in applikaasje pleatst twa skriften (w1 en w2). MongoDB bewarret w1 mei súkses, mar w2 is ferlern troch in hardwarefout.

Mear ûntwikkelders moatte dit witte oer databases
Diagram dat it senario yllustrearret. MongoDB crasht foardat it gegevens op skiif skriuwe kin

Ynsette op skiif is in djoer proses. Troch faak commits te foarkommen, ferbetterje ûntwikkelders de opnameprestaasjes ten koste fan betrouberens. MongoDB stipet op it stuit logging, mar smoarge skriuwingen kinne noch altyd ynfloed hawwe op gegevensintegriteit, om't logs standert elke 100ms wurde fêstlein. Dat is, in soartgelikense senario is noch altyd mooglik foar logs en de wizigingen dy't dêryn presintearre binne, hoewol it risiko folle leger is.

Elke databank hat syn eigen konsistinsje- en isolaasjemeganismen

Fan 'e ACID-easken hawwe konsistinsje en isolemint it grutste oantal ferskillende ymplemintaasjes, om't it oanbod fan ôfwikselingen breder is. It moat sein wurde dat konsistinsje en isolaasje frij djoere funksjes binne. Se fereaskje koördinaasje en fergrutsjen konkurrinsje foar gegevens gearhing. De kompleksiteit fan it probleem nimt signifikant ta as it nedich is om de databank horizontaal te skaaljen oer meardere datasintra (benammen as se yn ferskate geografyske regio's lizze). It berikken fan in heech nivo fan konsistinsje is heul lestich, om't it ek beskikberens ferminderet en netwurksegmentaasje fergruttet. Foar in mear algemiene útlis fan dit ferskynsel ried ik jo oan te ferwizen nei CAP teorem. It is ek de muoite wurdich op te merken dat applikaasjes lytse hoemannichten ynkonsistinsje kinne omgean, en programmeurs kinne de nuânses fan it probleem goed genôch begripe om ekstra logika yn 'e applikaasje te ymplementearjen om ynkonsistinsje te behanneljen sûnder swier te fertrouwen op 'e databank om it te behanneljen.

DBMS's jouwe faak ferskate nivo's fan isolaasje. Applikaasje-ûntwikkelders kinne de meast effektive kieze op basis fan har foarkar. Lege isolaasje soarget foar ferhege snelheid, mar fergruttet ek it risiko fan in gegevensrace. Hege isolaasje ferminderet dizze kâns, mar fertraget wurk en kin liede ta konkurrinsje, dat sil liede ta sokke remmen yn 'e basis dat mislearrings begjinne.

Mear ûntwikkelders moatte dit witte oer databases
Oersjoch fan besteande concurrency modellen en relaasjes tusken harren

De SQL-standert definiearret mar fjouwer isolaasjenivo's, hoewol d'r yn teory en praktyk folle mear binne. Jepson.io biedt in poerbêst oersjoch fan besteande concurrency modellen. Bygelyks, Google Spanner garandearret eksterne serializability mei klok syngronisaasje, en hoewol't dit is in strangere isolaasje laach, it is net definiearre yn standert isolaasje lagen.

De SQL-standert neamt de folgjende isolaasjenivo's:

  • Serializable (stringendste en djoerste): Serializable útfiering hat itselde effekt as guon sekwinsjele transaksje útfiering. Sekwinsjele útfiering betsjut dat elke folgjende transaksje pas begjint nei't de foarige is foltôge. Dêrby moat opmurken wurde dat it nivo Serializable faak útfierd as saneamde momintopname isolaasje (Bygelyks, yn Oracle) fanwege ferskillen yn ynterpretaasje, hoewol't snapshot isolaasje sels is net fertsjintwurdige yn de SQL standert.
  • Repeatable lêzen: Net-ferplichte records yn 'e aktuele transaksje binne beskikber foar de aktuele transaksje, mar feroarings makke troch oare transaksjes (lykas nije rigen) net sichtber.
  • Lês ynsette: Unbeheinde gegevens binne net beskikber foar transaksjes. Yn dit gefal kinne transaksjes allinich tawijde gegevens sjen, en fantomlêzingen kinne foarkomme. As in transaksje nije rigen ynfoeget en commits, sil de aktuele transaksje se sjen kinne as se frege wurde.
  • Lês uncommitted (minst strang en djoer nivo): Dirty lêzen binne tastien, transaksjes kinne sjen uncommitted feroarings makke troch oare transaksjes. Yn 'e praktyk kin dit nivo nuttich wêze foar rûge skattings, lykas fragen COUNT(*) op 'e tafel.

nivo Serializable minimizes it risiko fan gegevens races, wylst wêzen de meast djoere in útfiere en resultearret yn de heechste kompetitive lading op it systeem. Oare isolaasjenivo's binne makliker te ymplementearjen, mar ferheegje de kâns op gegevensrassen. Guon DBMS's kinne jo in oanpast isolaasjenivo ynstelle, oaren hawwe sterke foarkarren en net alle nivo's wurde stipe.

Stipe foar isolaasjenivo's wurdt faak advertearre yn in opjûne DBMS, mar allinich in soarchfâldige stúdzje fan har gedrach kin sjen litte wat der eins bart.

Mear ûntwikkelders moatte dit witte oer databases
Beoardieling fan anomalies fan tagelyk op ferskate isolaasjenivo's foar ferskate DBMS's

Martin Kleppmann yn syn projekt hermitage Fergeliket ferskate isolaasjenivo's, praat oer anomalies fan tagelyk, en oft de databank by steat is om te hâlden oan in bepaald isolaasjenivo. It ûndersyk fan Kleppmann lit sjen hoe oars database-ûntwikkelders tinke oer isolaasjenivo's.

Optimistysk blokkearjen komt ta de rêding as it dreech is om de gewoane te behâlden.

Blokkearje kin heul djoer wêze, net allinich om't it konkurrinsje yn 'e database fergruttet, mar ek om't it fereasket dat de applikaasje-tsjinners konstant ferbine mei de database. Netwurksegmentaasje kin eksklusive beskoattelsituaasjes fergrutsje en liede ta deadlocks dy't lestich te identifisearjen en op te lossen binne. Yn gefallen dêr't eksklusyf beskoatteljen is net geskikt, optimistysk beskoattelje helpt.

Optimistysk slot is in metoade wêryn it by it lêzen fan in tekenrige rekken hâldt mei de ferzje, kontrôlesum of tiid fan lêste wiziging. Hjirmei kinne jo derfoar soargje dat d'r gjin feroaring yn atomêre ferzje is foardat jo in yngong wizigje:

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

Yn dit gefal, it bywurkjen fan de tabel products sil net wurde útfierd as in oare operaasje earder makke feroarings oan dizze rige. As gjin oare operaasjes waarden útfierd op dizze rige, de feroaring foar ien rige sil plakfine en wy kinne sizze dat de fernijing wie suksesfol.

D'r binne oare anomalies neist smoarge lêzen en gegevensferlies

As it giet om konsistinsje fan gegevens, leit de fokus op it potinsjeel foar racebetingsten dy't liede kinne ta smoarge lêzen en gegevensferlies. Data-anomalies stopje dêr lykwols net.

Ien foarbyld fan sokke anomalies is opname ferfoarming (skriuw skews). Ferfoarmings binne dreech te ûntdekken, om't der meastentiids net aktyf nei socht wurdt. Se binne net troch smoarge lêzen of gegevensferlies, mar oan oertredings fan logyske beheiningen pleatst op 'e gegevens.

Litte wy bygelyks in tafersjochapplikaasje beskôgje dy't fereasket dat ien operator te alle tiden oprop 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;

Yn 'e boppesteande situaasje sil in rekordkorrupsje foarkomme as beide transaksjes mei súkses ynset wurde. Hoewol d'r gjin smoarge lêzings of gegevensferlies wiene, waard de yntegriteit fan 'e gegevens kompromittearre: no wurde twa minsken tagelyk beskôge as oprop.

Serialisearbere isolaasje, skema-ûntwerp, of database-beheiningen kinne helpe by it eliminearjen fan skriuwkorrupsje. Untwikkelders moatte sokke anomalies kinne identifisearje tidens ûntwikkeling om se yn produksje te foarkommen. Tagelyk binne opnameferfoarmingen ekstreem lestich om te sykjen yn 'e koadebasis. Benammen yn grutte systemen, doe't ferskillende ûntwikkeling teams binne ferantwurdlik foar it útfieren fan funksjes basearre op deselde tabellen en net iens oer de spesifiken fan gegevens tagong.

De databank en de brûker binne it net altyd iens oer wat te dwaan

Ien fan 'e wichtichste skaaimerken fan databases is de garânsje fan útfieringsoarder, mar dizze oarder sels is miskien net transparant foar de softwareûntwikkelder. Databanken útfiere transaksjes yn 'e folchoarder dy't se wurde ûntfongen, net yn' e folchoarder fan programmeurs. De folchoarder fan transaksjes is lestich te foarsizzen, benammen yn heul laden parallelle systemen.

Tidens ûntwikkeling, benammen by it wurkjen mei net-blokkearjende biblioteken, kinne minne styl en lege lêsberens brûkers leauwe dat transaksjes opfolgjend wurde útfierd, wylst se yn feite yn elke folchoarder yn 'e databank kinne oankomme.

Op it earste each, yn it programma hjirûnder, wurde T1 en T2 sequentially neamd, mar as dizze funksjes net blokkearje en it resultaat fuortendaliks weromjaan yn 'e foarm tasein, dan sil de folchoarder fan oproppen wurde bepaald troch de mominten doe't se de databank ynfierd:

result1 = T1() // echte resultaten binne beloften
resultaat2 = T2()

As atomiciteit fereaske is (dat is, alle operaasjes moatte wurde foltôge of ôfbrutsen) en folchoarder saken, dan operaasjes T1 en T2 moatte wurde útfierd binnen ien transaksje.

Sharding op applikaasjenivo kin bûten de applikaasje ferpleatst wurde

Sharding is in metoade om in databank horizontaal te dielen. Guon databases kinne automatysk gegevens horizontaal splitse, wylst oaren dat net kinne, of net heul goed binne. Wannear't gegevens-arsjitekten / -ûntwikkelders yn steat binne om krekt te foarsizzen hoe't gegevens tagong wurde, kinne se horizontale partysjes meitsje yn brûkersromte ynstee fan dit wurk te delegearjen nei de databank. Dit proses wurdt "sharding op applikaasjenivo" neamd (Sharding op applikaasjenivo).

Spitigernôch skept dizze namme faaks de misfetting dat sharding libbet yn applikaasjetsjinsten. Yn feite kin it ymplementearre wurde as in aparte laach foar de databank. Ofhinklik fan gegevensgroei en skema-iteraasjes, kinne sharding-easken frij kompleks wurde. Guon strategyen kinne profitearje fan de mooglikheid om te iterearjen sûnder tapassingstsjinners opnij te hoege te setten.

Mear ûntwikkelders moatte dit witte oer databases
In foarbyld fan in arsjitektuer wêryn applikaasjeservers skieden binne fan 'e shardingtsjinst

It ferpleatsen fan sharding yn in aparte tsjinst wreidet de mooglikheid út om ferskate shardingstrategyen te brûken sûnder de needsaak om applikaasjes opnij yn te setten. Vitess is in foarbyld fan sa'n sharding systeem op it tapassing nivo. Vitess leveret horizontale sharding foar MySQL en lit kliïnten dêrmei ferbine fia it MySQL-protokol. It systeem segmentearret de gegevens yn ferskate MySQL-knooppunten dy't neat oer elkoar witte.

Autoincrementing kin gefaarlik wêze

AUTOINCREMENT is in mienskiplike manier om primêre kaaien te generearjen. D'r binne faak gefallen as databases wurde brûkt as ID-generators, en de databank befettet tabellen dy't ûntworpen binne om identifiers te generearjen. D'r binne ferskate redenen wêrom't it generearjen fan primêre kaaien mei auto-inkrementearjen fier fan ideaal is:

  • Yn in ferspraat databank is auto-inkrementearjen in serieus probleem. Om de ID te generearjen, is in globale slot nedich. Ynstee dêrfan kinne jo in UUID generearje: dit fereasket gjin ynteraksje tusken ferskate databankknooppunten. Auto-incrementing mei slûzen kin liede ta twist en gâns ferminderje prestaasjes op inserts yn ferspraat situaasjes. Guon DBMS's (bygelyks MySQL) kinne spesjale konfiguraasje en mear soarchfâldige oandacht fereaskje om master-master-replikaasje goed te organisearjen. En it is maklik om flaters te meitsjen by it konfigurearjen, wat sil liede ta opname mislearrings.
  • Guon databases hawwe partitionearjende algoritmen basearre op primêre kaaien. Opfolgjende ID's kinne liede ta ûnfoarspelbere hot spots en ferhege lading op guon partysjes, wylst oaren idle bliuwe.
  • In primêre kaai is de fluchste manier om tagong te krijen ta in rige yn in databank. Mei bettere manieren om records te identifisearjen, kinne opfolgjende ID's de wichtichste kolom yn tabellen feroarje yn in nutteleaze kolom fol mei betsjuttingsleaze wearden. Kies dêrom, as it mooglik is, in wrâldwiid unike en natuerlike primêre kaai (bgl. brûkersnamme).

Foardat jo beslute oer in oanpak, beskôgje de ynfloed fan auto-inkrementearjende ID's en UUID's op yndeksearring, partitionering en sharding.

Stale gegevens kinne nuttich wêze en gjin beskoatteljen nedich

Multiversion Concurrency Control (MVCC) ymplemintearret in protte fan 'e konsistinsjeeasken dy't hjirboppe koart besprutsen binne. Guon databases (bygelyks Postgres, Spanner) brûke MVCC om transaksjes te "feeden" mei snapshots - âldere ferzjes fan 'e databank. Snapshot-transaksjes kinne ek serialisearre wurde om konsistinsje te garandearjen. By it lêzen fan in âlde momintopname wurde ferâldere gegevens lêzen.

It lêzen fan in bytsje ferâldere gegevens kin nuttich wêze, bygelyks by it generearjen fan analytiken út 'e gegevens of it berekkenjen fan ungefearde aggregaatwearden.

It earste foardiel fan wurkjen mei legacy gegevens is lege latency (benammen as de databank is ferdield oer ferskate geografyske). De twadde is dat transaksjes allinich lêze binne slotfrij. Dit is in signifikant foardiel foar applikaasjes dy't in protte lêze, salang't se ferâldere gegevens kinne omgean.

Mear ûntwikkelders moatte dit witte oer databases
De applikaasjeserver lêst gegevens fan 'e lokale replika dy't 5 sekonden ferâldere is, sels as de lêste ferzje beskikber is oan' e oare kant fan 'e Stille Oseaan

DBMS's wiskje âldere ferzjes automatysk en, yn guon gefallen, kinne jo dit dwaan op oanfraach. Bygelyks, Postgres kinne brûkers dwaan VACUUM op oanfraach, en ek periodyk fiert dizze operaasje automatysk. Spanner rint in garbage collector te krijen rid fan snapshots âlder as ien oere.

Eltse tiid boarnen binne ûnderwurpen oan ferfoarming

It bêst bewarre geheim yn kompjûterwittenskip is dat alle timing API's lizze. Yn feite witte ús masines de krekte hjoeddeistige tiid net. Kompjûters befetsje kwartskristallen dy't trillings generearje dy't brûkt wurde om tiid te hâlden. Se binne lykwols net krekt genôch en kinne foarút / efterlizze op 'e krekte tiid. De ferskowing kin 20 sekonden per dei berikke. Dêrom moat de tiid op ús kompjûters periodyk syngronisearre wurde mei it netwurk ien.

NTP-tsjinners wurde brûkt foar syngronisaasje, mar it syngronisaasjeproses sels is ûnderwurpen oan netwurkfertragingen. Sels syngronisaasje mei in NTP-tsjinner yn itselde datasintrum duorret wat tiid. It is dúdlik dat wurkjen mei in iepenbiere NTP-tsjinner kin liede ta noch gruttere ferfoarming.

Atoomklokken en har GPS-tsjinhingers binne better foar it bepalen fan 'e aktuele tiid, mar se binne djoer en fereaskje komplekse opset, sadat se net op elke auto kinne wurde ynstalleare. Hjirtroch brûke datasintra in tiered oanpak. Atoom- en/of GPS-klokken litte de krekte tiid sjen, wêrnei't it fia sekundêre tsjinners nei oare masines útstjoerd wurdt. Dit betsjut dat elke masine in bepaalde offset sil ûnderfine fan 'e krekte tiid.

De situaasje wurdt fergrutte troch it feit dat applikaasjes en databases faak lizze op ferskate masines (as net yn ferskate datasintra). Sa sil de tiid net allinich ferskille op DB-knooppunten ferdield oer ferskate masines. It sil ek oars wêze op 'e applikaasjetsjinner.

Google TrueTime nimt in folslein oare oanpak. De measte minsken leauwe dat Google's foarútgong yn dizze rjochting wurdt ferklearre troch de banale oergong nei atoom- en GPS-klokken, mar dit is mar in diel fan it grutte byld. Hjir is hoe't TrueTime wurket:

  • TrueTime brûkt twa ferskillende boarnen: GPS en atoomklokken. Dizze klokken hawwe net-korrelearre mislmodi. [sjoch side 5 foar details hjir - ca. oerset.), sadat har mienskiplik gebrûk de betrouberens fergruttet.
  • TrueTime hat in ûngewoane API. It jout tiid werom as in ynterval mei mjitflater en ûnwissichheid ynboud. It eigentlike momint yn 'e tiid is earne tusken de boppe- en ûndergrins fan it ynterval. Spanner, de ferspraat databank fan Google, wachtet gewoan oant it feilich is om te sizzen dat de hjoeddeistige tiid bûten berik is. Dizze metoade yntrodusearret wat latency yn it systeem, benammen as de ûnwissichheid op 'e masters heech is, mar soarget foar korrektens sels yn in wrâldwiid ferspraat situaasje.

Mear ûntwikkelders moatte dit witte oer databases
De Spanner-komponinten brûke TrueTime, wêrby't TT.now() in ynterval weromjout, sadat de Spanner gewoan sliept oant it punt wêr't it der wis fan wêze kin dat de hjoeddeistige tiid in bepaald punt foarby is

Fermindere krektens by it bepalen fan de aktuele tiid betsjut in ferheging fan 'e doer fan Spanner-operaasjes en in fermindering fan prestaasjes. Dêrom is it wichtich om de heechst mooglike krektens te behâlden, ek al is it ûnmooglik om in folslein krekte horloazje te krijen.

Fertraging hat in protte betsjuttingen

As jo ​​in tsiental saakkundigen freegje oer wat in fertraging is, krije jo wierskynlik ferskate antwurden. Yn DBMS wurdt latency faaks "database latency" neamd en is oars as wat wurdt waarnommen troch de klant. It feit is dat de kliïnt de som fan 'e netwurkfertraging en de databankfertraging observearret. De mooglikheid om it type latency te isolearjen is kritysk by it debuggen fan groeiende problemen. By it sammeljen en werjaan fan metriken, besykje altyd beide soarten yn 'e gaten te hâlden.

Prestaasjeeasken moatte wurde evaluearre foar in spesifike transaksje

Soms wurde de prestaasjeskarakteristiken fan in DBMS en syn beheiningen oanjûn yn termen fan skriuw-/lêzen trochput en latency. Dit soarget foar in algemien oersjoch fan wichtige systeemparameters, mar by it evaluearjen fan de prestaasjes fan in nije DBMS is in folle mear wiidweidige oanpak om krityske operaasjes apart te evaluearjen (foar elke fraach en / of transaksje). Foarbylden:

  • Skriuw trochslach en latency by it ynfoegjen fan in nije rige yn tabel X (mei 50 miljoen rigen) mei oantsjutte beheiningen en rigel padding yn besibbe tabellen.
  • Fertraging by it werjaan fan freonen fan freonen fan in bepaalde brûker as it gemiddelde oantal freonen 500 is.
  • Wachttiid by it opheljen fan de top 100-yngongen út 'e skiednis fan in brûker as de brûker 500 oare brûkers folget mei X-yngongen per oere.

Evaluaasje en eksperimintearje kinne sokke krityske gefallen omfetsje oant jo der wis fan binne dat de databank foldocht oan de prestaasjeseasken. In ferlykbere thumbregel hâldt ek rekken mei dizze ferdieling by it sammeljen fan latencymetriken en it bepalen fan SLO's.

Wês bewust fan hege kardinaliteit by it sammeljen fan metriken foar elke operaasje. Brûk logs, sammeljen fan eveneminten, of ferspraat tracing om debuggen mei hege krêft te krijen. Yn it artikel "Wolle jo Latency debuggen?» kinne jo josels fertroud meitsje mei metoaden foar fertraging fan debuggen.

Nested transaksjes kinne gefaarlik wêze

Net elke DBMS stipet geneste transaksjes, mar as se dogge, kinne sokke transaksjes resultearje yn ûnferwachte flaters dy't net altyd maklik te ûntdekken binne (dat is, it moat fanselssprekkend wêze dat d'r wat soarte fan anomaly is).

Jo kinne it brûken fan geneste transaksjes foarkomme mei kliïntbiblioteken dy't se kinne ûntdekke en omgean. As nêste transaksjes net kinne wurde ferlitten, nim dan spesjale soarch yn har ymplemintaasje om unferwachte situaasjes te foarkommen wêr't foltôge transaksjes per ongelok wurde ôfbrutsen fanwege nêsten.

Encapsulating transaksjes yn ferskillende lagen kin liede ta ûnferwachte nested transaksjes, en út in koade lêsberens eachpunt, it kin meitsje it dreech om te begripen de skriuwer syn bedoelingen. Besjoch it folgjende programma:

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

Wat sil de útfier wêze fan 'e boppesteande koade? Sil it beide transaksjes weromdraaie, of allinich de binnenste? Wat bart der as wy fertrouwe op meardere lagen fan biblioteken dy't de skepping fan transaksjes foar ús ynkapselje? Sille wy sokke gefallen identifisearje en ferbetterje?

Stel jo in gegevenslaach foar mei meardere operaasjes (bgl. newAccount) is al ymplementearre yn har eigen transaksjes. Wat bart der as jo se útfiere as ûnderdiel fan bedriuwslogika op heger nivo dy't rint binnen har eigen transaksje? Wat soe it isolemint en konsistinsje wêze yn dit gefal?

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

Ynstee fan te sykjen nei antwurden op sokke einleaze fragen, is it better om geneste transaksjes te foarkommen. Jo gegevenslaach kin ommers maklik operaasjes op hege nivo's útfiere sûnder har eigen transaksjes te meitsjen. Derneist is de saaklike logika sels yn steat om in transaksje te begjinnen, operaasjes derop út te fieren, in transaksje te begean of ôfbrekke.

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.

Transaksjes moatte net wurde bûn oan tapassing tastân

Soms is it ferleidend om applikaasjestatus te brûken yn transaksjes om bepaalde wearden te feroarjen of queryparameters oan te passen. De krityske nuânse om te beskôgjen is it juste berik fan tapassing. Klanten begjinne faak transaksjes opnij as d'r netwurkproblemen binne. As de transaksje dan hinget ôf fan in steat dat wurdt feroare troch in oar proses, it kin kieze de ferkearde wearde ôfhinklik fan de mooglikheid fan in gegevens race. Transaksjes moatte beskôgje it risiko fan gegevens race betingsten yn de applikaasje.

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

De boppesteande transaksje sil it folchoardernûmer ferheegje elke kear as it wurdt útfierd, nettsjinsteande it definitive resultaat. As de commit mislearret troch netwurkproblemen, sil it fersyk útfierd wurde mei in oar folchoardernûmer as jo it nochris besykje.

Queryplanners kinne jo in protte fertelle oer in databank

Queryplanners bepale hoe't in query sil wurde útfierd yn in databank. Se analysearje ek oanfragen en optimalisearje se foardat se ferstjoere. Planners kinne allinich wat mooglike skattings leverje op basis fan 'e sinjalen dy't har beskikking hawwe. Wat is bygelyks de bêste sykmetoade foar de folgjende query?

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

De resultaten kinne op twa manieren weromhelle wurde:

  • Folsleine tafel scan: Jo kinne sjen op elke yngong yn 'e tabel en werom artikels mei in oerienkommende skriuwer namme, en dan bestelle se.
  • Index scan: Jo kinne in yndeks brûke om oerienkommende ID's te finen, dy rigen te krijen en se dan te bestellen.

De taak fan de queryplanner is om te bepalen hokker strategy it bêste is. It is it wurdich te beskôgjen dat queryplanners allinich beheinde foarsizzende mooglikheden hawwe. Dit kin liede ta minne besluten. DBA's as ûntwikkelders kinne se brûke om ûnderprestearjende fragen te diagnostearjen en te fine-tunen. Nije ferzjes fan 'e DBMS kinne queryplanners konfigurearje, en selsdiagnoaze kin helpe by it bywurkjen fan de databank as de nije ferzje liedt ta prestaasjesproblemen. Trage query-logboeken, rapporten oer latencyproblemen, of statistyk foar útfieringstiid kinne helpe om fragen te identifisearjen dy't optimisaasje nedich binne.

Guon metriken presintearre troch de queryplanner kinne ûnderwurpen wêze oan lûd (benammen by it skatten fan latency of CPU-tiid). In goede oanfolling oan planners binne ark foar it tracearjen en folgjen fan it útfieringspaad. Se tastean jo te diagnose sokke problemen (helaas, net alle DBMSs jouwe sokke ark).

Online migraasje is lestich, mar mooglik

Online migraasje, live migraasje, of real-time migraasje betsjut ferpleatse fan de iene database nei de oare sûnder downtime of data korrupsje. Live migraasje is makliker út te fieren as de oergong binnen deselde DBMS / motor bart. De situaasje wurdt komplisearre as it nedich is om te ferpleatsen nei in nije DBMS mei ferskillende prestaasjes en skema easken.

D'r binne ferskate online migraasjemodellen. Hjir is ien fan harren:

  • Aktivearje dûbele yngong yn beide databases. De nije databank op dit stadium hat net alle gegevens, mar akseptearret allinnich de lêste gegevens. As jo ​​​​ienris wis binne fan dit, kinne jo trochgean nei de folgjende stap.
  • Lêzen fan beide databases ynskeakelje.
  • Konfigurearje it systeem sadat it lêzen en skriuwen primêr wurde útfierd op 'e nije databank.
  • Stopje mei skriuwen nei de âlde databank wylst jo trochgean mei it lêzen fan gegevens derfan. Op dit stadium is de nije databank noch sûnder wat gegevens. Se moatte wurde kopiearre út de âlde databank.
  • De âlde databank is allinnich-lês. Kopiearje de ûntbrekkende gegevens fan 'e âlde databank nei de nije. Nei't de migraasje foltôge is, skeakelje de paden nei de nije databank, en stopje de âlde en wiskje it fan it systeem.

Foar oanfoljende ynformaasje advisearje ik kontakt te meitsjen artikel, dy't details oer Stripe's migraasjestrategy basearre op dit model.

In signifikante ferheging fan 'e database bringt in tanimming fan ûnfoarspelberens mei

De groei fan 'e databank liedt ta ûnfoarspelbere problemen ferbûn mei syn skaal. Hoe mear wy witte oer de ynterne struktuer fan in databank, hoe better wy kinne foarsizze hoe't it sil skaalfergrutsje. Guon mominten binne lykwols noch net te foarsjen.
As de basis groeit, kinne eardere oannames en ferwachtings oangeande datavolumint en netwurkbânbreedte easken ferâldere wurde. Dit is as de fraach ûntstiet fan grutte ûntwerpoverhauls, grutskalige operasjonele ferbetteringen, opnij betinken fan ynset, of migraasje nei oare DBMS's om potinsjele problemen te foarkommen.

Mar tink net dat poerbêste kennis fan 'e ynterne struktuer fan' e besteande databank it iennichste is dat nedich is. Nije skalen sille nije ûnbekenden mei har bringe. Unfoarspelbere pinepunten, unjildich gegevensferdieling, ûnferwachte bânbreedte en hardwareproblemen, hieltyd tanimmend ferkear en nije netwurksegminten sille jo twinge om jo databankoanpak, datamodel, ynsetmodel en databankgrutte opnij te tinken.

...

Op it stuit dat ik begon te tinken oer it publisearjen fan dit artikel, stiene der al fiif mear items op myn oarspronklike list. Doe kaam in grut oantal nije ideeën oer wat oars kin wurde behannele. Dêrom, it artikel rekket op de minste foar de hân lizzende problemen dy't easkje maksimale oandacht. Dit betsjut lykwols net dat it ûnderwerp útput is en ik sil der net mear nei weromkomme yn myn takomstige materialen en sil gjin wizigingen oanmeitsje oan it hjoeddeistige.

PS

Lês ek op ús blog:

Boarne: www.habr.com

Add a comment