Miksi saatat tarvita puolisynkronista replikointia?

Hei kaikki. Vladislav Rodin on yhteydessä. Tällä hetkellä opetan kursseja ohjelmistoarkkitehtuurista ja korkean stressin ohjelmistoarkkitehtuurista OTUS:ssa. Uuden kurssivirran alkamista odotellessa "High Load Arkkitehti" Päätin kirjoittaa lyhyen palan alkuperäistä materiaalia, jonka haluan jakaa kanssasi.

Miksi saatat tarvita puolisynkronista replikointia?

Esittely

Koska kiintolevy pystyy suorittamaan vain noin 400-700 toimintoa sekunnissa (mikä on vertaansa vailla tyypilliseen korkean kuormituksen järjestelmän rps:ään), klassinen levytietokanta on arkkitehtuurin pullonkaula. Siksi on tarpeen kiinnittää erityistä huomiota tämän varaston skaalauskuvioihin.

Tällä hetkellä on olemassa kaksi tietokannan skaalausmallia: replikointi ja jakaminen. Jakamisen avulla voit skaalata kirjoitustoimintoa ja sen seurauksena pienentää rps-arvoa kirjoitusta kohti klusterin palvelinta kohti. Replikoinnin avulla voit tehdä saman asian, mutta lukuoperaatioilla. Tämä artikkeli on omistettu tälle mallille.

Replikointi

Jos katsot replikointia erittäin korkealla tasolla, se on yksinkertainen asia: sinulla oli yksi palvelin, sillä oli dataa, ja sitten tämä palvelin ei enää kestänyt näiden tietojen lukemisen kuormaa. Lisäät vielä pari palvelinta, synkronoit tiedot kaikkien palvelimien välillä, ja käyttäjä voi lukea miltä tahansa klusterisi palvelimelta.

Ilmeisestä yksinkertaisuudestaan ​​huolimatta on olemassa useita vaihtoehtoja tämän järjestelmän eri toteutusten luokitteluun:

  • Roolien mukaan klusterissa (isäntä-isäntä tai isäntä-orja)
  • Lähetettyjen objektien mukaan (rivipohjainen, lausekepohjainen tai sekoitettu)
  • Solmun synkronointimekanismin mukaan

Tänään käsittelemme kohtaa 3.

Miten tapahtumasitoumus tapahtuu?

Tämä aihe ei liity suoraan replikointiin, siitä voi kirjoittaa erillisen artikkelin, mutta koska jatkolukeminen on turhaa ilman transaktioiden sitoutumismekanismin ymmärtämistä, muistutan teitä perusasioista. Tapahtumasitoumus tapahtuu kolmessa vaiheessa:

  1. Tapahtuman kirjaaminen tietokannan lokiin.
  2. Tapahtuman käyttäminen tietokantakoneessa.
  3. Vahvistuksen palauttaminen asiakkaalle, että tapahtuma on toteutettu onnistuneesti.

Eri tietokannoista tällä algoritmilla voi olla vivahteita: esimerkiksi MySQL-tietokannan InnoDB-moottorissa on 2 lokia: toinen replikointia varten (binääriloki) ja toinen ACID:n ylläpitoa varten (undo/redo log), kun taas PostgreSQL:ssä on yksi loki, joka suorittaa molemmat toiminnot (kirjoita eteenpäin loki = WAL). Mutta se, mitä yllä on esitetty, on juuri yleinen käsite, jonka ansiosta tällaisia ​​vivahteita ei oteta huomioon.

Synkroninen (synkronoitu) replikointi

Lisätään logiikka vastaanotettujen muutosten replikoimiseksi tapahtuman vahvistusalgoritmiin:

  1. Tapahtuman kirjaaminen tietokannan lokiin.
  2. Tapahtuman käyttäminen tietokantakoneessa.
  3. Lähetetään tietoja kaikkiin replikoihin.
  4. Vahvistuksen vastaanottaminen kaikista replikoista, että tapahtuma on suoritettu niillä.
  5. Vahvistuksen palauttaminen asiakkaalle, että tapahtuma on toteutettu onnistuneesti.

Tällä lähestymistavalla saamme useita haittoja:

  • asiakas odottaa, että muutokset otetaan käyttöön kaikissa replikoissa.
  • Kun klusterin solmujen määrä kasvaa, vähennämme todennäköisyyttä, että kirjoitustoiminto onnistuu.

Jos kaikki on enemmän tai vähemmän selvää 1. pisteessä, niin syyt 2. kohtaan ovat selityksen arvoisia. Jos synkronisen replikoinnin aikana emme saa vastausta vähintään yhdeltä solmulta, peruutamme tapahtuman. Siten lisäämällä klusterin solmujen määrää lisäät kirjoitustoiminnon epäonnistumisen todennäköisyyttä.

Voimmeko odottaa vahvistusta vain tietystä prosenttiosuudesta solmuista, esimerkiksi 51 %:lta (päätösvaltaisuus)? Kyllä, voimme, mutta klassisessa versiossa vaaditaan vahvistus kaikista solmuista, koska näin voimme varmistaa klusterin tietojen täydellisen johdonmukaisuuden, mikä on tämän tyyppisen replikoinnin kiistaton etu.

Asynkroninen (asynkroninen) replikointi

Muokataan edellistä algoritmia. Lähetämme tiedot replikoihin "joskus myöhemmin", ja "joskus myöhemmin" muutokset otetaan käyttöön replikoissa:

  1. Tapahtuman kirjaaminen tietokannan lokiin.
  2. Tapahtuman käyttäminen tietokantakoneessa.
  3. Vahvistuksen palauttaminen asiakkaalle, että tapahtuma on toteutettu onnistuneesti.
  4. Tietojen lähettäminen replikoihin ja muutosten soveltaminen niihin.

Tämä lähestymistapa johtaa siihen, että klusteri toimii nopeasti, koska emme jätä asiakasta odottamaan tietojen saapuvan replikoihin ja jopa sitoutuneen.

Mutta ehto, jonka mukaan data kopioidaan replikoihin "joskus myöhemmin", voi johtaa tapahtuman menettämiseen ja käyttäjän vahvistaman tapahtuman menettämiseen, koska jos dataa ei ole ehtinyt replikoida, vahvistus asiakkaalle operaation onnistumisesta lähetettiin, ja solmu, johon muutokset saapuivat, kaatui kiintolevylle, menetämme tapahtuman, mikä voi johtaa erittäin epämiellyttäviin seurauksiin.

Semisync replikointi

Lopuksi päästään puolisynkroniseen replikointiin. Tämäntyyppinen replikointi ei ole kovin tunnettu tai kovin yleinen, mutta se on erittäin kiinnostava, koska se voi yhdistää sekä synkronisen että asynkronisen replikoinnin edut.

Yritetään yhdistää kaksi edellistä lähestymistapaa. Emme säilytä asiakasta pitkään, mutta vaadimme tietojen kopioimista:

  1. Tapahtuman kirjaaminen tietokannan lokiin.
  2. Tapahtuman käyttäminen tietokantakoneessa.
  3. Tietojen lähettäminen replikoihin.
  4. Vastaanotetaan vahvistus replikalta, että muutokset on vastaanotettu (ne otetaan käyttöön "joskus myöhemmin").
  5. Vahvistuksen palauttaminen asiakkaalle, että tapahtuma on toteutettu onnistuneesti.

Huomaa, että tällä algoritmilla tapahtuman menetys tapahtuu vain, jos sekä muutokset vastaanottava solmu että replikasolmu epäonnistuvat. Tällaisen epäonnistumisen todennäköisyyttä pidetään pienenä, ja nämä riskit hyväksytään.

Mutta tällä lähestymistavalla on mahdollista haamulukujen vaara. Kuvitellaan seuraava skenaario: vaiheessa 4 emme saaneet vahvistusta yhdeltäkään replikalta. Meidän on peruutettava tämä tapahtuma, emmekä saa palauttaa vahvistusta asiakkaalle. Koska tiedot käytettiin vaiheessa 2, vaiheen 2 lopun ja tapahtuman peruutuksen välillä on aikaero, jonka aikana rinnakkaiset tapahtumat voivat nähdä muutoksia, joita ei pitäisi olla tietokannassa.

Häviötön puolisynkroninen replikointi

Jos ajattelet hieman, voit vain kääntää algoritmin vaiheet ja korjata haamulukujen ongelman tässä skenaariossa:

  1. Tapahtuman kirjaaminen tietokannan lokiin.
  2. Lähetetään replikatietoja.
  3. Vastaanotetaan vahvistus replikalta, että muutokset on vastaanotettu (ne otetaan käyttöön "joskus myöhemmin").
  4. Tapahtuman käyttäminen tietokantakoneessa.
  5. Vahvistuksen palauttaminen asiakkaalle, että tapahtuma on toteutettu onnistuneesti.

Nyt teemme muutoksia vain, jos ne on kopioitu.

johtopäätös

Kuten aina, ideaaliratkaisuja ei ole olemassa, on joukko ratkaisuja, joista jokaisella on omat etunsa ja haittansa ja jotka sopivat erilaisten ongelmien ratkaisemiseen. Tämä on täysin totta valittaessa mekanismi tietojen synkronointia varten replikoidussa tietokannassa. Puolisynkronisen replikoinnin etujen joukko on riittävän vankka ja mielenkiintoinen, jotta sitä voidaan pitää huomion arvoisena alhaisesta esiintyvyydestään huolimatta.

Siinä kaikki. Nähdään tietenkin!

Lähde: will.com

Lisää kommentti