PostgreSQL og forbindelsesspecifikke skrivekonsistensindstillinger

Oversættelsen af ​​artiklen er udarbejdet specifikt til kursets studerende "Database". Interesseret i at udvikle sig i denne retning? Vi inviterer dig til Åben dag, hvor vi taler detaljeret om programmet, funktioner i onlineformatet, kompetencer og karrieremuligheder, der venter kandidater efter uddannelsen.

PostgreSQL og forbindelsesspecifikke skrivekonsistensindstillinger

PostgreSQL og forbindelsesspecifikke skrivekonsistensindstillinger
Hos Compose beskæftiger vi os med mange databaser, hvilket giver os mulighed for at blive mere fortrolige med deres funktionalitet og mangler. Efterhånden som vi lærer at elske funktionerne i nye databaser, begynder vi nogle gange at tænke på, hvor rart det ville være, hvis lignende funktioner var til stede i de mere modne værktøjer, vi har arbejdet med i lang tid. En af de nye funktioner, som jeg ønskede at se i PostgreSQL, var konfigurerbar skrivekonsistens pr. forbindelse på tværs af hele klyngen. Og som det viser sig, har vi det allerede, og i dag vil vi dele information med dig om, hvordan du kan bruge det.

Hvorfor har jeg brug for det?

Hvordan klyngen skal opføre sig afhænger af din applikation. Tag for eksempel en app til betaling af regninger. Du skal bruge XNUMX % konsistens på tværs af klyngen, så du bliver nødt til at aktivere synkrone commits, så din database venter på, at alle ændringer bliver foretaget. Men hvis din ansøgning er et hurtigt voksende socialt netværk, vil du sandsynligvis foretrække hurtig respons frem for XNUMX % konsistens. For at opnå dette kan du bruge asynkrone commits i din klynge.

Mød kompromis

Du skal foretage afvejninger mellem datakonsistens og ydeevne. PostgreSQL bevæger sig væk fra konsistens, fordi standardkonfigurationen så er forudsigelig og uden uventede overraskelser. Lad os nu se på kompromiserne.

Afvejning 1: Ydeevne

Hvis PostgreSQL-klyngen ikke kræver konsistens, kan den køre asynkront. Skrivningen foretages til klyngelederen, og opdateringer vil blive sendt til replikaerne nogle få millisekunder senere. Når en PostgreSQL-klynge kræver konsistens, skal den køre synkront. Skrivningen vil blive foretaget til klyngelederen, som sender en opdatering til replikaerne og venter på bekræftelse af, at hver enkelt har skrevet, før du sender en bekræftelse til den klient, der påbegyndte skrivningen, om, at den var vellykket. Den praktiske forskel mellem disse tilgange er, at den asynkrone metode kræver to netværkshop, mens den synkrone metode kræver fire.

Afvejning 2: Konsistens

Resultatet i tilfælde af et ledersvigt i disse to tilgange vil også være anderledes. Hvis arbejdet udføres asynkront, så hvis en sådan fejl opstår, vil ikke alle poster blive begået af replikaerne. Hvor meget vil gå tabt? Afhænger af selve applikationen og effektiviteten af ​​replikering. Compose-replikering forhindrer en replika i at blive en leder, hvis mængden af ​​information i den er 1 MB mindre end i lederen, det vil sige, at op til 1 MB poster potentielt kan gå tabt under asynkron drift.

Dette sker ikke i synkron tilstand. Hvis lederen fejler, opdateres alle replikaer, da enhver skrivning bekræftet på lederen skal bekræftes på replikaerne. Dette er konsistens.

Synkron adfærd giver mening i en faktureringsapplikation, hvor konsistens har en klar fordel i afvejningen mellem konsistens og ydeevne. Det vigtigste for en sådan applikation er gyldige data. Tænk nu på et socialt netværk, hvor hovedopgaven er at holde brugerens opmærksomhed ved at svare på anmodninger så hurtigt som muligt. I dette tilfælde vil ydeevne med færre netværkshop og mindre ventetid på commits være en prioritet. Afvejningen mellem ydeevne og konsistens er dog ikke den eneste, du skal tænke på.

Afvejning 3: Nedbrud

Det er meget vigtigt at forstå, hvordan en klynge opfører sig under en fiasko. Overvej en situation, hvor en eller flere replikaer fejler. Når commits behandles asynkront, vil lederen fortsætte med at fungere, dvs. acceptere og behandle skrivninger, uden at vente på manglende replikaer. Når replikaerne vender tilbage til klyngen, indhenter de lederen. Med synkron replikering, hvis replikaerne ikke reagerer, så har lederen intet valg og vil fortsætte med at vente på bekræftelse af commit, indtil replikaen vender tilbage til klyngen og kan acceptere og begå skrivningen.

Én forbindelse pr. transaktion?

Hver applikation har brug for en anden type kombination af konsistens og ydeevne. Medmindre det selvfølgelig er vores app til betaling af regninger, som vi forestiller os at være fuldstændig konsekvent, eller vores næsten flygtige sociale netværksapp. I alle andre tilfælde vil der være tidspunkter, hvor nogle operationer skal være synkrone, og nogle skal være asynkrone. Du vil måske ikke have, at systemet venter, indtil en besked sendt til chatten er begået, men hvis en betaling behandles i samme applikation, så bliver du nødt til at vente.

Alle disse beslutninger træffes selvfølgelig af applikationsudvikleren. At træffe de rigtige beslutninger om, hvornår du skal bruge hver enkelt tilgang, vil hjælpe dig med at få mest muligt ud af din klynge. Det er vigtigt, at udvikleren kan skifte mellem dem på SQL-niveau for forbindelser og for transaktioner.

Sikring af kontrol i praksis

Som standard giver PostgreSQL konsistens. Dette styres af serverparameteren synchronous_commit. Som standard er den på plads on, men den har tre andre muligheder: local, remote_write eller off.

Når parameteren indstilles til off alle synkrone commits stoppes, selv på det lokale system. Den lokale parameter angiver synkron tilstand for det lokale system, men skrivning til replikaer udføres asynkront. Remote_write går endnu længere: skrivninger til replikaer foretages asynkront, men returneres, når replikaen har accepteret skrivningen, men ikke har skrevet den til disk.

Ved at overveje det tilgængelige udvalg af muligheder, vælger vi en adfærd og huske på det on – det er synkrone optagelser, vil vi vælge local for asynkrone commits over netværket, mens lokale commits efterlades synkrone.

Nu fortæller vi dig, hvordan du konfigurerer dette om et øjeblik, men forestil dig, at vi sætter det op synchronous_commit в local for serveren. Vi spekulerede på, om det var muligt at ændre parameteren synchronous_commit på farten, og det viste sig, at det ikke kun er muligt, der er endda to måder at gøre dette på. Den første er at indstille sessionen for din forbindelse som følger:

SET SESSION synchronous_commit TO ON;  
// Your writes go here

Alle efterfølgende skrivninger i sessionen vil bekræfte skrivninger til replikaerne, før de returnerer et positivt resultat til den tilsluttede klient. Medmindre du selvfølgelig ændrer indstillingen synchronous_commit en gang til. Du kan undlade en del SESSION i kommandoen, fordi den vil være i standardværdien.

Den anden metode er god, når du bare vil sikre dig, at du får synkron replikering for en enkelt transaktion. I mange NoSQL-generationsdatabaser eksisterer begrebet transaktioner ikke, men det gør det i PostgreSQL. I dette tilfælde starter du en transaktion og indstiller derefter synchronous_commit в on før du udfører indtastningen af ​​transaktionen. COMMIT vil begå transaktionen ved hjælp af en hvilken som helst parameterværdi synchronous_commit, som blev indstillet på det tidspunkt, selvom det er bedst at indstille variablen på forhånd for at sikre, at andre udviklere forstår, at skrivninger ikke er asynkrone.

BEGIN;  
SET LOCAL synchronous_commit TO ON;  
// Your writes go here
COMMIT;  

Alle transaktionsbekræftelser vil nu blive bekræftet som skrevet til replikaer, før databasen returnerer et positivt svar til den tilsluttede klient.

Konfiguration af PostgreSQL

Før dette forestillede vi os et PostgreSQL-system med synchronous_commit, installeret i local. For at gøre dette realistisk på serversiden skal du indstille to serverkonfigurationsmuligheder. Endnu et parameter synchronous_standby_names vil komme til sin ret hvornår synchronous_commit vil være med on. Det bestemmer, hvilke replikaer der er kvalificerede til synkrone commits, og vi indstiller det til *, hvilket vil betyde, at alle replikaer er involveret. Disse værdier er normalt konfigureret i konfigurationsfil ved at tilføje:

synchronous_commit = local  
synchronous_standby_names='*'

Ved at indstille parameteren synchronous_commit i betydning local, opretter vi et system, hvor lokale diske forbliver synkrone, men netværksreplika-commits er asynkrone som standard. Medmindre vi selvfølgelig beslutter at gøre disse commits synkrone, som vist ovenfor.

Hvis du har fulgt udviklingen Guvernørprojekt, du har muligvis bemærket nogle nylige ændringer (1, 2), som gjorde det muligt for Governor-brugere at teste disse parametre og overvåge deres konsistens.

Et par ord mere...

For bare en uge siden ville jeg have fortalt dig, at det er umuligt at finjustere PostgreSQL så fint. Det var da Kurt, et medlem af Compose-platformsteamet, insisterede på, at en sådan mulighed eksisterede. Han beroligede mine indvendinger og fandt i PostgreSQL-dokumentationen følgende::

PostgreSQL og forbindelsesspecifikke skrivekonsistensindstillinger

Denne indstilling kan til enhver tid ændres. Adfærden for enhver transaktion bestemmes af den indstilling, der er gældende på tidspunktet for forpligtelsen. Derfor er det muligt og nyttigt for nogle transaktioner at forpligte sig synkront og for andre asynkront. For eksempel at tvinge en multistatement transaktion for at foretage commits asynkront, når standardværdien af ​​parameteren er modsat, indstillet SET LOCAL synchronous_commit TO OFF i en transaktion.

Med denne lille ændring af konfigurationsfilen gav vi brugerne kontrol over deres konsistens og ydeevne.

Kilde: www.habr.com

Tilføj en kommentar