PostgreSQL a nastavení konzistence zápisu pro každé konkrétní připojení

Překlad článku byl připraven speciálně pro studenty kurzu „Databáze“. Chcete se rozvíjet v této oblasti? Zveme vás na Den Otevřených Dveří, kde podrobně představíme program, zvláštnosti online formátu, kompetence a kariérní vyhlídky, které čekají na absolventy po ukončení studia.

PostgreSQL a nastavení konzistence zápisu pro každé konkrétní připojení

PostgreSQL a nastavení konzistence zápisu pro každé konkrétní připojení
V Compose máme co do činění s mnoha databázemi, což nám umožňuje blíže se seznámit s jejich funkcionalitou a nedostatky. Jak se učíme mít rádi funkční vlastnosti nových databází, občas přemýšlíme o tom, jak skvělé by bylo, kdyby podobné funkce byly k dispozici i v mnohem vyspělejších nástrojích, se kterými již dlouho pracujeme. Jednou z nových funkcí, kterou jsme chtěli vidět v PostgreSQL, byla nastavitelnost konzistence zápisu podle připojení v celém clusteru. A jak se ukázalo, už ji máme, a dnes se s vámi chceme podělit o informace o tom, jak ji můžete využít.

Proč mi to je?

To, jak se má cluster chovat, závisí na vaší aplikaci. Vezměme si jako příklad aplikaci pro placení účtů. Budete potřebovat stoprocentní konzistenci v clusteru, a proto budete muset zapnout synchronní potvrzení, aby vaše databáze čekala, až budou všechny změny provedeny. Pokud je však vaše aplikace rychle se vyvíjející sociální síť, pak bezpochyby upřednostníte rychlou odezvu před stoprocentní konzistencí. K tomu, abyste toho dosáhli, můžete ve svém clusteru použít asynchronní potvrzení.

Seznamte se, kompromis

Musíte udělat kompromis mezi konzistencí dat a výkonem. PostgreSQL se od konzistence odklání, protože výchozí konfigurace je předvídatelná a bez překvapení. Nyní se pojďme seznámit s kompromisy.

Kompromis 1: Výkon

Pokud klastru PostgreSQL není vyžadována konzistence, může fungovat asynchronně. Zápis se provádí na vedoucím uzlu klastru, jeho repliky obdrží aktualizace během několika milisekund. Když je klastru PostgreSQL potřebná konzistence, musí fungovat synchronně. Zápis bude proveden na vedoucím uzlu klastru, který odešle aktualizaci replikám a počká na potvrzení, že každá provedla zápis, než pošle potvrzení klientovi, který inicioval zápis, že proběhl úspěšně. Praktický rozdíl mezi těmito přístupy spočívá v tom, že asynchronní metoda vyžaduje dva síťové skoky, zatímco synchronní čtyři.

Komprosi 2: Konzistence

Výsledek v případě selhání vedoucího uzlu v těchto dvou přístupech bude také odlišný. Pokud se práce provádí asynchronně, při takové chybě nebudou všechny zápisy potvrzeny replikami. Kolik bude ztraceno? To závisí na samotné aplikaci a efektivitě replikace. Replikace Compose zabrání replikaci stát se vedoucím uzlem, pokud množství informací v ní je o 1 MB méně než v vedoucím uzlu, což znamená, že potenciálně může být ztraceno až 1 MB zápisů při asynchronní činnosti.

V synchronním režimu k tomu nedochází. Pokud vedoucí uzel selže, všechny repliky se aktualizují, protože jakýkoli zápis potvrzený na vedoucím uzlu musí být potvrzen v replikách. Toto je konzistence.

Synchronní chování má smysl použít v aplikaci pro placení účtů, kde má konzistence jasnou výhodu v hledání kompromisu mezi konzistencí a výkonem. Největší důležitostí pro takovou aplikaci jsou validní data. A nyní si vzpomeňte na sociální síť, kde je hlavním úkolem udržet pozornost uživatele tím, že odpovídáte na dotazy co nejrychleji. V takovém případě bude výkon s menším počtem síťových skoků a kratšími čekacími dobami pro potvrzení prioritou. Nicméně kompromis mezi výkonem a konzistencí není jediný, o kterém je třeba přemýšlet.

Komprosi 3: Selhání

Je velmi důležité pochopit, jak se cluster chová během selhání. Zvažme situaci, kdy selže jedna nebo více replik. Když jsou zápisy zpracovávány asynchronně, vůdce bude pokračovat v činnosti, tedy přijímat a zpracovávat zápisy, aniž by čekal na chybějící repliky. Když se repliky vrátí do clusteru, doženou vůdce. Při synchronní replikaci, pokud repliky neodpovídají, nebude mít vůdce na výběr a bude čekat na potvrzení zápisu, dokud se replika nevrátí do clusteru a nebudou moci přijmout a potvrdit zápis.

Jedno spojení na transakci?

Každá aplikace potřebuje specifický typ kombinace konzistence a výkonu. Pokud to samozřejmě není naše aplikace pro placení účtů, kterou si představujeme jako zcela konzistentní, nebo naše téměř efemérní síťová aplikace. Ve všech ostatních případech budou chvíle, kdy některé operace musí být synchronní a některé asynchronní. Možná nechcete, aby systém čekal, dokud nebude zpráva odeslaná do chatu zapsaná, ale pokud se ve stejné aplikaci provádí platba, bude třeba počkat.

Všechna tato rozhodnutí samozřejmě činí vývojář aplikace. Správná rozhodnutí o tom, kdy použít ten či onen přístup, pomohou maximálně využít cluster. Je důležité, aby vývojář mohl přepínat mezi nimi na úrovni SQL pro připojení a pro transakce.

Zajištění kontroly v praxi

Ve výchozím nastavení PostgreSQL zajišťuje konzistenci. To je řízeno parametrem serveru synchronous_commit. Ve výchozím stavu je nastaven na on, ale má další tři možnosti: local, remote_write nebo off.

Při nastavování parametru na off se zastaví všechny synchronní zápisy, dokonce i v místním systému. Parametr `local` určuje synchronní režim pro místní systém, ale zápisy do repliky se provádějí asynchronně. Remote_write jde ještě dál: zápisy do repliky se provádějí asynchronně, ale vrátí se, když replika přijme zápis, ale nezapíše ho na disk.

S ohledem na dostupné možnosti vybíráme chování a s ohledem na to, že on – to jsou synchronní zápisy, zvolíme local pro asynchronní zápisy přes síť, přičemž místní zápisy zůstávají synchronní.

Nyní vám ukážeme, jak to nastavit během okamžiku, ale představte si, že jsme nainstalovali synchronous_commit v local pro server. Ptali jsme se, zda je možné měnit parametr synchronous_commit za běhu, a ukázalo se, že nejen možné, dokonce existují hned dva způsoby. První je nastavit relaci vašeho spojení následujícím způsobem:

SET SESSION synchronous_commit TO ON;  
// Vaše zápisy přicházejí sem

Všechny následné zápisy v relaci potvrdí operace zápisu pro repliky, než vrátí pozitivní výsledek připojenému klientovi. Pokud tedy nezměníte nastavení synchronous_commit znovu. Můžete vynechat část SESSION v příkazu, protože bude mít výchozí hodnotu.

Druhý způsob je dobrý, když chcete jen zajistit, abyste dostali synchronní replikaci pro jednu transakci. Mnoho databází generace "NoSQL" nemá pojem transakcí, ale tento koncept existuje v PostgreSQL. V tomto případě spustíte transakci a pak nastavíte synchronous_commit v on před provedením zápisu pro transakci. COMMIT potvrdí transakci, používajíc jakoukoli hodnotu parametru synchronous_commit, která byla nastavena v tu chvíli, i když je nejlepší nastavit proměnnou předem, abyste se ujistili, že ostatní vývojáři chápou, že zápisy nejsou asynchronní.

BEGIN;  
SET LOCAL synchronous_commit TO ON;  
// Vaše zápisy přicházejí sem
COMMIT;  

Všechny commity transakcí nyní budou potvrzeny jako zapsané do replik ještě předtím, než databáze vrátí pozitivní odpověď připojenému klientovi.

Nastavení PostgreSQL

Do této doby jsme si představovali systém PostgreSQL s synchronous_commit, nainstalovaným v local. Aby to byla realita na straně serveru, budete muset nastavit dva parametry konfigurace serveru. Další parametr synchronous_standby_names se uplatní, když synchronous_commit bude v on. Určuje, které repliky mají právo na synchronní commity, a my ho nastavíme na *, což znamená zapojení všech replik. Tyto hodnoty se obvykle nakonfigurují v konfiguračním souboru přidáním:

synchronous_commit = local  
synchronous_standby_names='*'

Nastavením parametru synchronous_commit na hodnotu local, vytváříme systém, ve kterém záznamy na lokálních discích zůstávají synchronní, ale commity síťových replik jsou výchozí asynchronní. Pokud ovšem nehodláme tyto commity udělat synchronní, jak je uvedeno výše.

Pokud jste sledovali vývoj projektu Governor, můžete si všimnout některých nedávných změn (1, 2), které umožnily uživatelům Governor testovat tyto parametry a kontrolovat jejich konzistenci.

Ještě pár slov…

Před týdnem bych vám řekl, že je nemožné tak podrobně nastavit PostgreSQL. Tehdy Kurt, člen týmu platformy Compose, trval na tom, že taková možnost existuje. Utišil mé námitky a našel v dokumentaci PostgreSQL následující:

PostgreSQL a nastavení konzistence zápisu pro každé konkrétní připojení

Tento parametr může být změněn kdykoli. Chování při jakékoli transakci se určuje nastavením, které je platné při potvrzení. Proto je možné a užitečné, aby u některých transakcí byly potvrzení provedeny synchronně, zatímco u jiných asynchronně. Například, aby se jedna multistatement transakce prováděla potvrzení asynchronně, když je výchozí hodnota parametru opačná, zadejte SET LOCAL synchronous_commit TO OFF v transakci.

Díky této malé úpravě v konfiguračním souboru jsme uživatelům umožnili kontrolovat jejich konzistenci a výkon.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster