Zašto bi vam mogla biti potrebna polusinkrona replikacija?

Bok svima. Javlja se Vladislav Rodin. Trenutačno predajem tečajeve o softverskoj arhitekturi i softverskoj arhitekturi visokog stresa na OTUS-u. U iščekivanju početka novog tečaja "Arhitekt visokog opterećenja" Odlučio sam napisati kratak izvorni materijal koji želim podijeliti s vama.

Zašto bi vam mogla biti potrebna polusinkrona replikacija?

Uvod

Zbog činjenice da HDD može izvesti samo oko 400-700 operacija u sekundi (što je neusporedivo s tipičnim rps-om na visokoopterećenom sustavu), klasična diskovna baza podataka je usko grlo arhitekture. Stoga je potrebno obratiti posebnu pozornost na obrasce skaliranja ove pohrane.

Trenutno postoje 2 obrasca skaliranja baze podataka: replikacija i dijeljenje. Sharding vam omogućuje skaliranje operacije pisanja i, kao rezultat toga, smanjenje broja okretaja u sekundi po pisanju po poslužitelju u vašem klasteru. Replikacija vam omogućuje da učinite istu stvar, ali s operacijama čitanja. Upravo je ovom uzorku posvećen ovaj članak.

Replikacija

Ako promatrate replikaciju na vrlo visokoj razini, to je jednostavna stvar: imali ste jedan poslužitelj, na njemu su bili podaci, a onda se ovaj poslužitelj više nije mogao nositi s opterećenjem čitanja tih podataka. Dodate još nekoliko poslužitelja, sinkronizirate podatke na svim poslužiteljima i korisnik može čitati s bilo kojeg poslužitelja u vašem klasteru.

Unatoč prividnoj jednostavnosti, postoji nekoliko opcija za klasifikaciju različitih implementacija ove sheme:

  • Po ulogama u klasteru (master-master ili master-slave)
  • Poslani objekti (na temelju retka, na temelju izjave ili mješovito)
  • Prema mehanizmu sinkronizacije čvora

Danas ćemo se baviti točkom 3.

Kako se izvršava transakcija?

Ova tema nije izravno povezana s replikacijom; o njoj se može napisati poseban članak, ali budući da je daljnje čitanje beskorisno bez razumijevanja mehanizma predaje transakcije, dopustite mi da vas podsjetim na najosnovnije stvari. Obaveza transakcije odvija se u 3 faze:

  1. Zapisivanje transakcije u zapisnik baze podataka.
  2. Korištenje transakcije u motoru baze podataka.
  3. Vraćanje potvrde klijentu da je transakcija uspješno primijenjena.

U različitim bazama podataka ovaj algoritam može imati nijanse: na primjer, u InnoDB pogonu MySQL baze podataka postoje 2 dnevnika: jedan za replikaciju (binarni dnevnik), a drugi za održavanje ACID-a (poništavanje/ponovljenje dnevnika), dok u PostgreSQL postoji jedan dnevnik koji obavlja obje funkcije (pisati unaprijed dnevnik = WAL). Ali ono što je gore predstavljeno upravo je opći koncept koji dopušta da se takve nijanse ne uzmu u obzir.

Sinkrona (sinkrona) replikacija

Dodajmo logiku za repliciranje primljenih promjena u algoritam izvršenja transakcije:

  1. Zapisivanje transakcije u zapisnik baze podataka.
  2. Korištenje transakcije u motoru baze podataka.
  3. Slanje podataka svim replikama.
  4. Primanje potvrde od svih replika da je na njima izvršena transakcija.
  5. Vraćanje potvrde klijentu da je transakcija uspješno primijenjena.

Ovim pristupom dobivamo niz nedostataka:

  • klijent čeka da se promjene primijene na sve replike.
  • kako se broj čvorova u klasteru povećava, smanjujemo vjerojatnost da će operacija pisanja biti uspješna.

Ako je s 1. točkom sve više-manje jasno, onda razloge za 2. točku vrijedi objasniti. Ako tijekom sinkrone replikacije ne primimo odgovor od barem jednog čvora, vratit ćemo transakciju. Stoga, povećanjem broja čvorova u klasteru, povećavate vjerojatnost da operacija pisanja neće uspjeti.

Možemo li čekati potvrdu od samo određenog postotka čvorova, npr. od 51% (kvorum)? Da, možemo, ali u klasičnoj verziji potrebna je potvrda sa svih čvorova, jer tako možemo osigurati potpunu konzistentnost podataka u klasteru, što je nedvojbena prednost ove vrste replikacije.

Asinkrona (asinhrona) replikacija

Modificirajmo prethodni algoritam. Poslat ćemo podatke replikama “nekad kasnije”, a “nekad kasnije” promjene će se primijeniti na replike:

  1. Zapisivanje transakcije u zapisnik baze podataka.
  2. Korištenje transakcije u motoru baze podataka.
  3. Vraćanje potvrde klijentu da je transakcija uspješno primijenjena.
  4. Slanje podataka replikama i primjena promjena na njih.

Ovaj pristup dovodi do činjenice da klaster radi brzo, jer ne ostavljamo klijenta da čeka da podaci dođu do replika, pa čak i da budu predani.

Ali uvjet ispisivanja podataka na replike "nekad kasnije" može dovesti do gubitka transakcije i do gubitka transakcije koju je potvrdio korisnik, jer ako podaci nisu imali vremena za repliciranje, potvrda klijentu o uspješnosti operacije je poslano, a čvor na koji su stigle promjene srušio HDD, gubimo transakciju, što može dovesti do vrlo neugodnih posljedica.

Polusinkronizirana replikacija

Konačno dolazimo do polu-sinkrone replikacije. Ova vrsta replikacije nije dobro poznata niti vrlo uobičajena, ali je od velikog interesa jer može kombinirati prednosti i sinkrone i asinkrone replikacije.

Pokušajmo kombinirati prethodna dva pristupa. Nećemo dugo zadržati klijenta, ali ćemo zahtijevati da se podaci repliciraju:

  1. Zapisivanje transakcije u zapisnik baze podataka.
  2. Korištenje transakcije u motoru baze podataka.
  3. Slanje podataka u replike.
  4. Primanje potvrde od replike da su promjene primljene (primijenit će se “kasnije”).
  5. Vraćanje potvrde klijentu da je transakcija uspješno primijenjena.

Imajte na umu da s ovim algoritmom do gubitka transakcije dolazi samo ako i čvor koji prima promjene i replika čvora zakažu. Vjerojatnost takvog kvara smatra se niskom i ti su rizici prihvaćeni.

Ali s ovim pristupom postoji mogući rizik od fantomskih očitavanja. Zamislimo sljedeći scenarij: u koraku 4 nismo primili potvrdu ni od jedne replike. Moramo vratiti ovu transakciju i ne vratiti potvrdu klijentu. Budući da su podaci primijenjeni u koraku 2, postoji vremenski razmak između kraja koraka 2 i vraćanja transakcije, tijekom kojeg paralelne transakcije mogu vidjeti promjene koje ne bi trebale biti u bazi podataka.

Polusinkronizirana replikacija bez gubitka

Ako malo razmislite, možete samo obrnuti korake algoritma i riješiti problem fantomskih čitanja u ovom scenariju:

  1. Zapisivanje transakcije u zapisnik baze podataka.
  2. Slanje podataka replike.
  3. Primanje potvrde od replike da su promjene primljene (primijenit će se “kasnije”).
  4. Korištenje transakcije u motoru baze podataka.
  5. Vraćanje potvrde klijentu da je transakcija uspješno primijenjena.

Sada uređujemo promjene samo ako su replicirane.

Izlaz

Kao i uvijek, ne postoje idealna rješenja; postoji skup rješenja, od kojih svako ima svoje prednosti i nedostatke i prikladno je za rješavanje različitih klasa problema. Ovo apsolutno vrijedi za odabir mehanizma za sinkronizaciju podataka u repliciranoj bazi podataka. Skup prednosti koje ima polusinkrona replikacija dovoljno je solidan i zanimljiv da se može smatrati vrijednim pažnje, unatoč maloj rasprostranjenosti.

To je sve. Vidimo se u tečaj!

Izvor: www.habr.com

Dodajte komentar