Hoekom het jy dalk semi-sinchrone replikasie nodig?

Hi almal. Vladislav Rodin is in kontak. Ek gee tans kursusse oor sagteware-argitektuur en hoëspanningsagteware-argitektuur by OTUS. In afwagting van die begin van 'n nuwe kursusstroom "Hoë lading argitek" Ek het besluit om 'n kort stukkie oorspronklike materiaal te skryf wat ek met julle wil deel.

Hoekom het jy dalk semi-sinchrone replikasie nodig?

Inleiding

As gevolg van die feit dat die HDD slegs ongeveer 400-700 bewerkings per sekonde kan uitvoer (wat onvergelykbaar is met tipiese rps op 'n hoëladingstelsel), is die klassieke skyfdatabasis die bottelnek van die argitektuur. Daarom is dit nodig om spesiale aandag te skenk aan die skaalpatrone van hierdie berging.

Tans is daar 2 databasisskaalpatrone: replikasie en versplintering. Sharing laat jou toe om die skryfbewerking te skaal, en as gevolg daarvan die rps per skryf per bediener in jou groep te verminder. Replikasie laat jou toe om dieselfde ding te doen, maar met leesbewerkings. Dit is hierdie patroon waaraan hierdie artikel gewy word.

replikasie

As jy na replikasie op 'n baie hoë vlak kyk, is dit 'n eenvoudige ding: jy het een bediener gehad, daar was data daarop, en dan kon hierdie bediener nie meer die las van die lees van hierdie data hanteer nie. U voeg nog 'n paar bedieners by, sinchroniseer data oor alle bedieners, en die gebruiker kan vanaf enige bediener in u groepering lees.

Ten spyte van sy oënskynlike eenvoud, is daar verskeie opsies om verskeie implementerings van hierdie skema te klassifiseer:

  • Deur rolle in die groepering (meester-meester of meester-slaaf)
  • Deur voorwerpe wat gestuur is (rygebaseerd, stellinggebaseer of gemeng)
  • Volgens die nodus sinchronisasie meganisme

Vandag gaan ons met punt 3 handel.

Hoe vind 'n transaksieverbintenis plaas?

Hierdie onderwerp hou nie direk verband met replikasie nie; 'n aparte artikel kan daaroor geskryf word, maar aangesien verdere lees nutteloos is sonder om die transaksie-toewysingsmeganisme te verstaan, laat ek jou aan die mees basiese dinge herinner. 'n Transaksie-verbintenis vind in 3 fases plaas:

  1. Teken 'n transaksie by die databasislogboek aan.
  2. Die gebruik van 'n transaksie in 'n databasis-enjin.
  3. Bevestiging terug aan die kliënt dat die transaksie suksesvol toegepas is.

In verskillende databasisse kan hierdie algoritme nuanses hê: byvoorbeeld, in die InnoDB-enjin van die MySQL-databasis is daar 2 logs: een vir replikasie (binêre log), en die ander vir die instandhouding van ACID (ongedoen/herdoen log), terwyl dit in PostgreSQL is. daar is een logboek wat beide funksies verrig (skryf vooruit log = WAL). Maar wat hierbo aangebied word, is juis die algemene konsep, wat toelaat dat sulke nuanses nie in ag geneem word nie.

Sinchroniese (sinchroniese) replikasie

Kom ons voeg logika by om die ontvangde veranderinge aan die transaksie-toewysingsalgoritme te herhaal:

  1. Teken 'n transaksie by die databasislogboek aan.
  2. Die gebruik van 'n transaksie in 'n databasis-enjin.
  3. Stuur data na alle replikas.
  4. Ontvang bevestiging van alle replikas dat 'n transaksie daarop voltooi is.
  5. Bevestiging terug aan die kliënt dat die transaksie suksesvol toegepas is.

Met hierdie benadering kry ons 'n aantal nadele:

  • die kliënt wag dat die veranderinge op alle replikas toegepas word.
  • soos die aantal nodusse in die groep toeneem, verminder ons die waarskynlikheid dat die skryfbewerking suksesvol sal wees.

As alles min of meer duidelik is met die 1ste punt, dan is die redes vir die 2de punt die moeite werd om te verduidelik. As ons tydens sinchroniese replikasie nie 'n antwoord van ten minste een nodus ontvang nie, rol ons die transaksie terug. Dus, deur die aantal nodusse in die groep te verhoog, verhoog jy die waarskynlikheid dat 'n skryfbewerking sal misluk.

Kan ons wag vir bevestiging van slegs 'n sekere persentasie nodusse, byvoorbeeld vanaf 51% (kworum)? Ja, ons kan, maar in die klassieke weergawe word bevestiging van alle nodusse vereis, want dit is hoe ons volledige datakonsekwentheid in die groepering kan verseker, wat 'n ongetwyfelde voordeel van hierdie tipe replikasie is.

Asinchrone (asinkroniese) replikasie

Kom ons verander die vorige algoritme. Ons sal data "iets later" na die replikas stuur, en "iets later" sal die veranderinge op die replikas toegepas word:

  1. Teken 'n transaksie by die databasislogboek aan.
  2. Die gebruik van 'n transaksie in 'n databasis-enjin.
  3. Bevestiging terug aan die kliënt dat die transaksie suksesvol toegepas is.
  4. Stuur data na replikas en pas veranderinge daarop toe.

Hierdie benadering lei daartoe dat die cluster vinnig werk, want ons laat die kliënt nie wag dat die data die replikas bereik en selfs toegewyd is nie.

Maar die toestand om data op replikas te stort "iets later" kan lei tot die verlies van 'n transaksie, en tot die verlies van 'n transaksie wat deur die gebruiker bevestig is, want as die data nie tyd gehad het om gerepliseer te word nie, 'n bevestiging aan die kliënt oor die sukses van die operasie gestuur is, en die nodus waarheen die veranderinge aangekom het, het HDD neergestort, ons verloor die transaksie, wat kan lei tot baie onaangename gevolge.

Semisync replikasie

Uiteindelik kom ons by semi-sinchrone replikasie. Hierdie tipe replikasie is nie baie bekend of baie algemeen nie, maar dit is van groot belang omdat dit die voordele van beide sinchroniese en asinchrone replikasie kan kombineer.

Kom ons probeer om die 2 vorige benaderings te kombineer. Ons sal die kliënt nie lank hou nie, maar ons sal vereis dat die data gerepliseer word:

  1. Teken 'n transaksie by die databasislogboek aan.
  2. Die gebruik van 'n transaksie in 'n databasis-enjin.
  3. Stuur data na replikas.
  4. Ontvang bevestiging van die replika dat die veranderinge ontvang is (dit sal “iets later” toegepas word).
  5. Bevestiging terug aan die kliënt dat die transaksie suksesvol toegepas is.

Neem asseblief kennis dat met hierdie algoritme, transaksieverlies slegs plaasvind as beide die nodus wat die veranderinge ontvang en die replika node misluk. Die waarskynlikheid van so 'n mislukking word as laag beskou, en hierdie risiko's word aanvaar.

Maar met hierdie benadering is daar 'n moontlike risiko van spooklees. Kom ons stel ons die volgende scenario voor: in stap 4 het ons geen bevestiging van enige replika ontvang nie. Ons moet hierdie transaksie terugrol en nie 'n bevestiging aan die kliënt terugstuur nie. Aangesien die data in stap 2 toegepas is, is daar 'n tydgaping tussen die einde van stap 2 en die terugrol van die transaksie, waartydens parallelle transaksies veranderinge kan sien wat nie in die databasis behoort te wees nie.

Verloor-minder semisink replikasie

As jy 'n bietjie dink, kan jy net die stappe van die algoritme omkeer en die probleem van fantoomlesings in hierdie scenario oplos:

  1. Teken 'n transaksie by die databasislogboek aan.
  2. Stuur tans replikadata.
  3. Ontvang bevestiging van die replika dat die veranderinge ontvang is (dit sal “iets later” toegepas word).
  4. Die gebruik van 'n transaksie in 'n databasis-enjin.
  5. Bevestiging terug aan die kliënt dat die transaksie suksesvol toegepas is.

Nou pleeg ons veranderinge slegs as dit herhaal is.

Output

Soos altyd is daar geen ideale oplossings nie; daar is 'n stel oplossings, wat elkeen sy eie voor- en nadele het en geskik is om verskillende klasse probleme op te los. Dit is absoluut waar vir die keuse van 'n meganisme vir die sinchronisering van data in 'n gerepliseerde databasis. Die stel voordele wat semi-sinchroniese replikasie het, is so stewig en interessant dat dit as aandag waardig beskou kan word, ten spyte van die lae voorkoms daarvan.

Dis al. Sien jou by kursus!

Bron: will.com

Voeg 'n opmerking