Wêrom kinne jo semy-synchrone replikaasje nedich wêze?

Hoi allegearre. Vladislav Rodin is yn kontakt. Ik lear op it stuit kursussen oer Software Architecture en High-Stress Software Architecture by OTUS. Yn ôfwachting fan it begjin fan in nije kursus flow "High Load Architect" Ik besleat om in koart stikje orizjineel materiaal te skriuwen dat ik mei jo diele wol.

Wêrom kinne jo semy-synchrone replikaasje nedich wêze?

Ynlieding

Fanwegen it feit dat de HDD allinich sa'n 400-700 operaasjes per sekonde kin útfiere (wat net te fergelykjen is mei typyske rps foar in systeem mei hege lading), is de klassike skiifdatabank de knelpunt fan 'e arsjitektuer. Dêrom is it needsaaklik om spesjaal omtinken te jaan oan de skaalfergrutting fan dizze opslach.

Op it stuit binne d'r 2 skaalpatroanen foar databases: replikaasje en sharding. Sharding lit jo de skriuwoperaasje skaalje en, as gefolch, de rps per skriuw per server yn jo kluster ferminderje. Replikaasje kinne jo itselde ding dwaan, mar mei lêsoperaasjes. It is dit patroan dat dit artikel is wijd oan.

replikaasje

As jo ​​​​nei replikaasje op in heul heech nivo sjogge, is it in ienfâldich ding: jo hiene ien server, d'r wiene gegevens op, en dan koe dizze server net mear omgean mei de lading fan it lêzen fan dizze gegevens. Jo foegje noch in pear servers ta, syngronisearje gegevens oer alle servers, en de brûker kin lêze fan elke server yn jo kluster.

Nettsjinsteande syn skynbere ienfâld, binne d'r ferskate opsjes foar it klassifisearjen fan ferskate ymplemintaasjes fan dit skema:

  • Troch rollen yn it kluster (master-master of master-slave)
  • Troch ferstjoerde objekten (rige-basearre, statement-basearre of mingde)
  • Neffens de node syngronisaasje meganisme

Hjoed sille wy te krijen hawwe mei punt 3.

Hoe komt in transaksje commit foar?

Dit ûnderwerp is net direkt relatearre oan replikaasje; der kin in apart artikel oer skreaun wurde, mar om't fierdere lêzen nutteloos is sûnder it meganisme fan transaksje-begjin te begripen, lit my jo de meast basale dingen herinnerje. In transaksje commit bart yn 3 stadia:

  1. It oanmelden fan in transaksje nei it databanklog.
  2. It brûken fan in transaksje yn in databankmotor.
  3. Befêstiging werom te jaan oan de klant dat de transaksje mei sukses tapast is.

Yn ferskate databases kin dit algoritme nuânses hawwe: bygelyks yn 'e InnoDB-motor fan' e MySQL-database binne d'r 2 logs: ien foar replikaasje (binêr log), en de oare foar it behâld fan ACID (ûngedien meitsje / opnij dwaan), wylst yn PostgreSQL der is ien log dat útfiert beide funksjes (skriuwe foarút log = WAL). Mar wat hjirboppe presintearre is krekt it algemiene konsept, wêrtroch sokke nuânses net yn rekken brocht wurde kinne.

Syngroane (syngronisaasje) replikaasje

Litte wy logika tafoegje om de ûntfongen wizigingen te replikearjen oan it algoritme foar transaksje-commit:

  1. It oanmelden fan in transaksje nei it databanklog.
  2. It brûken fan in transaksje yn in databankmotor.
  3. It ferstjoeren fan gegevens nei alle replika's.
  4. Untfange befêstiging fan alle replika's dat in transaksje is foltôge op harren.
  5. Befêstiging werom te jaan oan de klant dat de transaksje mei sukses tapast is.

Mei dizze oanpak krije wy in oantal neidielen:

  • de kliïnt wachtet op de wizigingen dy't tapast wurde op alle replika's.
  • as it oantal knopen yn it kluster nimt ta, ferleegje wy de kâns dat de skriuwoperaasje suksesfol sil wêze.

As alles min of mear dúdlik is mei it 1e punt, dan binne de redenen foar it 2e punt it wurdich om te ferklearjen. As wy by syngroane replikaasje gjin antwurd krije fan op syn minst ien knooppunt, rôlje wy de transaksje werom. Sa, troch it fergrutsjen fan it oantal knopen yn it kluster, Jo fergrutsje de kâns dat in skriuwoperaasje sil mislearje.

Kinne wy ​​wachtsje op befêstiging fan mar in bepaald persintaazje knopen, bygelyks fan 51% (quorum)? Ja, wy kinne, mar yn 'e klassike ferzje is befêstiging fan alle knooppunten fereaske, om't dit is hoe't wy in folsleine gegevenskonsistinsje yn' e kluster kinne soargje, wat in sûnder twifel foardiel is fan dit type replikaasje.

Asynchronous (async) replikaasje

Litte wy it foarige algoritme feroarje. Wy stjoere gegevens nei de replika's "wat letter", en "wat letter" wurde de wizigingen tapast op 'e replika's:

  1. It oanmelden fan in transaksje nei it databanklog.
  2. It brûken fan in transaksje yn in databankmotor.
  3. Befêstiging werom te jaan oan de klant dat de transaksje mei sukses tapast is.
  4. It ferstjoeren fan gegevens nei replika's en it tapassen fan wizigingen dêrop.

Dizze oanpak liedt ta it feit dat it kluster fluch wurket, om't wy de kliïnt net wachtsje op 'e gegevens om de replika's te berikken en sels ynset te wurden.

Mar de betingst fan it dumpen fan gegevens op replika's "wat letter" kin liede ta it ferlies fan in transaksje, en ta it ferlies fan in transaksje befêstige troch de brûker, want as de gegevens gjin tiid hawwe om te replikearjen, in befêstiging oan 'e kliïnt oer it sukses fan 'e operaasje waard stjoerd, en it knooppunt dêr't de wizigingen oankamen ferûngelokke HDD, wy ferlieze de transaksje, wat kin liede ta tige onaangename gefolgen.

Semisync replikaasje

Uteinlik komme wy by semi-synchrone replikaasje. Dit type replikaasje is net heul bekend as heul gewoan, mar it is fan grut belang om't it de foardielen fan sawol syngroane as asynchrone replikaasje kombinearje kin.

Litte wy besykje de 2 foargeande oanpak te kombinearjen. Wy sille de kliïnt net lang hâlde, mar wy sille fereaskje dat de gegevens wurde replikearre:

  1. It oanmelden fan in transaksje nei it databanklog.
  2. It brûken fan in transaksje yn in databankmotor.
  3. It ferstjoeren fan gegevens nei replika's.
  4. Befêstiging ûntfange fan 'e replika dat de wizigingen binne ûntfongen (se sille "wat letter" wurde tapast).
  5. Befêstiging werom te jaan oan de klant dat de transaksje mei sukses tapast is.

Tink derom dat mei dit algoritme transaksjeferlies allinich foarkomt as sawol de knooppunt dy't de wizigingen ûntfangt as de replika-knooppunt mislearje. De kâns op sa'n mislearring wurdt beskôge as leech, en dizze risiko's wurde akseptearre.

Mar mei dizze oanpak is d'r in mooglik risiko fan fantomlêzingen. Lit ús it folgjende senario foarstelle: yn stap 4 hawwe wy gjin befêstiging krigen fan in replika. Wy moatte dizze transaksje weromdraaie en gjin befêstiging weromjaan oan de kliïnt. Sûnt de gegevens waarden tapast yn stap 2, der is in tiid gat tusken it ein fan stap 2 en it weromdraaien fan de transaksje, wêrby't parallelle transaksjes kinne sjen feroarings dy't net moatte wêze yn de databank.

Ferlieze-minder semisync replikaasje

As jo ​​​​in bytsje tinke, kinne jo de stappen fan it algoritme gewoan omkeare en it probleem fan fantomlêzingen reparearje yn dit senario:

  1. It oanmelden fan in transaksje nei it databanklog.
  2. Replikagegevens ferstjoere.
  3. Befêstiging ûntfange fan 'e replika dat de wizigingen binne ûntfongen (se sille "wat letter" wurde tapast).
  4. It brûken fan in transaksje yn in databankmotor.
  5. Befêstiging werom te jaan oan de klant dat de transaksje mei sukses tapast is.

No meitsje wy feroarings allinich as se replikeare binne.

konklúzje

Lykas altyd binne d'r gjin ideale oplossingen; d'r is in set fan oplossingen, elk fan dy hat syn eigen foardielen en neidielen en is geskikt foar it oplossen fan ferskate klassen fan problemen. Dit is perfoarst wier foar it kiezen fan in meganisme foar it syngronisearjen fan gegevens yn in replike databank. De set fan foardielen dy't semy-synchrone replikaasje hat is genôch solide en nijsgjirrich dat it kin wurde beskôge wurdich omtinken, nettsjinsteande syn lege prevalens.

Da's alles. Oant sjen by ferrin!

Boarne: www.habr.com

Add a comment