FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

I artikeln kommer jag att berÀtta hur vi nÀrmade oss frÄgan om tillförlitlighet för PostgreSQL, varför det blev viktigt för oss och vad vi slutligen Ästadkom.

Vi har en högbelastad tjÀnst: 2,5 miljoner anvÀndare vÀrlden över, över 50 000 aktiva anvÀndare varje dag. Servrarna ligger i Amazon inom en region i Irland: mer Àn 100 olika servrar Àr stÀndigt i drift, varav nÀstan 50 har databaser.

Hela backend-omrÄdet Àr en stor monolitisk stateful-applikation pÄ Java, som upprÀtthÄller en konstant websocket-anslutning till klienten. NÀr flera anvÀndare arbetar samtidigt pÄ samma tavla ser alla förÀndringar i realtid, eftersom varje förÀndring registreras i databasen. Vi har ungefÀr 10 000 förfrÄgningar per sekund till vÄra databaser. Under toppbelastning skriver vi i Redis med 80-100 000 förfrÄgningar per sekund.
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Varför vi gick frÄn Redis till PostgreSQL

Ursprungligen fungerade vÄr tjÀnst med Redis, en key-value-lagring som lagrar all data i minnet. servern.

Fördelar med Redis:

  1. Hög svarsförmÄga, eftersom allt lagras i minnet;
  2. BekvÀm backup och replikering.

Nackdelar med Redis för oss:

  1. Det finns inga verkliga transaktioner. Vi försökte simulera dem pÄ applikationsnivÄ. TyvÀrr fungerade detta inte alltid bra och krÀvde mycket komplicerad kod.
  2. DatamÀngden Àr begrÀnsad av mÀngden minne. NÀr datamÀngden ökar kommer minnet att vÀxa, och till slut kommer vi att nÄ kapacitetsgrÀnserna för den valda instansen, vilket i AWS krÀver att vi stoppar vÄr tjÀnst för att Àndra typ av instans.
  3. Det Àr nödvÀndigt att stÀndigt upprÀtthÄlla en lÄg latensnivÄ, eftersom vi har ett mycket stort antal förfrÄgningar. Optimal latens för oss Àr 17-20 ms. Vid en latens pÄ 30-40 ms fÄr vi lÄnga svar pÄ vÄra applikationsförfrÄgningar och degradering av tjÀnsten. TyvÀrr intrÀffade detta i september 2018, nÀr en av instanserna med Redis av nÄgon anledning fick en latens som var dubbelt sÄ hög som vanligt. För att lösa problemet stoppade vi tjÀnsten mitt pÄ dagen för underhÄll och ersatte den problematiska Redis-instansen.
  4. Det Àr lÀtt att fÄ inkonsekvens i datan Àven vid smÄ fel i koden och sedan spendera mycket tid pÄ att skriva kod för att rÀtta till dessa data.

Vi har beaktat nackdelarna och insett att vi behöver flytta till nÄgot mer bekvÀmt, med normala transaktioner och mindre beroende av latens. Vi genomförde en undersökning, analyserade mÄnga alternativ och valde PostgreSQL.

Vi har flyttat till den nya databasen i 1,5 Är och har bara flyttat en liten del av datan, sÄ vi arbetar för nÀrvarande med bÄde Redis och PostgreSQL. Mer om etapperna för flytten och övergÄngen av data mellan databaserna stÄr det i artikeln av min kollega.

NÀr vi precis började flytta, arbetade vÄr applikation direkt med databasen och kommunicerade med master Redis och PostgreSQL. PostgreSQL-klustret bestod av en master och en replik med asynkron replikering. SÄ hÀr sÄg schemat ut för arbete med databaserna:
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Implementering av PgBouncer

Under tiden vi flyttade, utvecklades produkten ocksÄ: antalet anvÀndare och servrar som arbetade med PostgreSQL ökade, och vi började fÄ brist pÄ anslutningar. PostgreSQL skapar en separat process för varje anslutning och förbrukar resurser. Antalet anslutningar kan ökas till en viss punkt, annars finns risken att databasen arbetar suboptimalt. Den ideala lösningen i en sÄdan situation Àr att vÀlja en anslutningshanterare som placeras framför databasen.

Vi hade tvÄ alternativ för anslutningshanterare: Pgpool och PgBouncer. Men den första stöder inte transaktionslÀge med databasen, sÄ vi valde PgBouncer.

Vi har stÀllt in följande arbetsschema: vÄr applikation kommunicerar med en PgBouncer, som har PostgreSQL-masters bakom sig, och bakom varje master finns en replik med asynkron replikering.
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Samtidigt kunde vi inte lagra hela datamÀngden i PostgreSQL och hastigheten pÄ datahanteringen var viktig för oss, sÄ vi började shardera PostgreSQL pÄ applikationsnivÄ. Det ovan beskrivna schemat Àr relativt bekvÀmt för detta: vid tillÀgg av ett nytt shard Àr det tillrÀckligt att uppdatera PgBouncer-konfigurationen sÄ att applikationen kan börja arbeta med det nya shardet.

Felresistens för PgBouncer

Detta system fungerade fram till dess att den enda instansen av PgBouncer dog. Vi befinner oss i AWS, dÀr alla instanser körs pÄ hÄrdvara som ibland gÄr ner. I sÄdana fall flyttas instansen bara till ny hÄrdvara och fungerar igen. SÄ var Àven fallet med PgBouncer, men den blev otillgÀnglig. Resultatet av detta nedfall blev att vÄr tjÀnst var otillgÀnglig i 25 minuter. AWS rekommenderar för sÄdana situationer att anvÀnda redundans pÄ anvÀndarsidan, vilket vi inte hade implementerat vid den tidpunkten.

Efter detta började vi seriöst fundera pÄ tillförlitlighet för PgBouncer och PostgreSQL-kluster, eftersom en liknande situation kunde intrÀffa med vilken instans som helst i vÄrt AWS-konto.

Vi byggde PgBouncer:s redundansmodell pÄ följande sÀtt: alla applikationsservrar kontaktar Network Load Balancer, bakom vilken det finns tvÄ PgBouncer-instanser. Varje PgBouncer pekar pÄ samma master PostgreSQL för varje shard. Om en instans av AWS faller, omdirigeras all trafik genom den andra PgBouncer. AWS sÀkerstÀller redundans för Network Load Balancer.

Denna konfiguration gör det problemfritt att lÀgga till nya PgBouncer-servrar.
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Att skapa ett tillförlitligt PostgreSQL-kluster

Vid lösningen av denna uppgift övervÀgde vi olika alternativ: skrÀddarsydd failover, repmgr, AWS RDS, Patroni.

Egenutvecklade skript

Dessa kan övervaka masterns status och, om den faller, höja en replik till master och uppdatera PgBouncer-konfigurationen.

Fördelarna med detta tillvÀgagÄngssÀtt ligger i den maximala enkelheten, eftersom du sjÀlv skriver skripten och exakt förstÄr hur de fungerar.

Nackdelar:

  • Master kan ha överlevt, istĂ€llet kan ett nĂ€tverksfel ha intrĂ€ffat. Failover, utan att veta detta, kommer att höja en replik till master, och den gamla master kommer att fortsĂ€tta att fungera. Som ett resultat fĂ„r vi tvĂ„ servrar i rollen som master och vi vet inte vilken av dem som har de senaste aktuella uppgifterna. En sĂ„dan situation kallas ocksĂ„ split-brain;
  • Vi blev utan replik. I vĂ„r konfiguration finns det en master och en replik, efter omkopplingen höjs replik till master och vi har inga fler replikar, sĂ„ vi mĂ„ste manuellt lĂ€gga till en ny replik;
  • Ytterligare övervakning av failover-processen behövs, och vi har 12 shard av PostgreSQL, vilket innebĂ€r att vi mĂ„ste övervaka 12 kluster. Vid ökning av antalet shards fĂ„r vi inte glömma att uppdatera failover.

Egenutvecklad failover verkar mycket komplicerad och krÀver omfattande support. NÀr det gÀller en PostgreSQL-kluster Àr detta den enklaste lösningen, men den Àr inte skalbar, sÄ den passar oss inte.

Repmgr

Replication Manager för PostgreSQL-kluster, som kan hantera driften av ett PostgreSQL-kluster. Det finns ingen automatisk failover ‘ur lĂ„dan’, sĂ„ det krĂ€vs att man skriver sin egen ‘wrapper’ ovanpĂ„ den fĂ€rdiga lösningen. SĂ„ det kan visa sig vara Ă€nnu mer komplicerat Ă€n med egenutvecklade skript, dĂ€rför bestĂ€mde vi oss för att inte ens pröva Repmgr.

AWS RDS

Stöder allt nödvÀndigt för oss, kan göra backups och stöder connection pool. Har automatisk switchning: nÀr huvudservern dör blir en replica den nya huvudservern, och AWS Àndrar DNS-posterna till den nya huvudservern, medan replication kan finnas i olika AZ.

Nackdelar inkluderar avsaknaden av finjustering. Ett exempel pÄ finjusteringar: pÄ vÄra instanser finns det begrÀnsningar för TCP-anslutningar, vilket tyvÀrr inte gÄr att göra i RDS:

net.ipv4.tcp_keepalive_time=10
net.ipv4.tcp_keepalive_intvl=1
net.ipv4.tcp_keepalive_probes=5
net.ipv4.tcp_retries2=3

Dessutom Àr priset för AWS RDS nÀstan dubbelt sÄ hög som det vanliga priset för instansen, vilket var den huvudsakliga anledningen till att vi avstod denna lösning.

Patroni

Detta Àr en mal pÄ python för att hantera PostgreSQL med bra dokumentation, automatisk failover och öppen kÀllkod pÄ GitHub.

Fördelar med Patroni:

  • Varje konfigurationsparameter Ă€r tydligt beskriven, det Ă€r klart hur allt fungerar;
  • Automatisk failover fungerar ur lĂ„dan;
  • Skriven i python, och eftersom vi sjĂ€lva skriver mycket i python, kommer vi att ha lĂ€ttare att hantera problem och kanske till och med hjĂ€lpa till med projektets utveckling;
  • Hanterar PostgreSQL helt och hĂ„llet, gör att man kan Ă€ndra konfigurationen direkt pĂ„ alla noder i klustret, och om en omstart av klustret krĂ€vs för att tillĂ€mpa den nya konfigurationen, kan detta ocksĂ„ göras med hjĂ€lp av Patroni.

Nackdelar:

  • Det framgĂ„r inte tydligt i dokumentationen hur man korrekt arbetar med PgBouncer. Även om det Ă€r svĂ„rt att kalla detta en nackdel, eftersom uppgiften för Patroni Ă€r att hantera PostgreSQL, och hur anslutningar gĂ„r till Patroni Ă€r vĂ„rt problem;
  • FĂ„ exempel pĂ„ implementering av Patroni i stor skala, samtidigt som det finns mĂ„nga exempel pĂ„ implementering frĂ„n grunden.

Slutligen valde vi att anvÀnda just Patroni för att skapa en hög tillgÀnglighet kluster.

Implementeringsprocessen av Patroni

Innan vi introducerade Patroni hade vi 12 PostgreSQL-shardar med konfigurationen en master och en replika med asynkron replikering. Applikationsservrarna kontaktade databaserna via Network Load Balancer, som hade tvÄ instanser med PgBouncer, som i sin tur hade alla PostgreSQL-servrar.
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

För att implementera Patroni behövde vi vÀlja en distribuerad lagring för klusterkonfigurationen. Patroni fungerar med distribuerade konfigurationslagringssystem som etcd, Zookeeper och Consul. Vi har faktiskt en fullt funktionell Consul-kluster i produktion som arbetar i samverkan med Vault och som vi inte anvÀnder pÄ nÄgot annat sÀtt. Ett utmÀrkt tillfÀlle att börja anvÀnda Consul för sitt avsedda syfte.

Hur fungerar Patroni med Consul

Vi har ett Consul-kluster som bestÄr av tre noder och ett Patroni-kluster som bestÄr av en ledare och en replik (i Patroni kallas master för klusterledare och slavarna för replikor). Varje instans av Patroni-klustret skickar kontinuerligt information om klusterstatus till Consul. DÀrför kan man alltid i Consul ta reda pÄ den aktuella konfigurationen av Patroni-klustret och vem som för tillfÀllet Àr ledare.

FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

För att koppla Patroni till Consul rÀcker det med att studera den officiella dokumentationen, som sÀger att man mÄste ange vÀrd i formatet http eller https beroende pÄ hur vi arbetar med Consul, samt kopplingsschema, vilket Àr valfritt:

host: vÀrd:port för Consul-slutpunkten, i formatet: http(s)://host:port
schema: (valfritt) http eller https, standardinstÀllningen Àr http

Det ser enkelt ut, men hÀr börjar underströmmarna. Vi arbetar med Consul via en sÀker anslutning genom https, och vÄr anslutningskonfiguration ser ut pÄ följande sÀtt:

consul:
  host: https://server.production.consul:8080 
  verify: true
  cacert: {{ consul_cacert }}
  cert: {{ consul_cert }}
  key: {{ consul_key }}

Men sÄ fungerar det inte. Vid starten kan inte Patroni ansluta till Consul, eftersom den försöker gÄ via http.

För att lösa problemet hjÀlpte kÀllkoden för Patroni. Tur att den Àr skriven i python. Det visar sig att vÀrdparametern inte parsas alls, utan protokollet mÄste anges i schema. SÄ hÀr ser blocket för fungerande konfiguration ut för att arbeta med Consul hos oss:

consul:
  host: server.production.consul:8080
  scheme: https
  verify: true
  cacert: {{ consul_cacert }}
  cert: {{ consul_cert }}
  key: {{ consul_key }}

Consul-template

SÄ, vi har valt en lagringslösning för konfigurationen. Nu mÄste vi förstÄ hur PgBouncer kommer att byta sin konfiguration nÀr ledaren i klustret Patroni Àndras. Det finns inget svar pÄ denna frÄga i dokumentationen, eftersom det inte finns nÄgon beskrivning av hur PgBouncer fungerar.

I jakten pÄ en lösning fann vi en artikel (tyvÀrr minns jag inte titeln) dÀr det stod att Consul-template hjÀlpte mycket i kopplingen mellan PgBouncer och Patroni. Detta fick oss att undersöka hur Consul-template fungerar.

Det visade sig att Consul-template stÀndigt övervakar konfigurationen av PostgreSQL-klustret i Consul. Vid byte av ledare uppdaterar den PgBouncer-konfigurationen och skickar ett kommando för att ladda om den.

FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

En stor fördel med template Àr att den lagras i kodform, sÄ nÀr en ny shard lÀggs till behöver vi bara göra ett nytt commit och uppdatera template automatiskt, vilket stöder principen om Infrastructure as Code.

Ny arkitektur med Patroni

Resultatet blev följande arbetsmönster:
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Alla applikationsservrar kontaktar load balancern → bakom den stĂ„r tvĂ„ instanser av PgBouncer → pĂ„ varje instans körs Consul-template, som övervakar statusen för varje Patroni-kluster och ser till att PgBouncer-konfigurationen Ă€r aktuell, vilket dirigerar förfrĂ„gningar till den nuvarande ledaren i varje kluster.

Manuell testning

Innan denna lösning implementerades i produktion testade vi den i en liten testmiljö och kontrollerade det automatiska vÀxlingen. Vi öppnade en tavla, flyttade en lapp och just dÄ "dödade" vi ledaren i klustret. I AWS rÀcker det med att stÀnga av instansen via konsolen.

FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Lappen ÄtervÀnde inom 10-20 sekunder, och sedan började den flytta normalt igen. Det betyder att Patroni-klustret fungerade korrekt: det bytte ledare, skickade information till Consul och Consul-template plockade omedelbart upp denna information, ersatte PgBouncer-konfigurationen och skickade ett kommando för reload.

Hur överlever man hög belastning och bibehÄller minimal driftstopp?

Allt fungerar utmÀrkt! Men nya frÄgor dyker upp: Hur fungerar det under hög belastning? Hur snabbt och sÀkert ska allt rullas ut pÄ produktion?

Att svara pÄ den första frÄgan hjÀlper oss att anvÀnda en testmiljö dÀr vi genomför belastningstestning. Den Àr helt identisk med produktionen nÀr det kommer till arkitektur och har genererade testdata som ungefÀr motsvarar produktionens volym. Vi beslutar oss för att "ta ner" en av PostgreSQL-mÀstarna under testet och se vad som hÀnder. Men innan vi gör det Àr det viktigt att kontrollera den automatiska distributionen, eftersom vi i denna miljö har flera PostgreSQL-shards, vilket innebÀr att vi fÄr en utmÀrkt testning av konfigurationsskripten före produktion.

BÄda uppgifterna ser ambitiösa ut, men vi har PostgreSQL 9.6. Kanske vi bör uppgradera direkt till 11.2?

Vi planerar att göra detta i tvÄ steg: först uppgradera versionen till 11.2, och sedan starta Patroni.

Uppgradering av PostgreSQL

För att snabbt uppgradera versionen av PostgreSQL mÄste du anvÀnda alternativet -k, som skapar hÄrda lÀnkar pÄ disken och eliminerar behovet av att kopiera dina data. För databaser pÄ 300-400 GB tar uppgraderingen 1 sekund.

Vi har mÄnga shards, sÄ uppgraderingen mÄste ske automatiskt. För detta har vi skrivit en Ansible-playbook som utför hela uppgraderingsprocessen Ät oss:

/usr/lib/postgresql/11/bin/pg_upgrade 
<b>--länk </b>
--gammal-datadir='' --ny-datadir='' 
 --gammal-bindir=''  --ny-bindir='' 
 --gammal-alternativ=' -c konfigurationsfil=' 
 --nya-alternativ=' -c konfigurationsfil='

HĂ€r Ă€r det viktigt att notera att innan uppgraderingen pĂ„börjas mĂ„ste den köras med parametern —check, för att vara sĂ€ker pĂ„ att uppgraderingen Ă€r möjlig. VĂ„rt skript gör ocksĂ„ en ersĂ€ttning av konfigurationerna under uppgraderingen. Skriptet körde pĂ„ 30 sekunder, vilket Ă€r ett utmĂ€rkt resultat.

Starta Patroni

För att lösa det andra problemet rÀcker det med att titta pÄ konfigurationen för Patroni. I det officiella repository finns ett exempel pÄ en konfiguration med initdb som hanterar initialiseringen av en ny databas vid första starten av Patroni. Men eftersom vi redan har en fÀrdig databas, har vi helt enkelt tagit bort den delen frÄn konfigurationen.

NÀr vi började installera Patroni pÄ en befintlig PostgreSQL-kluster och starta den stötte vi pÄ ett nytt problem: bÄda servrarna startades som ledare. Patroni vet inget om det tidigare tillstÄndet av klustret och försöker starta bÄda servrarna som tvÄ separata kluster med samma namn. För att lösa detta problem Àr det nödvÀndigt att ta bort datakatalogen frÄn slaven:

rm -rf /var/lib/postgresql/

Detta mÄste göras endast pÄ slaven!

Vid anslutning av en ren replik gör Patroni en basebackup av ledaren och ÄterstÀller den pÄ repliken, för att sedan hÀmta det aktuella tillstÄndet via wal-loggar.

En annan utmaning vi stött pÄ Àr att alla PostgreSQL-kluster som standard kallas main. NÀr varje kluster inte vet nÄgot om de andra Àr det okej. Men nÀr du vill anvÀnda Patroni mÄste alla kluster ha ett unikt namn. Lösningen Àr att byta namn pÄ klustret i PostgreSQL-konfigurationen.

Belastningstest

Vi genomförde ett test som simulerar anvÀndarbeteende pÄ plattformarna. NÀr belastningen nÄdde vÄrt genomsnittliga dagliga vÀrde upprepade vi exakt samma test, vi stÀngde av en instans med ledande PostgreSQL. Den automatiska failovern fungerade som förvÀntat: Patroni bytte ledare, Consul-template uppdaterade PgBouncers konfiguration och skickade en reload-kommando. FrÄn vÄra grafer i Grafana kunde vi se att det fanns fördröjningar pÄ 20-30 sekunder och ett litet antal fel frÄn servrar relaterade till anslutningen till databasen. Det Àr en normal situation, sÄdana vÀrden Àr acceptabla för vÄr failover och absolut bÀttre Àn driftsstopp.

Utrullning av Patroni i produktion

Som ett resultat fick vi följande plan:

  • Utrullning av Consul-template pĂ„ PgBouncer-servrar och start;
  • Uppgradering av PostgreSQL till version 11.2;
  • Byta klusternamn;
  • Starta Patroni-klustret.

VÄr plan gör det möjligt att utföra första punkten nÀstan nÀr som helst, vi kan gradvis ta bort varje PgBouncer frÄn drift och genomföra utrullning och start av consul-template. Det var precis vad vi gjorde.

För snabb utrullning anvÀnde vi Ansible, eftersom vi redan hade testat alla playbooks i testmiljön, och tiden för att genomföra hela scenariot var mellan 1,5 och 2 minuter för varje shard. Vi kunde rulla ut varje shard sekventiellt utan att stÀnga av vÄr tjÀnst, men vi skulle behöva stÀnga av varje PostgreSQL i nÄgra minuter. I sÄdana fall kunde anvÀndare vars data finns pÄ den shard inte arbeta fullt ut under tiden, vilket Àr oacceptabelt för oss.

Lösningen pÄ den hÀr situationen blev ett planerat underhÄll som genomförs var tredje mÄnad. Detta Àr ett fönster för planerat arbete nÀr vi stÀnger av vÄr tjÀnst helt och uppgraderar databasinstanser. Det var en vecka kvar till nÀsta fönster, och vi valde att vÀnta och förbereda oss ytterligare. Under vÀntetiden vidtog vi extra precaution: för varje PostgreSQL-shard lyfte vi en reservreplik för att hantera eventuella misslyckanden och en ny instans för varje shard, som skulle bli en ny replik i Patroni-klustret, sÄ att vi inte behövde köra ett kommando för att ta bort data. Allt detta hjÀlpte till att minimera risken för fel.
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Vi startade om vÄr tjÀnst och allt fungerade som det skulle, anvÀndarna fortsatte sitt arbete, men vi mÀrkte en onormalt hög belastning pÄ Consul-servrarna.
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Varför sÄg vi inte detta i testmiljön? Detta problem illustrerar tydligt vikten av att följa principen Infrastructure as code och att utveckla hela infrastrukturen, frÄn testmiljöer till produktionsmiljöer. Annars Àr det lÀtt att fÄ sÄdana problem som vi fick. Vad hÀnde? Consul kom först till produktion och senare till testmiljöerna, vilket resulterade i att versionen av Consul i testmiljöerna var högre Àn i produktion. Just i en av versionerna rÀttades en CPU-lÀckage nÀr man arbetade med consul-template. SÄ vi uppdaterade helt enkelt Consul för att lösa problemet.

Starta om Patroni-klustret

Men vi fick ett nytt problem som vi inte ens misstĂ€nkte. Vid uppdateringen av Consul tar vi helt enkelt bort Consul-noden frĂ„n klustret med kommandot consul leave → Patroni ansluter till en annan Consul-server → allting fungerar. Men nĂ€r vi kom till den sista instansen av Consul-klustret och skickade kommando consul leave till den, startade alla Patroni-kluster om, och i loggarna sĂ„g vi följande felmeddelande:

FEL: get_cluster
Spår tillbaka (senaste anropet sist):
...
RetryFailedError: 'Överskred återförsöksfristen'
FEL: Fel vid kommunikation med DCS
<b>LOGG: databasystemet är avstängt</b>

Patroni-klustret kunde inte fÄ information om sitt kluster och startade om.

För att hitta en lösning kontaktade vi författarna till Patroni genom en issue pÄ GitHub. De föreslog förbÀttringar av vÄra konfigurationsfiler:

consul:
 consul.checks: []
bootstrap:
 dcs:
   retry_timeout: 8

Vi lyckades reproducera problemet i testmiljön och testade dessa instÀllningar dÀr, men tyvÀrr fungerade de inte.

Problemet Àr fortfarande olöst. Vi planerar att prova följande lösningar:

  • AnvĂ€nda Consul-agent pĂ„ varje instans i Patroni-klustret;
  • Korrigera problemet i koden.

Vi förstÄr var felet uppstÄr: problemet ligger troligen i anvÀndningen av standardtimeouten, som inte ÄsidosÀtts via konfigurationsfilen. NÀr den sista Consul-servern tas bort frÄn klustret fryser hela Consul-klustret, vilket varar lÀngre Àn en sekund, och dÀrför kan Patroni inte fÄ klustrets status och startar om hela klustret.

Lyckligtvis har vi inte stött pÄ nÄgra fler fel.

Resultat av anvÀndningen av Patroni

Efter en framgÄngsrik start av Patroni lÄnade vi en extra replika i varje kluster. Nu finns det en form av kvorum i varje kluster: en ledare och tvÄ repliker, för sÀkerhets skull vid split-brain under omkoppling.
FelsÀkert PostgreSQL-kluster + Patroni. Implementeringserfarenhet

Patroni har fungerat pÄ produktion i mer Àn tre mÄnader. Under denna tid har det redan hjÀlpt oss. Nyligen dog ledaren för ett av klustren i AWS, automatisk failover utlöste, och anvÀndarna kunde fortsÀtta arbeta. Patroni uppfyllde sin huvuduppgift.

En liten sammanfattning av anvÀndningen av Patroni:

  • BekvĂ€mligheterna med att Ă€ndra konfigurationen. Det rĂ€cker att Ă€ndra konfigurationen pĂ„ en instans sĂ„ synkroniseras den över hela klustret. Om en omstart krĂ€vs för att tillĂ€mpa den nya konfigurationen, kommer Patroni att meddela detta. Patroni kan starta om hela klustret med ett enda kommando, vilket ocksĂ„ Ă€r mycket bekvĂ€mt.
  • Automatisk failover fungerar och har redan hjĂ€lpt oss.
  • Uppgradering av PostgreSQL utan driftstopp för applikationen. Först mĂ„ste replikerna uppgraderas till den nya versionen, sedan byta ledare i Patroni-klustret och uppgradera den gamla ledaren. Under detta sker nödvĂ€ndig testning av den automatiska failovern.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster