PostgreSQL a nastavenia konzistencie zápisu špecifické pre pripojenie

Preklad článku bol pripravený špeciálne pre študentov kurzu "databáza". Máte záujem rozvíjať sa týmto smerom? Pozývame vás na Deň otvorených dverí, kde podrobne hovoríme o programe, vlastnostiach online formátu, kompetenciách a kariérnych vyhliadkach, ktoré absolventov po zaškolení čakajú.

PostgreSQL a nastavenia konzistencie zápisu špecifické pre pripojenie

PostgreSQL a nastavenia konzistencie zápisu špecifické pre pripojenie
V Compose sa zaoberáme mnohými databázami, čo nám dáva možnosť bližšie sa zoznámiť s ich funkcionalitou a nedostatkami. Keď sa učíme milovať funkcie nových databáz, niekedy začneme premýšľať o tom, aké by bolo pekné, keby podobné funkcie boli prítomné aj v zrelších nástrojoch, s ktorými už dlho pracujeme. Jednou z nových funkcií, ktoré som chcel vidieť v PostgreSQL, bola konfigurovateľná konzistencia zápisu pre pripojenie v rámci celého klastra. A ako sa ukazuje, už ho máme a dnes sa s vami chceme podeliť o informácie, ako ho môžete využiť.

Prečo to potrebujem?

Ako by sa mal klaster správať, závisí od vašej aplikácie. Vezmite si napríklad aplikáciu na platbu faktúr. Budete potrebovať XNUMX% konzistenciu v celom klastri, takže budete musieť povoliť synchrónne odovzdania, aby vaša databáza čakala na vykonanie všetkých zmien. Ak je však vaša aplikácia rýchlo rastúca sociálna sieť, potom pravdepodobne uprednostníte rýchlu odozvu pred XNUMX% konzistentnosťou. Aby ste to dosiahli, môžete vo svojom klastri použiť asynchrónne odovzdania.

Zoznámte sa s kompromisom

Musíte robiť kompromisy medzi konzistenciou údajov a výkonom. PostgreSQL sa vzďaľuje od konzistentnosti, pretože predvolená konfigurácia je potom predvídateľná a bez neočakávaných prekvapení. Teraz sa pozrime na kompromisy.

Kompromis 1: Výkon

Ak klaster PostgreSQL nevyžaduje konzistenciu, môže bežať asynchrónne. Zápis sa vykoná do vedúceho klastra a aktualizácie budú odoslané do jeho replík o niekoľko milisekúnd neskôr. Keď klaster PostgreSQL vyžaduje konzistenciu, musí bežať synchrónne. Zápis sa vykoná vedúcemu klastra, ktorý odošle aktualizáciu replík a počká na potvrdenie, že každý napísal, a potom odošle klientovi, ktorý inicioval zápis, že zápis bol úspešný. Praktický rozdiel medzi týmito prístupmi je v tom, že asynchrónna metóda vyžaduje dva skoky v sieti, zatiaľ čo synchrónna metóda vyžaduje štyri.

Kompromis 2: Konzistentnosť

Rozdielny bude aj výsledok v prípade zlyhania lídra v týchto dvoch prístupoch. Ak sa práca vykonáva asynchrónne, potom ak dôjde k takejto chybe, nie všetky záznamy budú potvrdené replikami. Koľko sa stratí? Závisí od samotnej aplikácie a účinnosti replikácie. Komponovaná replikácia zabráni tomu, aby sa replika stala vedúcou, ak je množstvo informácií v nej o 1 MB menšie ako vo vedúcej časti, to znamená, že počas asynchrónnej operácie by sa potenciálne mohlo stratiť až 1 MB záznamov.

V synchrónnom režime sa to nestane. Ak vodiaca čiara zlyhá, všetky repliky sa aktualizujú, pretože každý zápis potvrdený na vodičke musí byť potvrdený na replikách. Toto je konzistencia.

Synchrónne správanie má zmysel vo fakturačnej aplikácii, kde má konzistentnosť jasnú výhodu v kompromise medzi konzistenciou a výkonom. Pre takúto aplikáciu sú najdôležitejšie platné údaje. Teraz premýšľajte o sociálnej sieti, v ktorej je hlavnou úlohou udržať pozornosť používateľa čo najrýchlejším odpovedaním na požiadavky. V tomto prípade bude prioritou výkon s menším počtom skokov v sieti a kratším čakaním na odovzdanie. Kompromis medzi výkonom a konzistentnosťou však nie je jediný, na ktorý musíte myslieť.

Kompromis 3: Pády

Je veľmi dôležité pochopiť, ako sa klaster správa počas zlyhania. Zvážte situáciu, keď jedna alebo viacero replík zlyhá. Keď sú odovzdania spracované asynchrónne, vodca bude naďalej fungovať, to znamená prijímať a spracovávať zápisy bez čakania na chýbajúce repliky. Keď sa repliky vrátia do zhluku, dobehnú vodcu. Ak pri synchrónnej replikácii repliky neodpovedajú, vedúci nebude mať na výber a bude naďalej čakať na potvrdenie potvrdenia, kým sa replika nevráti do klastra a nebude môcť prijať a potvrdiť zápis.

Jedno pripojenie na transakciu?

Každá aplikácia potrebuje iný typ kombinácie konzistencie a výkonu. Pokiaľ to samozrejme nie je naša aplikácia na platenie účtov, ktorú si predstavujeme ako úplne konzistentná, alebo naša takmer pominuteľná aplikácia na sociálne siete. Vo všetkých ostatných prípadoch nastanú situácie, keď niektoré operácie musia byť synchrónne a niektoré asynchrónne. Možno nebudete chcieť, aby systém čakal, kým sa odošle správa do chatu, ale ak je platba spracovaná v tej istej aplikácii, budete musieť počkať.

Všetky tieto rozhodnutia, samozrejme, robí vývojár aplikácie. Správne rozhodnutia o tom, kedy použiť jednotlivé prístupy, vám pomôžu vyťažiť z vášho klastra maximum. Je dôležité, aby medzi nimi mohol vývojár prepínať na úrovni SQL pre pripojenia a pre transakcie.

Zabezpečenie kontroly v praxi

PostgreSQL štandardne poskytuje konzistenciu. Toto je riadené parametrom servera synchronous_commit. Štandardne je na pozícii on, ale má tri ďalšie možnosti: local, remote_write alebo off.

Pri nastavovaní parametra na off všetky synchrónne odovzdania sú zastavené, dokonca aj na lokálnom systéme. Lokálny parameter určuje synchrónny režim pre lokálny systém, ale zápisy do replík sa vykonávajú asynchrónne. Remote_write ide ešte ďalej: zápisy na repliky sa robia asynchrónne, ale vrátia sa, keď replika zápis akceptovala, ale nezapísala ho na disk.

Po zvážení dostupného rozsahu možností si vyberáme správanie a pamätajúc na to on – ide o synchrónne nahrávky, vyberieme local pre asynchrónne odovzdania cez sieť, zatiaľ čo lokálne odovzdania budú synchrónne.

Teraz vám o chvíľu povieme, ako to nastaviť, ale predstavte si, že sme to nastavili synchronous_commit в local pre server. Zaujímalo nás, či je možné zmeniť parameter synchronous_commit za behu a ukázalo sa, že je to nielen možné, ale existujú dokonca dva spôsoby, ako to urobiť. Prvým je nastavenie relácie vášho pripojenia takto:

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

Všetky nasledujúce zápisy v relácii potvrdia zápisy do replík predtým, ako vrátia kladný výsledok pripojenému klientovi. Samozrejme, pokiaľ nezmeníte nastavenie synchronous_commit znova. Časť môžete vynechať SESSION v príkaze, pretože bude mať predvolenú hodnotu.

Druhá metóda je dobrá, keď sa chcete uistiť, že získate synchrónnu replikáciu pre jednu transakciu. V mnohých databázach generácie NoSQL koncept transakcií neexistuje, ale v PostgreSQL áno. V tomto prípade spustíte transakciu a potom nastavíte synchronous_commit в on pred vykonaním záznamu pre transakciu. COMMIT vykoná transakciu pomocou ľubovoľnej hodnoty parametra synchronous_commit, ktorý bol nastavený v tom čase, aj keď je najlepšie nastaviť premennú vopred, aby ostatní vývojári pochopili, že zápisy nie sú asynchrónne.

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

Všetky potvrdenia transakcie budú teraz potvrdené ako zapísané do repliky predtým, ako databáza vráti kladnú odpoveď pripojenému klientovi.

Nastavenie PostgreSQL

Predtým sme si predstavili systém PostgreSQL s synchronous_commit, nainštalovaný v local. Aby to bolo na strane servera realistické, budete musieť nastaviť dve možnosti konfigurácie servera. Ešte jeden parameter synchronous_standby_names príde na svoje kedy synchronous_commit bude v on. Určuje, ktoré repliky sú vhodné pre synchrónne odovzdania, a my to nastavíme *, čo bude znamenať, že sú zapojené všetky repliky. Tieto hodnoty sú zvyčajne konfigurované v konfiguračný súbor pridaním:

synchronous_commit = local  
synchronous_standby_names='*'

Nastavením parametra synchronous_commit do významu local, vytvoríme systém, v ktorom lokálne disky zostanú synchrónne, ale potvrdenia sieťovej repliky sú štandardne asynchrónne. Pokiaľ sa, samozrejme, nerozhodneme urobiť tieto potvrdenia synchrónne, ako je uvedené vyššie.

Ak ste sledovali vývoj Projekt guvernéra, možno ste si všimli nejaké nedávne zmeny (1, 2), čo umožnilo používateľom Governor testovať tieto parametre a sledovať ich konzistentnosť.

Ešte pár slov...

Ešte pred týždňom by som vám povedal, že je nemožné vyladiť PostgreSQL tak jemne. Vtedy Kurt, člen tímu platformy Compose, trval na tom, že takáto príležitosť existuje. Upokojil moje námietky a našiel v dokumentácii PostgreSQL nasledujúce:

PostgreSQL a nastavenia konzistencie zápisu špecifické pre pripojenie

Toto nastavenie je možné kedykoľvek zmeniť. Správanie každej transakcie je určené nastavením platným v čase potvrdenia. Preto je možné a užitočné, aby sa niektoré transakcie potvrdzovali synchrónne a iné asynchrónne. Napríklad prinútiť jedného multistatement transakcie vykonať potvrdenia asynchrónne, keď je predvolená hodnota parametra opačná, set SET LOCAL synchronous_commit TO OFF v transakcii.

Touto malou úpravou konfiguračného súboru sme používateľom poskytli kontrolu nad ich konzistenciou a výkonom.

Zdroj: hab.com

Pridať komentár