Zakaj morda potrebujete polsinhrono podvajanje?

Pozdravljeni vsi skupaj. Vladislav Rodin je v stiku. Trenutno poučujem tečaje o arhitekturi programske opreme in arhitekturi programske opreme z visokim stresom na OTUS. V pričakovanju začetka novega tečaja "Arhitekt visoke obremenitve" Odločil sem se napisati kratek izvirni material, ki ga želim deliti z vami.

Zakaj morda potrebujete polsinhrono podvajanje?

Predstavitev

Zaradi dejstva, da lahko trdi disk izvede le okoli 400-700 operacij na sekundo (kar je neprimerljivo s tipičnimi rps za visoko obremenjen sistem), je klasična diskovna baza podatkov ozko grlo arhitekture. Zato je treba posebno pozornost posvetiti vzorcem skaliranja tega pomnilnika.

Trenutno obstajata 2 vzorca skaliranja baze podatkov: replikacija in razrez. Sharding vam omogoča, da povečate operacijo pisanja in posledično zmanjšate število vrtljajev na zapis na strežnik v vaši gruči. Replikacija vam omogoča, da naredite isto stvar, vendar z operacijami branja. Temu vzorcu je posvečen ta članek.

Podvajanje

Če pogledate replikacijo na zelo visoki ravni, je to preprosta stvar: imeli ste en strežnik, na njem so bili podatki, potem pa ta strežnik ni več zmogel bremena branja teh podatkov. Dodate še nekaj strežnikov, sinhronizirate podatke med vsemi strežniki in uporabnik lahko bere s katerega koli strežnika v vaši gruči.

Kljub navidezni preprostosti obstaja več možnosti za razvrščanje različnih izvedb te sheme:

  • Po vlogah v gruči (master-master ali master-slave)
  • Po poslanih predmetih (na podlagi vrstice, na podlagi izjave ali mešano)
  • Glede na mehanizem sinhronizacije vozlišča

Danes se bomo ukvarjali s 3. točko.

Kako pride do potrditve transakcije?

Ta tema ni neposredno povezana s podvajanjem; o njej je mogoče napisati ločen članek, a ker je nadaljnje branje neuporabno brez razumevanja mehanizma potrditve transakcije, naj vas spomnim na najbolj osnovne stvari. Zaveza transakcije poteka v treh fazah:

  1. Beleženje transakcije v dnevnik baze podatkov.
  2. Uporaba transakcije v motorju baze podatkov.
  3. Vrnitev potrditve stranki, da je bila transakcija uspešno uporabljena.

V različnih zbirkah podatkov ima lahko ta algoritem nianse: na primer, v mehanizmu InnoDB baze podatkov MySQL obstajata 2 dnevnika: eden za replikacijo (binarni dnevnik) in drugi za vzdrževanje ACID (dnevnik razveljavitve/ponovitve), medtem ko v PostgreSQL obstaja en dnevnik, ki opravlja obe funkciji (dnevnik pisanja naprej = WAL). Toda zgoraj predstavljeno je ravno splošen koncept, ki omogoča, da se takšne nianse ne upoštevajo.

Sinhrono (sinhrono) podvajanje

Dodajmo logiko za ponovitev prejetih sprememb v algoritem potrditve transakcije:

  1. Beleženje transakcije v dnevnik baze podatkov.
  2. Uporaba transakcije v motorju baze podatkov.
  3. Pošiljanje podatkov vsem replikam.
  4. Prejemanje potrditve od vseh replik, da je bila transakcija na njih opravljena.
  5. Vrnitev potrditve stranki, da je bila transakcija uspešno uporabljena.

S tem pristopom dobimo številne pomanjkljivosti:

  • odjemalec počaka, da se spremembe uporabijo za vse replike.
  • ko se število vozlišč v gruči poveča, zmanjšamo verjetnost, da bo operacija pisanja uspešna.

Če je s 1. točko vse bolj ali manj jasno, potem velja pojasniti razloge za 2. točko. Če med sinhrono replikacijo ne prejmemo odgovora od vsaj enega vozlišča, transakcijo vrnemo nazaj. Tako s povečanjem števila vozlišč v gruči povečate verjetnost, da operacija pisanja ne bo uspela.

Ali lahko čakamo na potrditev le določenega odstotka vozlišč, na primer od 51% (kvorum)? Da, lahko, vendar je v klasični različici potrebna potrditev iz vseh vozlišč, saj lahko tako zagotovimo popolno konsistentnost podatkov v gruči, kar je nedvomna prednost tovrstnega podvajanja.

Asinhrono (asinhrono) podvajanje

Spremenimo prejšnji algoritem. Podatke bomo replikam poslali »nekoč kasneje«, »nekoč pozneje« pa bodo spremembe uporabljene na replikah:

  1. Beleženje transakcije v dnevnik baze podatkov.
  2. Uporaba transakcije v motorju baze podatkov.
  3. Vrnitev potrditve stranki, da je bila transakcija uspešno uporabljena.
  4. Pošiljanje podatkov replikam in uveljavljanje sprememb na njih.

Ta pristop vodi k dejstvu, da gruča deluje hitro, ker odjemalca ne pustimo čakati, da podatki dosežejo replike in se celo potrdijo.

Toda pogoj za izpis podatkov na replike "nekoč pozneje" lahko privede do izgube transakcije in do izgube transakcije, ki jo potrdi uporabnik, ker če podatki niso imeli časa za replikacijo, potrditev stranki o uspešnosti operacije je bilo poslano in vozlišče, v katerega so prispele spremembe, se je zrušil HDD, izgubimo transakcijo, kar lahko povzroči zelo neprijetne posledice.

Polsinhrono podvajanje

Končno pridemo do polsinhronega podvajanja. Ta vrsta podvajanja ni dobro znana ali zelo pogosta, vendar je zelo zanimiva, saj lahko združuje prednosti sinhronega in asinhronega podvajanja.

Poskusimo združiti prejšnja dva pristopa. Odjemalca ne bomo obdržali dolgo, vendar bomo zahtevali, da se podatki podvojijo:

  1. Beleženje transakcije v dnevnik baze podatkov.
  2. Uporaba transakcije v motorju baze podatkov.
  3. Pošiljanje podatkov v replike.
  4. Prejem potrditve od replike, da so bile spremembe prejete (uveljavljene bodo »nekoč pozneje«).
  5. Vrnitev potrditve stranki, da je bila transakcija uspešno uporabljena.

Upoštevajte, da s tem algoritmom pride do izgube transakcije le, če vozlišče, ki prejema spremembe, in replika vozlišča ne uspeta. Verjetnost takšne okvare se šteje za majhno in ta tveganja so sprejeta.

Toda pri tem pristopu obstaja možno tveganje za fantomske odčitke. Predstavljajmo si naslednji scenarij: v 4. koraku nismo prejeli potrditve od nobene replike. To transakcijo moramo razveljaviti in stranki ne vrniti potrditve. Ker so bili podatki uporabljeni v 2. koraku, obstaja časovna vrzel med koncem 2. koraka in povrnitvijo transakcije, med katero lahko vzporedne transakcije opazijo spremembe, ki ne bi smele biti v bazi podatkov.

Polsinhronsko podvajanje brez izgube

Če malo premislite, lahko preprosto obrnete korake algoritma in odpravite težavo fantomskih branj v tem scenariju:

  1. Beleženje transakcije v dnevnik baze podatkov.
  2. Pošiljanje replike podatkov.
  3. Prejem potrditve od replike, da so bile spremembe prejete (uveljavljene bodo »nekoč pozneje«).
  4. Uporaba transakcije v motorju baze podatkov.
  5. Vrnitev potrditve stranki, da je bila transakcija uspešno uporabljena.

Zdaj potrdimo spremembe le, če so bile podvojene.

Izhod

Kot vedno idealnih rešitev ni, obstaja množica rešitev, od katerih ima vsaka svoje prednosti in slabosti ter je primerna za reševanje različnih razredov problemov. To povsem velja za izbiro mehanizma za sinhronizacijo podatkov v podvojeni bazi podatkov. Nabor prednosti, ki jih ima polsinhrona replikacija, je dovolj trden in zanimiv, da ga kljub nizki razširjenosti lahko štejemo za vrednega pozornosti.

To je vse. Se vidimo na seveda!

Vir: www.habr.com

Dodaj komentar