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
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:
- Zapisivanje transakcije u zapisnik baze podataka.
- Korištenje transakcije u motoru baze podataka.
- 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:
- Zapisivanje transakcije u zapisnik baze podataka.
- Korištenje transakcije u motoru baze podataka.
- Slanje podataka svim replikama.
- Primanje potvrde od svih replika da je na njima izvršena transakcija.
- 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:
- Zapisivanje transakcije u zapisnik baze podataka.
- Korištenje transakcije u motoru baze podataka.
- Vraćanje potvrde klijentu da je transakcija uspješno primijenjena.
- 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:
- Zapisivanje transakcije u zapisnik baze podataka.
- Korištenje transakcije u motoru baze podataka.
- Slanje podataka u replike.
- Primanje potvrde od replike da su promjene primljene (primijenit će se “kasnije”).
- 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:
- Zapisivanje transakcije u zapisnik baze podataka.
- Slanje podataka replike.
- Primanje potvrde od replike da su promjene primljene (primijenit će se “kasnije”).
- Korištenje transakcije u motoru baze podataka.
- 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
Izvor: www.habr.com