ĂversĂ€ttningen av artikeln Ă€r sĂ€rskilt utarbetad för studenter i kursen . Ăr du intresserad av att utvecklas inom detta omrĂ„de? Vi inbjuder dig till , dĂ€r vi gĂ„r igenom programmet, funktionerna i onlineformatet, kompetenserna och karriĂ€rmöjligheterna som vĂ€ntar studenter efter avslutad utbildning.

PostgreSQL och instÀllningar för skrivkonsistens för varje specifik anslutning
Hos Compose hanterar vi mÄnga databaser, vilket ger oss möjlighet att lÀra kÀnna deras funktionalitet och brister. NÀr vi lÀr oss att uppskatta de funktionella egenskaperna hos nya databaser, börjar vi ibland tÀnka pÄ hur bra det skulle vara om sÄdana funktioner ocksÄ fanns i mer mogna verktyg vi redan har arbetat lÀnge med. En av de nya funktionerna som vi ville se i PostgreSQL var anpassningsbar skrivkonsistens per anslutning i hela klustret. Och som det visade sig har vi redan den funktionen, och idag vill vi dela med oss av information om hur du kan anvÀnda den.
Varför skulle jag behöva detta?
Hur ett kluster ska bete sig beror pÄ din applikation. LÄt oss ta ett exempel med en faktureringsapplikation. Du kommer att behöva hundraprocentig konsistens i klustret, sÄ du mÄste aktivera synkrona commits sÄ att din databas vÀntar tills alla Àndringar har registrerats. Men om din applikation Àr ett snabbt vÀxande socialt nÀtverk, föredrar du förmodligen snabb respons snarare Àn hundraprocentig konsistens. För att uppnÄ detta kan du anvÀnda asynkrona commits i ditt kluster.
LÄt oss introducera kompromissen
Du mÄste göra en kompromiss mellan datakonsistens och prestanda. PostgreSQL rör sig bort frÄn konsistens, eftersom standardkonfigurationen dÄ blir förutsÀgbar och utan ovÀntade överraskningar. Och nu ska vi bekanta oss med kompromisserna.
Kompromiss 1: Prestanda
Om PostgreSQL-klustret inte behöver konsistens kan det fungera asynkront. Skrivning görs till klustrets ledare, och dess repliker fÄr uppdateringar efter nÄgra millisekunder. NÀr PostgreSQL-klustret krÀver konsistens mÄste det fungera synkront. Skrivning kommer att göras i klustrets ledare, som skickar uppdateringen till replikerna och vÀntar pÄ bekrÀftelse frÄn varje replika att den har genomfört skrivningen, innan den skickar bekrÀftelsen till klienten som initierade skrivningen om att den har genomförts framgÄngsrikt. Den praktiska skillnaden mellan dessa tillvÀgagÄngssÀtt Àr att den asynkrona metoden krÀver tvÄ nÀtverkshopp, medan den synkrona krÀver fyra.
Kompromiss 2: Konsistens
Resultatet vid ett fel i ledaren i dessa tvÄ tillvÀgagÄngssÀtt kommer ocksÄ att vara olika. Om arbetet utförs asynkront, kommer inte alla skrivningar att bekrÀftas av replikerna vid ett sÄdant fel. Hur mycket kommer gÄ förlorat? Det beror pÄ sjÀlva applikationen och effektiviteten i replikationen. Compose-replikeringen förhindrar att en replika blir ledare om mÀngden information i den Àr 1 MB mindre Àn i ledaren, vilket innebÀr att upp till 1 MB skrivningar potentiellt kan gÄ förlorade vid asynkront arbete.
I synkront lÀge sker detta inte. Om ledaren fallerar, uppdateras alla repliker eftersom varje skrivning som bekrÀftats pÄ ledaren mÄste bekrÀftas i replikerna. Det hÀr Àr konsistensen.
Synkront beteende Àr meningsfullt att anvÀnda i en applikation för rÀkning, dÀr konsistens har en uppenbar fördel i strÀvan att hitta en kompromiss mellan konsistens och prestanda. Det viktigaste för en sÄdan applikation Àr giltiga data. TÀnk nu pÄ ett socialt nÀtverk, dÀr huvuduppgiften Àr att behÄlla anvÀndarens uppmÀrksamhet genom att svara pÄ förfrÄgningar sÄ snabbt som möjligt. I sÄdana fall kommer prestanda med fÀrre nÀtverkshopp och mindre vÀntetid för commits att prioriteras. Men kompromissen mellan prestanda och konsistens Àr inte den enda som man behöver tÀnka pÄ.
Kompromiss 3: Fel
Det Àr mycket viktigt att förstÄ hur en kluster beter sig vid fel. LÄt oss tÀnka oss en situation dÀr en eller flera repliker slutar fungera. NÀr förÀndringar hanteras asynkront kommer ledaren att fortsÀtta fungera, det vill sÀga ta emot och bearbeta poster utan att vÀnta pÄ de saknade replikarna. NÀr replikarna ÄtervÀnder till klustret kommer de att komma ikapp ledaren. Vid synkron replikering, om replikarna inte svarar, har ledaren inget val utan kommer att fortsÀtta vÀnta pÄ bekrÀftelse av Ätagandet tills replikarna ÄtervÀnder till klustret och kan ta emot och bekrÀfta posten.
En anslutning per transaktion?
Varje applikation behöver en speciell typ av kombination av konsistens och prestanda. Om den inte Àr vÄr faktureringsapplikation, som vi förestÀller oss som helt konsistent, eller vÄr nÀstan flyktiga sociala medieapp. I alla andra fall kommer det att finnas stunder nÀr vissa operationer mÄste vara synkrona och andra asynkrona. Du kanske inte vill att systemet ska vÀnta tills ett meddelande som skickats i chatten har bekrÀftats, men om en betalning görs i samma applikation, mÄste det vÀnta.
Alla dessa beslut tas sjÀlvklart av applikationsutvecklaren. RÀtt beslut om nÀr man ska anvÀnda den ena eller andra metoden kommer att hjÀlpa till att utnyttja klustret maximalt. Det Àr viktigt att utvecklaren kan vÀxla mellan dem pÄ SQL-nivÄ för anslutningar och transaktioner.
Att sÀkerstÀlla kontroll i praktiken
Som standard sÀkerstÀller PostgreSQL konsistens. Detta kontrolleras av serversparametern synchronous_commit. Som standard ligger den i lÀget on, men den har tre andra alternativ: local, remote_write eller off.
NÀr parametern stÀlls in pÄ off stoppas alla synkrona Ätaganden, Àven i det lokala systemet. Parametern i local definierar det synkrona lÀget för det lokala systemet, men poster skrivs till replikarna asynkront. Remote_write gÄr Ànnu lÀngre: poster skrivs till replikarna asynkront, men returneras nÀr replican har tagit emot posten, men inte skrivit den pÄ disk.
Genom att övervĂ€ga de tillgĂ€ngliga alternativen vĂ€ljer vi beteendet och med tanke pĂ„ att on â det Ă€r synkrona poster, kommer vi att vĂ€lja local för asynkrona Ă„taganden över nĂ€tverket, medan lokala Ă„taganden förblir synkrona.
Nu ska vi berÀtta för dig hur du stÀller in detta pÄ ett ögonblick, men förestÀll dig att vi har installerat synchronous_commit pÄ local servern. Vi undrade om det var möjligt att Àndra instÀllningen synchronous_commit i realtid, och det visade sig att det inte bara Àr möjligt, utan det finns till och med tvÄ sÀtt att göra det. Det första Àr att stÀlla in sessionen för din anslutning pÄ följande sÀtt:
SET SESSION synchronous_commit TO ON;
// Ditt skrivande hÀrAlla efterföljande skrivningar i sessionen kommer att bekrÀfta skrivoperationer för repliker innan de returnerar ett positivt resultat till den anslutna klienten. Om du förstÄs inte Àndrar instÀllningen synchronous_commit igen. Du kan utelÀmna delen SESSION i kommandot, eftersom den kommer att vara i standardvÀrdet.
Det andra sÀttet Àr bra om du bara vill vara sÀker pÄ att du fÄr synkron replikering för en enda transaktion. I mÄnga 'NoSQL'-databaser finns det ingen begrepp om transaktioner, men det finns en i PostgreSQL. I det hÀr fallet pÄbörjar du en transaktion och stÀller sedan in synchronous_commit pÄ on innan du utför skrivoperationen för transaktionen. COMMIT kommer att bekrÀfta transaktionen med vilket vÀrde parameter synchronous_commit, som var instÀllt vid den tidpunkten, Àven om det Àr bÀst att stÀlla in variabeln i förvÀg för att sÀkerstÀlla att andra utvecklare förstÄr att skrivningar inte Àr asynkrona.
BEGIN;
SET LOCAL synchronous_commit TO ON;
// Ditt skrivande hÀr
COMMIT; Alla transaktionskommittéer kommer nu att bekrÀftas som skrivna till repliker innan databasen returnerar ett positivt svar till den anslutna klienten.
InstÀllning av PostgreSQL
Tidigare har vi förestÀllt oss ett PostgreSQL-system med synchronous_commit, installerat pÄ local. För att detta ska vara verkligt pÄ serversidan mÄste du göra tvÄ serverkonfigurationsinstÀllningar. En annan parameter synchronous_standby_names trÀdde i kraft nÀr synchronous_commit Àr i on. Den definierar vilka repliker som har rÀtt till synkrona kommittéer, och vi kommer att stÀlla in den till *, vilket kommer att innebÀra att alla repliker Àr aktiverade. Dessa vÀrden justeras vanligtvis i genom att lÀgga till:
synchronous_commit = local
synchronous_standby_names='*'Genom att stÀlla in parametern synchronous_commit till vÀrdet local, skapar vi ett system dÀr lokala diskar förblir synkrona, men kommittéer av nÀtverksrepliker Àr asynkrona som standard. Om vi inte förstÄs beslutar att göra dessa kommittéer synkrona, som visat ovan.
Om du har följt utvecklingen av , du kanske har lagt mÀrke till nÄgra nyliga förÀndringar (, ), som har möjliggjort för anvÀndare av Governor att testa dessa alternativ och övervaka deras konsistens.
Lite merâŠ
För bara en vecka sedan skulle jag ha sagt att det var omöjligt att finjustera PostgreSQL sÄ noggrant. Just dÄ pÄpekade Kurt, en medlem av Compose-plattformsteamet, att det faktiskt Àr möjligt. Han tystade mina invÀndningar och hittade i PostgreSQL-dokumentationen :

Denna instĂ€llning kan Ă€ndras nĂ€r som helst. Beteendet för alla transaktioner bestĂ€ms av instĂ€llningen som gĂ€ller vid commit. DĂ€rför kan det vara bĂ„de möjligt och fördelaktigt att för vissa transaktioner effectueras commits synkront, medan för andra â asynkront. Till exempel, för att fĂ„ en multistatement transaktion att utföra commits asynkront nĂ€r standardvĂ€rdet motsĂ€tter sig detta, sĂ€tt: SET LOCAL synchronous_commit TO OFF i transaktionen.
Med en sÄdan liten modifiering i konfigurationsfilen har vi gett anvÀndarna möjlighet att styra sin konsistens och prestanda.
KĂ€lla: habr.com
