Prijevod članka pripremljen je posebno za studente predmeta
PostgreSQL i postavke konzistentnosti pisanja specifične za vezu
U Composeu se bavimo mnogim bazama podataka, što nam daje priliku da se bolje upoznamo s njihovom funkcionalnošću i nedostacima. Kako učimo da volimo karakteristike novih baza podataka, ponekad počinjemo razmišljati kako bi bilo lijepo da su slične karakteristike prisutne u zrelijim alatima s kojima radimo već duže vrijeme. Jedna od novih karakteristika koju sam želio vidjeti u PostgreSQL-u bila je konfigurabilna konzistentnost pisanja za konekciju kroz cijeli klaster. I kako se ispostavilo, mi ga već imamo, a danas želimo s vama podijeliti informacije o tome kako ga možete koristiti.
Zašto mi treba?
Kako bi se klaster trebao ponašati ovisi o vašoj aplikaciji. Uzmimo, na primjer, aplikaciju za plaćanje računa. Trebat će vam XNUMX% konzistentnost u cijelom klasteru, tako da ćete morati omogućiti sinhrona urezivanja tako da vaša baza podataka čeka da se izvrše sve promjene. Međutim, ako je vaša aplikacija brzorastuća društvena mreža, vjerojatno ćete preferirati brzi odgovor od XNUMX% postojanosti. Da biste to postigli, možete koristiti asinkrona urezivanja u svom klasteru.
Upoznajte kompromis
Morate napraviti kompromise između konzistentnosti podataka i performansi. PostgreSQL se udaljava od konzistentnosti jer je tada zadana konfiguracija predvidljiva i bez neočekivanih iznenađenja. Pogledajmo sada kompromise.
Kompromis 1: Performanse
Ako PostgreSQL klaster ne zahtijeva konzistentnost, može raditi asinhrono. Zapisivanje se vrši vođi klastera, a ažuriranja će biti poslana na njegove replike nekoliko milisekundi kasnije. Kada PostgreSQL klaster zahtijeva konzistentnost, mora raditi sinhrono. Pisanje će biti izvršeno vođi klastera, koji će poslati ažuriranje replikama i čekati potvrdu da je svaka napisala prije slanja potvrde klijentu koji je pokrenuo upis da je uspješno. Praktična razlika između ovih pristupa je u tome što asinhrona metoda zahtijeva dva mrežna skoka, dok sinhrona metoda zahtijeva četiri.
Kompromis 2: Konzistentnost
Rezultat u slučaju neuspjeha lidera u ova dva pristupa također će biti drugačiji. Ako se posao izvodi asinhrono, onda ako dođe do takve greške, replike neće urezati sve zapise. Koliko će biti izgubljeno? Zavisi od same aplikacije i efikasnosti replikacije. Replikacija sastavljanja će spriječiti da replika postane vodeća ako je količina informacija u njoj 1 MB manja nego u lideru, odnosno, do 1 MB zapisa može biti izgubljeno tokom asinhronog rada.
Ovo se ne dešava u sinhronom režimu. Ako lider ne uspije, sve replike se ažuriraju, budući da svako upisivanje potvrđeno na lideru mora biti potvrđeno na replikama. Ovo je dosljednost.
Sinhrono ponašanje ima smisla u aplikaciji za naplatu gdje konzistentnost ima jasnu prednost u kompromisu između konzistentnosti i performansi. Najvažnija stvar za takvu aplikaciju su validni podaci. Sada razmislite o društvenoj mreži u kojoj je glavni zadatak zadržati pažnju korisnika tako što će odgovoriti na zahtjeve što je brže moguće. U ovom slučaju, performanse s manje mrežnih skokova i manje čekanja na urezivanje bit će prioritet. Međutim, kompromis između performansi i dosljednosti nije jedini o kojem morate razmišljati.
Kompromis 3: Padovi
Veoma je važno razumjeti kako se klaster ponaša tokom kvara. Razmotrite situaciju u kojoj jedna ili više replika ne uspije. Kada se urezivanje obrađuje asinhrono, vođa će nastaviti da funkcioniše, to jest, prihvata i obrađuje zapise, bez čekanja na nedostajuće replike. Kada se replike vrate u klaster, sustižu vođu. Kod sinhrone replikacije, ako replike ne odgovore, tada vođa neće imati izbora i nastavit će čekati potvrdu urezivanja dok se replika ne vrati u klaster i može prihvatiti i urezati upis.
Jedna veza po transakciji?
Svakoj aplikaciji je potrebna drugačija kombinacija konzistentnosti i performansi. Osim, naravno, ako se radi o našoj aplikaciji za plaćanje računa, za koju zamišljamo da je potpuno konzistentna, ili o našoj skoro efemernoj aplikaciji za društveno umrežavanje. U svim drugim slučajevima, biće trenutaka kada neke operacije moraju biti sinhrone, a neke asinhrone. Možda ne želite da sistem čeka dok se poruka poslata u chat ne izvrši, ali ako se uplata obrađuje u istoj aplikaciji, onda ćete morati pričekati.
Sve ove odluke, naravno, donosi programer aplikacije. Donošenje ispravnih odluka o tome kada koristiti svaki pristup pomoći će vam da izvučete maksimum iz svog klastera. Važno je da se programer može prebacivati između njih na SQL razini za veze i za transakcije.
Osiguravanje kontrole u praksi
PostgreSQL podrazumevano obezbeđuje doslednost. Ovo je kontrolirano parametrom servera synchronous_commit
. Podrazumevano je na poziciji on
, ali ima tri druge opcije: local
, remote_write
ili off
.
Prilikom postavljanja parametra na off
sva sinhrona urezivanja su zaustavljena, čak i na lokalnom sistemu. Lokalni parametar specificira sinhroni način rada za lokalni sistem, ali upisi u replike se izvode asinhrono. Remote_write
ide još dalje: upisi u replike se vrše asinhrono, ali se vraćaju kada replika prihvati upis, ali ga nije zapisala na disk.
Uzimajući u obzir raspoloživi raspon opcija, biramo ponašanje i, imajući to na umu on
– ovo su sinhroni snimci, mi ćemo izabrati local
za asinkrono urezivanje preko mreže, dok lokalno urezivanje ostavlja sinhronim.
Sada ćemo vam reći kako da ovo postavite za trenutak, ali zamislite da smo mi postavili synchronous_commit
в local
za server. Pitali smo se da li je moguće promijeniti parametar synchronous_commit
u hodu, a pokazalo se da je to ne samo moguće, već postoje čak dva načina da se to uradi. Prvi je da postavite sesiju vaše veze na sljedeći način:
SET SESSION synchronous_commit TO ON;
// Your writes go here
Sva naredna upisivanja u sesiji će potvrditi upisivanje u replike prije vraćanja pozitivnog rezultata povezanom klijentu. Osim ako, naravno, ne promijenite postavku synchronous_commit
opet. Možete izostaviti dio SESSION
u naredbi jer će biti u zadanoj vrijednosti.
Druga metoda je dobra kada samo želite da budete sigurni da ćete dobiti sinhronu replikaciju za jednu transakciju. U mnogim bazama podataka generisanja NoSQL koncept transakcija ne postoji, ali postoji u PostgreSQL-u. U ovom slučaju započinjete transakciju i zatim postavljate synchronous_commit
в on
prije izvršenja unosa za transakciju. COMMIT
će izvršiti transakciju koristeći bilo koju vrijednost parametra synchronous_commit
, koji je postavljen u to vrijeme, iako je najbolje postaviti varijablu unaprijed kako bi bili sigurni da drugi programeri razumiju da upisi nisu asinhroni.
BEGIN;
SET LOCAL synchronous_commit TO ON;
// Your writes go here
COMMIT;
Sva urezivanja transakcija će sada biti potvrđena kao napisana u replike prije nego što baza podataka vrati pozitivan odgovor povezanom klijentu.
Postavljanje PostgreSQL-a
Prije ovoga, zamislili smo PostgreSQL sistem sa synchronous_commit
, ugrađen u local
. Da bi ovo bilo realistično na strani servera, morat ćete postaviti dvije opcije konfiguracije servera. Još jedan parametar synchronous_standby_names
doći će na svoje kada synchronous_commit
bit će unutra on
. Određuje koje replike ispunjavaju uslove za sinkrono urezivanje, a mi ćemo ga postaviti na *
, što će značiti da su uključene sve replike. Ove vrijednosti se obično konfiguriraju u
synchronous_commit = local
synchronous_standby_names='*'
Postavljanjem parametra synchronous_commit
u značenje local
, kreiramo sistem u kojem lokalni diskovi ostaju sinhroni, ali urezivanja mrežne replike su po defaultu asinhrona. Osim ako, naravno, ne odlučimo da ove urezivanja učinimo sinhronim, kao što je gore prikazano.
Ako ste pratili razvoj
jos par rijeci...
Pre samo nedelju dana, rekao bih vam da je nemoguće tako fino podesiti PostgreSQL. Tada je Kurt, član tima platforme Compose, insistirao da takva prilika postoji. Umirio je moje prigovore i pronašao u dokumentaciji PostgreSQL-a
Ova postavka se može promijeniti u bilo kojem trenutku. Ponašanje za bilo koju transakciju je određeno postavkom koja je na snazi u vrijeme urezivanja. Stoga je moguće i korisno da se neke transakcije urezuju sinhrono, a druge asinhrono. Na primjer, prisiliti jednog multistatement
transakcija da izvrši asinhrono urezivanje kada je zadana vrijednost parametra suprotna, postavljeno SET LOCAL synchronous_commit TO OFF
u transakciji.
Ovom malom modifikacijom konfiguracionog fajla, dali smo korisnicima kontrolu nad njihovom konzistentnošću i performansama.
izvor: www.habr.com