PostgreSQL și configurarea consistenței scrierii pentru fiecare conexiune specifică

Traducerea articolului a fost pregătită special pentru studenții cursului „Baze de Date”. Ești interesat să te dezvolți în acest domeniu? Te invităm la Ziua Porților Deschise, unde vom discuta în detaliu despre program, caracteristicile formatului online, competențele și perspectivele de carieră care așteaptă absolvenții după învățare.

PostgreSQL și configurarea consistenței scrierii pentru fiecare conexiune specifică

PostgreSQL și configurarea consistenței scrierii pentru fiecare conexiune specifică
La Compose ne ocupăm cu multe baze de date, ceea ce ne oferă oportunitatea de a cunoaște mai bine funcționalitățile și dezavantajele acestora. Pe măsură ce învățăm să iubim caracteristicile funcționale ale noilor baze de date, ne gândim adesea cum ar fi fost bine dacă astfel de funcții ar fi fost disponibile și în instrumentele mai mature cu care lucrăm de mult timp. Una dintre noile caracteristici pe care ne-am dorit-o în PostgreSQL a fost consistența scrierii configurabilă pe conexiune în întregul cluster. Și, se pare, că deja o avem, iar astăzi vrem să împărtășim informații despre cum o poți folosi.

De ce mi-ar trebui asta?

Modul în care trebuie să se comporte clusterul depinde de aplicația ta. Să luăm, de exemplu, o aplicație pentru plăți. Vei avea nevoie de o consistență de sută la sută în cluster, prin urmare va trebui să activezi comitetele sincrone, astfel încât baza ta de date să aștepte până când toate modificările sunt efectuate. Cu toate acestea, dacă aplicația ta este o rețea socială în rapidă dezvoltare, atunci cu siguranță vei prefera un răspuns rapid în detrimentul consistenței de sută la sută. Pentru a atinge acest obiectiv, poți utiliza comitetele asincrone în clusterul tău.

Întâlnește compromisurile

Va trebui să faci un compromis între consistența datelor și performanță. PostgreSQL avansează de la consistență, deoarece configurarea implicită în acest caz devine predictibilă, fără surprize neașteptate. Acum să ne familiarizăm cu compromisurile.

Compromis 1: Performanța

Dacă un cluster PostgreSQL nu necesită coerență, acesta poate funcționa complet asincron. Scrierea se face pe liderul clusterului, iar replicile sale vor primi actualizările după câteva milisecunde. Când clusterul PostgreSQL necesită coerență, acesta trebuie să funcționeze sincron. Scrierea se va face pe liderul clusterului, care va trimite replicilor actualizarea și va aștepta confirmarea că fiecare a efectuat scrierea, înainte de a trimite confirmarea clientului care a inițiat scrierea, că aceasta a avut succes. Diferența practică între aceste abordări este că metoda asincronă necesită două salturi prin rețea, iar cea sincronă – patru.

Compromisul 2: Coerența

Rezultatul în cazul unei defecțiuni a liderului în aceste două abordări va fi, de asemenea, diferit. Dacă operațiunea se desfășoară asincron, atunci în cazul unei astfel de erori, nu toate înregistrările vor fi confirmate de replici. Câte vor fi pierdute? Depinde de aplicația însăși și de eficiența replicării. Replicarea Compose va împiedica replica să devină lider în cazul în care cantitatea de informații din aceasta este cu 1 MB mai mică decât în lider, ceea ce înseamnă că pot fi potențial pierdute până la 1 MB de înregistrări în timpul funcționării asincrone.

În modul sincron, acest lucru nu se întâmplă. Dacă liderul eșuează, toate replicile sunt actualizate, deoarece orice înregistrare confirmată pe lider trebuie să fie confirmată în replici. Asta este coerența.

Comportamentul sincron are sens să fie folosit în aplicația pentru plată facturi, unde coerența are un avantaj evident în căutarea unui compromis între coerență și performanță. Ceea ce este cel mai important pentru o astfel de aplicație sunt datele valide. Și acum amintiți-vă de rețeaua socială, unde sarcina principală este de a captura atenția utilizatorului, răspunzând solicitărilor cât mai repede posibil. În acest caz, performanța cu un număr mai mic de salturi prin rețea și o așteptare mai mică a confirmărilor va fi prioritară. Totuși, compromisurile între performanță și coerență nu sunt singurele la care trebuie să ne gândim.

Compromisul 3: Defecțiuni

Este foarte important să înțelegem comportamentul unui cluster în timpul unei defecțiuni. Să luăm în considerare situația în care una sau mai multe replici eșuează. Atunci când comit-urile sunt procesate asincron, liderul va continua să funcționeze, adică va accepta și procesa înregistrări fără a aștepta replicile lipsă. Când replicile revin în cluster, acestea vor ajunge din urmă liderul. În cazul replicării sincrone, dacă replicile nu răspund, liderul nu va avea de ales și va continua să aștepte confirmarea comit-ului până când replica va reveni în cluster și va putea accepta și confirma înregistrarea.

Câte o conexiune pe tranzacție?

Fiecare aplicație are nevoie de un anumit tip de combinație între consistență și performanță. Cu excepția cazului în care este aplicația noastră pentru plăți, pe care o imaginăm complet consistentă, sau aplicația noastră aproape efemeră de socializare. În toate celelalte cazuri, vor fi momente în care unele operațiuni trebuie să fie sincrone, iar altele – asincrone. Nu vrei ca sistemul să aștepte până când un mesaj trimis în chat este comis, dar dacă în aceeași aplicație se desfășoară o plată, va trebui să aștepți.

Toate aceste decizii sunt, desigur, luate de dezvoltatorul aplicației. Deciziile corecte privind momentul de aplicare a unei metode sau al alteia vor ajuta la maximizarea performanței cluster-ului. Este important ca dezvoltatorul să poată comuta între acestea la nivel de SQL pentru conexiuni și tranzacții.

Asigurarea controlului în practică

În mod implicit, PostgreSQL asigură consistență. Acest lucru este controlat de parametrul serverului synchronous_commit. În mod implicit, acesta se află în poziția on, dar are trei alte opțiuni: local, remote_write sau off.

Atunci când parametrul este setat la off se opresc toate comit-urile sincrone, chiar și în sistemul local. Parametrul 'local' definește modul sincronic pentru sistemul local, dar înregistrările în replici se fac asincron. Remote_write merge și mai departe: înregistrările în replici se fac asincron, dar sunt returnate când replica a acceptat înregistrarea, dar nu a scris-o pe disc.

Examinând gama de opțiuni disponibile, alegem comportamentul și, având în vedere că on – acestea sunt înregistrări sincrone, vom alege local pentru comit-uri asincrone prin rețea, lăsând comit-urile locale sincrone.

Acum, vă vom arăta cum să configurați acest lucru într-o clipă, dar imaginați-vă că am instalat synchronous_commit în local pentru server. Ne-am întrebat dacă este posbil să schimbăm parametrul synchronous_commit din mers, și s-a dovedit că nu doar că este posibil, ci există chiar două moduri de a face asta. Primul este să setați sesiunea conexiunii dumneavoastră în următoarea manieră:

SET SESSION synchronous_commit TO ON;  
// Scrierile dumneavoastră aici

Toate înregistrările ulterioare din sesiune vor confirma operațiunile de scriere pentru replici, înainte de a returna un rezultat pozitiv clientului conectat. Desigur, cu condiția să nu schimbați din nou setarea synchronous_commit . Puteți omite partea SESSION din comandă, deoarece aceasta va fi la valoarea implicită.

Al doilea mod este bun atunci când doriți doar să vă asigurați că obțineți replicare sincronă pentru o singură tranzacție. În multe baze de date de generație „NoSQL” nu există concepte de tranzacții, dar acest lucru există în PostgreSQL. În acest caz, aveți nevoie să lansați o tranzacție și apoi să setați synchronous_commit în on înainte de a efectua înregistrarea pentru tranzacție. COMMIT va fixa tranzacția, folosind orice valoare a parametrului synchronous_commit, care a fost setată la acel moment, deși este cel mai bine să setați variabila dinainte, pentru a vă asigura că alți dezvoltatori înțeleg că înregistrările nu sunt asincrone.

BEGIN;  
SET LOCAL synchronous_commit TO ON;  
// Scrierile dumneavoastră aici
COMMIT;  

Toate comiturile tranzacțiilor vor fi acum confirmate, înainte ca baza de date să returneze un răspuns pozitiv clientului conectat.

Configurarea PostgreSQL

În trecut, ne-am imaginat un sistem PostgreSQL cu synchronous_commit, instalat în local. Pentru a fi real pe partea serverului, va trebui să setați două parametrii de configurare a serverului. Un alt parametru synchronous_standby_names va intra în vigoare când synchronous_commit va fi în on. Acesta definește ce replici au dreptul la comituri sincrone, și noi îl vom seta la *, ceea ce va însemna activarea tuturor replicilor. Aceste valori se configurează de obicei în fișierul de configurare prin adăugarea:

synchronous_commit = local  
synchronous_standby_names='*'

Setând parametrul synchronous_commit to the value local, creăm un sistem în care discurile locale rămân sincrone, dar comiturile replicilor de rețea sunt în mod implicit asincrone. Dacă, desigur, nu decid să facem aceste comituri sincrone, așa cum s-a arătat mai sus.

Dacă ați urmărit evoluția proiectului Governor, ați putea observa unele modificări recente (1, 2), care au permis utilizatorilor Governor să testeze aceste opțiuni și să le controleze coerența.

Încă câteva cuvinte...

Cu o săptămână în urmă, ți-aș fi spus că nu este posibil să ajustezi atât de fin PostgreSQL. Atunci Kurt, un membru al echipei platformei Compose, a insistat că există o astfel de posibilitate. El mi-a liniștit obiecțiile și a găsit în documentația PostgreSQL următoarele:

PostgreSQL și configurarea consistenței scrierii pentru fiecare conexiune specifică

Această opțiune poate fi modificată în orice moment. Comportamentul pentru orice tranzacție este determinat de setarea activă la momentul comiterii. Prin urmare, este posibil și util ca pentru unele tranzacții comiterea să se facă sincron sau pentru altele - asincron. De exemplu, pentru a forța o multistatement tranzacție să efectueze comiterea asincron, când valoarea implicită a parametrului este opusă, deși este stabilită SET LOCAL synchronous_commit TO OFF în tranzacție.

Prin această mică modificare în fișierul de configurare, am oferit utilizatorilor posibilitatea de a controla coerența și performanța lor.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster