Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

A cikkben elmesélem, hogyan közelítettük meg a PostgreSQL hibatűrés kérdését, miért vált fontossá számunkra, és mi történt végül.

Nagyon leterhelt szolgáltatásunk van: 2,5 millió felhasználó világszerte, naponta több mint 50 100 aktív felhasználó. A szerverek Írország egyik régiójában található Amazone-ban találhatók: több mint 50 különböző szerver működik folyamatosan, ebből közel XNUMX adatbázissal.

A teljes háttérrendszer egy nagy monolitikus állapottartó Java-alkalmazás, amely állandó websocket kapcsolatot tart fenn az ügyféllel. Ha egyszerre több felhasználó dolgozik ugyanazon a táblán, akkor mindannyian valós időben látják a változásokat, mert minden változtatást az adatbázisba írunk. Körülbelül 10 80 kérés érkezik másodpercenként adatbázisainkba. A Redis csúcsterhelésén másodpercenként 100-XNUMX ezer kérést írunk.
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

Miért váltottunk Redisről PostgreSQL-re?

Kezdetben szolgáltatásunk a Redis-szel működött együtt, egy kulcsérték-tárolóval, amely az összes adatot a szerver RAM-jában tárolja.

A Redis előnyei:

  1. Nagy válaszsebesség, mert mindent a memóriában tárolnak;
  2. Könnyű biztonsági mentés és replikáció.

A Redis hátrányai számunkra:

  1. Nincsenek valódi tranzakciók. Ezeket próbáltuk szimulálni az alkalmazásunk szintjén. Sajnos ez nem mindig működött jól, és nagyon összetett kódot igényelt.
  2. Az adatok mennyiségét a memória mennyisége korlátozza. Az adatmennyiség növekedésével a memória növekszik, és a végén belefutunk a kiválasztott példány jellemzőibe, ami az AWS-ben megköveteli a szolgáltatásunk leállítását a példány típusának megváltoztatásához.
  3. Az alacsony késleltetési szintet folyamatosan fenn kell tartani, mert. nagyon sok kérésünk van. Az optimális késleltetési szint számunkra 17-20 ms. 30-40 ms-os szinten hosszú válaszokat kapunk az alkalmazásunkból és a szolgáltatás leromlásából származó kérésekre. Sajnos ez 2018 szeptemberében történt velünk, amikor az egyik Redis-es példány valamiért a szokásosnál 2-szer nagyobb késleltetést kapott. A probléma megoldása érdekében nem tervezett karbantartás miatt a nap közepén leállítottuk a szolgáltatást, és kicseréltük a problémás Redis-példányt.
  4. Könnyen előfordulhat, hogy az adatok inkonzisztenciája még kisebb kódhibák esetén is előfordul, majd sok időt töltenek kódírással az adatok javítására.

Figyelembe vettük a hátrányokat, és rájöttünk, hogy valami kényelmesebbre kell váltanunk, normál tranzakciókkal és kevesebb késleltetéssel. Kutatást végzett, sok lehetőséget elemzett, és a PostgreSQL-t választotta.

Már 1,5 éve költöztünk egy új adatbázisra, és az adatoknak csak egy kis részét helyeztük át, így most egyszerre dolgozunk a Redis-szel és a PostgreSQL-lel. Az adatbázisok közötti adatmozgatás és adatváltás szakaszairól bővebb információ található kollégám cikkét.

Amikor először elkezdtük a költözést, alkalmazásunk közvetlenül az adatbázissal működött, és hozzáfért a fő Redishez és a PostgreSQL-hez. A PostgreSQL-fürt egy mesterből és egy aszinkron replikációval rendelkező replikából állt. Így nézett ki az adatbázis séma:
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

A PgBouncer megvalósítása

Miközben költöztünk, a termék is fejlődött: nőtt a PostgreSQL-lel működő felhasználók és szerverek száma, és kezdtek hiányozni a kapcsolatok. A PostgreSQL minden kapcsolathoz külön folyamatot hoz létre, és erőforrásokat fogyaszt. Egy bizonyos pontig növelheti a kapcsolatok számát, különben esély van az adatbázis optimális teljesítményének elmaradására. Ilyen helyzetben az ideális megoldás egy kapcsolatkezelő kiválasztása, amely a bázis előtt áll.

Két lehetőségünk volt a kapcsolatkezelőre: Pgpool és PgBouncer. De az első nem támogatja az adatbázissal való munkavégzés tranzakciós módját, ezért a PgBouncer-t választottuk.

A következő munkasémát állítottuk fel: alkalmazásunk egy PgBouncer-t ér el, amely mögött PostgreSQL-mesterek állnak, és mindegyik mester mögött egy aszinkron replikációval rendelkező replika található.
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

Ugyanakkor nem tudtuk a teljes adatmennyiséget PostgreSQL-ben tárolni, és az adatbázissal való munka sebessége is fontos volt számunkra, ezért elkezdtük a PostgreSQL felosztását az alkalmazás szintjén. A fent leírt séma viszonylag kényelmes erre: egy új PostgreSQL shard hozzáadásakor elég frissíteni a PgBouncer konfigurációt, és az alkalmazás azonnal dolgozni tud az új sharddal.

PgBouncer feladatátvétel

Ez a séma addig működött, amíg az egyetlen PgBouncer példány el nem halt. Az AWS-ben vagyunk, ahol minden példány olyan hardveren fut, amely időről időre elhal. Ilyen esetekben a példány egyszerűen új hardverre költözik, és újra működik. Ez történt a PgBouncerrel, de elérhetetlenné vált. Az idei esés eredménye az volt, hogy szolgáltatásunk 25 percig nem elérhető. Az AWS az ilyen helyzetekre a felhasználói oldali redundancia alkalmazását javasolja, amely akkor még nem volt bevezetve hazánkban.

Ezek után komolyan elgondolkodtunk a PgBouncer és PostgreSQL fürtök hibatűrésén, mert hasonló helyzet az AWS fiókunk bármelyik példányával előfordulhat.

A PgBouncer hibatűrési sémát a következőképpen építettük fel: minden alkalmazásszerver hozzáfér a Network Load Balancerhez, amely mögött két PgBouncer található. Minden PgBouncer ugyanazt a PostgreSQL-mestert nézi minden egyes szilánknál. Ha ismét előfordul egy AWS-példány összeomlása, az összes forgalmat egy másik PgBouncer-n keresztül irányítják át. A Network Load Balancer feladatátvételét az AWS biztosítja.

Ez a séma megkönnyíti az új PgBouncer szerverek hozzáadását.
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

Hozzon létre egy PostgreSQL feladatátvevő fürtöt

A probléma megoldása során különböző lehetőségeket mérlegeltünk: saját írású feladatátvétel, repmgr, AWS RDS, Patroni.

Saját írású forgatókönyvek

Figyelemmel kísérhetik a mester munkáját, és annak meghibásodása esetén a replikát a mesterbe helyezhetik, és frissíthetik a PgBouncer konfigurációját.

Ennek a megközelítésnek az előnyei a maximális egyszerűség, mivel Ön maga írja meg a szkripteket, és pontosan tudja, hogyan működnek.

Hátrányok:

  • Lehet, hogy a mester nem halt meg, hanem hálózati hiba történt. A Failover, ennek tudatában, a replikát a mesterré teszi, míg a régi mester tovább dolgozik. Ennek eredményeként két szervert kapunk master szerepkörben, és nem fogjuk tudni, hogy melyikük rendelkezik a legfrissebb adatokkal. Ezt a helyzetet agyhasadásnak is nevezik;
  • Válasz nélkül maradtunk. A mi konfigurációnkban a fő és egy replika, váltás után a replika felkerül a főre, és már nincsenek replikáink, ezért manuálisan kell hozzáadnunk egy új replikát;
  • A feladatátvételi művelet további felügyeletére van szükségünk, miközben 12 PostgreSQL-szilánk áll rendelkezésünkre, ami azt jelenti, hogy 12 fürtöt kell figyelnünk. A szilánkok számának növekedésével a feladatátvételt is frissítenie kell.

A saját maga által írt feladatátvétel nagyon bonyolultnak tűnik, és nem triviális támogatást igényel. Egyetlen PostgreSQL-fürttel ez lenne a legegyszerűbb lehetőség, de nem skálázódik, így nekünk nem megfelelő.

Repmgr

Replication Manager for PostgreSQL-fürtök, amely képes kezelni egy PostgreSQL-fürt működését. Ugyanakkor nem rendelkezik automatikus feladatátvétellel a dobozból, így a munkához saját „csomagolóanyagot” kell írnia a kész megoldás tetejére. Így minden még bonyolultabbra fordulhat, mint a saját kezűleg írt szkripteknél, így a Repmgr-t meg sem próbáltuk.

AWS RDS

Mindent támogat, amire szükségünk van, tudja, hogyan kell biztonsági másolatot készíteni, és fenntartja a kapcsolatkészletet. Automatikus átkapcsolással rendelkezik: amikor a mester meghal, a replika lesz az új mester, és az AWS megváltoztatja a dns rekordot az új masterre, míg a replikák különböző AZ-okban helyezkedhetnek el.

A hátrányok közé tartozik a finombeállítások hiánya. Példaként a finomhangolásra: példányainkban korlátozások vannak a tcp kapcsolatokra vonatkozóan, ami sajnos RDS-ben nem lehetséges:

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

Ráadásul az AWS RDS majdnem kétszer olyan drágább, mint a normál példányár, ez volt a fő oka a megoldás elhagyásának.

Patroni

Ez egy Python-sablon a PostgreSQL kezelésére, jó dokumentációval, automatikus feladatátvétellel és forráskóddal a githubon.

A Patroni előnyei:

  • Minden konfigurációs paraméter le van írva, világos, hogyan működik;
  • Az automatikus feladatátvétel a dobozból kivéve működik;
  • Pythonban írva, és mivel mi magunk is sokat írunk pythonban, könnyebben kezeljük a problémákat, és talán még a projekt fejlesztését is segítjük;
  • Teljesen felügyeli a PostgreSQL-t, lehetővé teszi a fürt összes csomópontjának konfigurációjának egyidejű módosítását, és ha a fürtöt újra kell indítani az új konfiguráció alkalmazásához, akkor ezt újra megteheti a Patroni segítségével.

Hátrányok:

  • A dokumentációból nem világos, hogyan kell helyesen dolgozni a PgBouncer-rel. Bár ezt nehéz mínusznak nevezni, mert a Patroni feladata a PostgreSQL kezelése, és az, hogy a Patronihoz hogyan fognak menni a kapcsolatok, az már a mi problémánk;
  • Kevés példa van a Patroni megvalósítására nagy mennyiségben, míg sok példa van a nulláról való megvalósításra.

Ennek eredményeként a Patronit választottuk egy feladatátvételi fürt létrehozásához.

Patroni végrehajtási folyamat

A Patroni előtt 12 PostgreSQL-szilánk volt egy fő konfigurációban és egy aszinkron replikációval rendelkező replikában. Az alkalmazásszerverek a Network Load Balanceren keresztül fértek hozzá az adatbázisokhoz, ami mögött két PgBouncer-es példány állt, mögöttük pedig az összes PostgreSQL szerver.
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

A Patroni megvalósításához ki kellett választanunk egy elosztott tárolási fürt konfigurációt. A Patroni olyan elosztott konfigurációs tárolórendszerekkel dolgozik, mint az etcd, Zookeeper, Consul. Most van a piacon egy teljes értékű Consul klaszterünk, amely a Vaulttal együttműködve működik, és már nem használjuk. Remek ok arra, hogy elkezdje a Consul rendeltetésszerű használatát.

Hogyan dolgozik Patroni a konzullal

Van egy Consul klaszterünk, amely három csomópontból áll, és egy Patroni klaszter, amely egy vezetőből és egy replikából áll (a Patroniban a mestert klasztervezetőnek, a szolgákat pedig replikáknak nevezik). A Patroni klaszter minden példánya folyamatosan információkat küld a fürt állapotáról a Consulnak. Ezért a Consultól mindig megtudhatja a Patroni klaszter aktuális konfigurációját és azt, hogy jelenleg ki a vezető.

Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

A Patroni és a Consul összekapcsolásához elegendő a hivatalos dokumentáció tanulmányozása, amely szerint meg kell adnia a gazdagépet http vagy https formátumban, attól függően, hogy hogyan dolgozunk a Consul-lal, és a csatlakozási sémát, opcionálisan:

host: the host:port for the Consul endpoint, in format: http(s)://host:port
scheme: (optional) http or https, defaults to http

Egyszerűnek tűnik, de itt kezdődnek a buktatók. A Consul segítségével biztonságos kapcsolaton keresztül dolgozunk https-en keresztül, és a kapcsolati konfigurációnk így fog kinézni:

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

De ez nem megy. Indításkor a Patroni nem tud csatlakozni a Consulhoz, mert úgyis megpróbál átmenni a http-n.

A probléma kezelésében a Patroni forráskódja segített. Még jó, hogy pythonban van megírva. Kiderült, hogy a host paramétert semmilyen módon nem értelmezték, és a protokollt meg kell adni a sémában. Nálunk így néz ki a Consul-lal való együttműködés működő konfigurációs blokkja:

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

konzul-sablon

Tehát a tárolót választottuk a konfigurációhoz. Most meg kell értenünk, hogy a PgBouncer hogyan fogja megváltoztatni a konfigurációját, amikor megváltoztatja a vezetőt a Patroni-fürtben. Erre a kérdésre nincs válasz a dokumentációban, mert. ott elvileg nincs leírva a PgBouncerrel való munka.

A megoldást keresve találtunk egy cikket (a címére sajnos nem emlékszem), ahol azt írták, hogy a Сonsul-template sokat segített a PgBouncer és a Patroni párosításában. Ez arra késztetett bennünket, hogy megvizsgáljuk, hogyan működik a Consul-sablon.

Kiderült, hogy a Consul-template folyamatosan figyeli a PostgreSQL-fürt konfigurációját a Consulban. Amikor a vezető megváltozik, frissíti a PgBouncer konfigurációját, és parancsot küld annak újratöltésére.

Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

A sablon nagy előnye, hogy kódként tárolódik, így új shard hozzáadásakor elég egy új commit és a sablon automatikus frissítése, támogatva az Infrastructure as code elvet.

Új építészet Patronival

Ennek eredményeként a következő munkasémát kaptuk:
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

Minden alkalmazásszerver hozzáfér a balanszerhez → mögötte két PgBouncer példány áll → minden példányon elindul a Consul-sablon, amely figyeli az egyes Patroni fürtök állapotát és figyeli a PgBouncer konfiguráció relevanciáját, amely kéréseket küld az aktuális vezetőnek. minden klaszterből.

Kézi tesztelés

Ezt a sémát lefuttattuk, mielőtt elindítottuk egy kis tesztkörnyezeten, és ellenőriztük az automatikus váltás működését. Kinyitották a táblát, megmozgatták a matricát, és abban a pillanatban „megölték” a klaszter vezetőjét. Az AWS-ben ez olyan egyszerű, mint a példány leállítása a konzolon keresztül.

Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

A matrica 10-20 másodpercen belül visszatért, majd ismét elkezdett normálisan mozogni. Ez azt jelenti, hogy a Patroni klaszter megfelelően működött: megváltoztatta a vezetőt, elküldte az információkat a Consulnak, a Consul-template pedig azonnal felvette ezeket az információkat, lecserélte a PgBouncer konfigurációt, és elküldte az újratöltés parancsát.

Hogyan lehet túlélni nagy terhelés mellett és minimálisra csökkenteni az állásidőt?

Minden tökéletesen működik! De új kérdések merülnek fel: Hogyan fog működni nagy terhelés mellett? Hogyan lehet gyorsan és biztonságosan bevezetni mindent a gyártás során?

Az első kérdés megválaszolásában segít a tesztkörnyezet, amelyen a terhelési tesztelést végezzük. Felépítését tekintve teljesen megegyezik a gyártással, és olyan tesztadatokat generált, amelyek mennyisége megközelítőleg megegyezik a gyártáséval. Úgy döntünk, hogy „megöljük” az egyik PostgreSQL-mestert a teszt során, és meglátjuk, mi történik. Előtte azonban érdemes ellenőrizni az automatikus görgetést, mert ezen a környezetben több PostgreSQL shardunk is van, így kiváló tesztelést kapunk a konfigurációs szkriptek gyártás előtt.

Mindkét feladat ambiciózusnak tűnik, de van PostgreSQL 9.6. Azonnal frissíthetünk 11.2-re?

Úgy döntünk, hogy ezt 2 lépésben tesszük: először frissítünk 11.2-re, majd elindítjuk a Patronit.

PostgreSQL frissítés

A PostgreSQL verzió gyors frissítéséhez használja a lehetőséget -k, amelyben merev hivatkozások jönnek létre a lemezen, és nincs szükség az adatok másolására. 300-400 GB-os alapon a frissítés 1 másodpercig tart.

Nagyon sok szilánkunk van, ezért a frissítést automatikusan kell elvégezni. Ennek érdekében írtunk egy Ansible játékkönyvet, amely a teljes frissítési folyamatot kezeli helyettünk:

/usr/lib/postgresql/11/bin/pg_upgrade 
<b>--link </b>
--old-datadir='' --new-datadir='' 
 --old-bindir=''  --new-bindir='' 
 --old-options=' -c config_file=' 
 --new-options=' -c config_file='

Itt fontos megjegyezni, hogy a frissítés megkezdése előtt a paraméterrel kell végrehajtani --jelölje behogy biztosan tudja frissíteni. A szkriptünk a konfigurációk helyettesítését is elvégzi a frissítés idejére. A forgatókönyvünk 30 másodperc alatt készült el, ami kiváló eredmény.

Indítsa el a Patronit

A második probléma megoldásához nézze meg a Patroni konfigurációt. A hivatalos adattárnak van egy példa konfigurációja az initdb-vel, amely felelős egy új adatbázis inicializálásáért a Patroni első indításakor. De mivel már van egy kész adatbázisunk, egyszerűen eltávolítottuk ezt a részt a konfigurációból.

Amikor elkezdtük telepíteni a Patronit egy már meglévő PostgreSQL-fürtre és futtatni, új problémába ütköztünk: mindkét szerver vezetőként indult. A Patroni semmit sem tud a fürt korai állapotáról, és megpróbálja mindkét kiszolgálót két különálló, azonos nevű fürtként elindítani. A probléma megoldásához törölnie kell a slave adatait tartalmazó könyvtárat:

rm -rf /var/lib/postgresql/

Ezt csak a rabszolgán kell megtenni!

Ha tiszta replika van csatlakoztatva, a Patroni létrehoz egy basebackup vezetőt, és visszaállítja azt a replikára, majd utoléri az aktuális állapotot a fali naplók szerint.

Egy másik nehézség, amellyel találkoztunk, hogy az összes PostgreSQL-fürt alapértelmezés szerint fő neve. Ha az egyik klaszter semmit sem tud a másikról, ez normális. Ha azonban a Patronit szeretné használni, akkor minden klaszternek egyedi névvel kell rendelkeznie. A megoldás a fürt nevének megváltoztatása a PostgreSQL konfigurációban.

terhelési teszt

Elindítottunk egy tesztet, amely szimulálja a felhasználói élményt a táblákon. Amikor a terhelés elérte az átlagos napi értéket, pontosan ugyanazt a tesztet ismételtük meg, egy példányt kikapcsoltunk a PostgreSQL vezetővel. Az automatikus feladatátvétel a vártnak megfelelően működött: Patroni megváltoztatta a vezetőt, a Consul-template frissítette a PgBouncer konfigurációját, és parancsot küldött az újratöltésre. A Grafana-ban készült grafikonjaink alapján egyértelmű volt, hogy 20-30 másodperces késések és kis mennyiségű hiba lép fel a szervereknél az adatbázishoz való kapcsolódás során. Ez egy normális helyzet, az ilyen értékek elfogadhatók a feladatátvételünkhöz, és határozottan jobbak, mint a szolgáltatás leállási ideje.

A Patroni gyártásba helyezése

Ennek eredményeként a következő tervet dolgoztuk ki:

  • Telepítse a Consul-sablont a PgBouncer szerverekre és indítsa el;
  • PostgreSQL frissítések a 11.2-es verzióra;
  • Módosítsa a fürt nevét;
  • A Patroni Cluster elindítása.

Ugyanakkor a sémánk lehetővé teszi, hogy szinte bármikor megtegyük az első pontot, sorra eltávolíthatunk minden PgBouncert a munkából, és telepíthetjük és futtathatjuk rajta a consul-sablont. Így tettük.

A gyors üzembe helyezés érdekében az Ansible-t használtuk, mivel már teszteltük az összes játékkönyvet egy tesztkörnyezetben, és a teljes szkript végrehajtási ideje 1,5-2 perc volt minden shard esetében. A szolgáltatásunk leállítása nélkül mindent sorban kiadhatunk minden egyes szilánkra, de néhány percre ki kell kapcsolnunk minden PostgreSQL-t. Ebben az esetben azok a felhasználók, akiknek az adatai ezen a szilánkon vannak, jelenleg nem működhetnek teljes mértékben, és ez számunkra elfogadhatatlan.

Ebből a helyzetből a kiutat a tervezett karbantartás jelentette, amelyre 3 havonta kerül sor. Ez az ütemezett munka ablaka, amikor teljesen leállítjuk szolgáltatásunkat és frissítjük adatbázispéldányainkat. Egy hét volt hátra a következő ablakig, és úgy döntöttünk, csak várunk és készülünk tovább. A várakozási idő alatt további biztonságba helyeztük magunkat: minden PostgreSQL shardhoz létrehoztunk egy tartalék replikát arra az esetre, ha a legfrissebb adatok megőrzése nem sikerülne, és minden egyes shardhoz hozzáadtunk egy új példányt, amelyből a Patroni-fürt új replikája lesz, hogy ne hajtson végre adattörlési parancsot . Mindez hozzájárult a hibakockázat minimalizálásához.
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

Újraindítottuk a szolgáltatásunkat, minden úgy működött, ahogy kellett, a felhasználók továbbra is dolgoztak, de a grafikonokon a Consul szervereken abnormálisan nagy terhelést vettünk észre.
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

Miért nem láttuk ezt a tesztkörnyezetben? Ez a probléma jól szemlélteti, hogy követni kell az Infrastruktúra mint kód elvet, és finomítani kell a teljes infrastruktúrán, a tesztkörnyezetektől a termelésig. Ellenkező esetben nagyon könnyű megoldani a problémát. Mi történt? A Consul először éles, majd tesztkörnyezeteken jelent meg, ennek eredményeként a tesztkörnyezeteken a Consul verziója magasabb volt, mint a gyártási verzióban. Éppen az egyik kiadásban sikerült megoldani a CPU szivárgást a consul-sablonnal való munka során. Ezért egyszerűen frissítettük a Consult, ezzel megoldva a problémát.

Indítsa újra a Patroni-fürtöt

Kaptunk azonban egy új problémát, amit nem is sejtettünk. A Consul frissítésekor egyszerűen eltávolítjuk a Consul csomópontot a fürtből a consul elhagyása paranccsal → Patroni csatlakozik egy másik Consul szerverhez → minden működik. Ám amikor elértük a Consul klaszter utolsó példányát, és elküldtük neki a consul távozási parancsot, az összes Patroni klaszter egyszerűen újraindult, és a naplókban a következő hibát láttuk:

ERROR: get_cluster
Traceback (most recent call last):
...
RetryFailedError: 'Exceeded retry deadline'
ERROR: Error communicating with DCS
<b>LOG: database system is shut down</b>

A Patroni-fürt nem tudott információkat kérni a fürtjéről, ezért újraindult.

A megoldás érdekében felvettük a kapcsolatot a Patroni szerzőivel a githubon található probléma útján. Javasolták a konfigurációs fájljaink fejlesztését:

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

Sikerült megismételnünk a problémát egy tesztkörnyezetben, és ott teszteltük ezeket a lehetőségeket, de sajnos nem működtek.

A probléma továbbra is megoldatlan. A következő megoldásokat tervezzük kipróbálni:

  • Használja a Consul-ügynököt minden Patroni-fürtpéldányon;
  • Javítsa ki a hibát a kódban.

Megértjük, hol történt a hiba: a probléma valószínűleg az alapértelmezett időtúllépés használata, amelyet a konfigurációs fájl nem ír felül. Amikor az utolsó Consul-kiszolgálót eltávolítják a fürtből, a teljes Consul-fürt több mint egy másodpercig lefagy, emiatt a Patroni nem tudja megszerezni a fürt állapotát, és teljesen újraindítja az egész fürtöt.

Szerencsére nem tapasztaltunk több hibát.

A Patroni használatának eredményei

A Patroni sikeres elindítása után minden fürthöz egy további replikát adtunk. Mostantól minden klaszterben van egy kvórum látszata: egy vezető és két replika, hogy biztonságos legyen az agy megosztottsága váltáskor.
Feladatátvevő fürt PostgreSQL + Patroni. Megvalósítási tapasztalat

A Patroni több mint három hónapja dolgozik a gyártáson. Ezalatt az idő alatt már sikerült kisegíteni minket. Nemrég az egyik fürt vezetője meghalt az AWS-ben, az automatikus feladatátvétel működött, a felhasználók pedig tovább dolgoztak. Patroni teljesítette fő feladatát.

Egy kis összefoglaló a Patroni használatáról:

  • Könnyű konfigurációmódosítás. Elegendő egy példányon módosítani a konfigurációt, és a rendszer felhúzza a teljes fürtre. Ha az új konfiguráció alkalmazásához újraindítás szükséges, a Patroni értesíti Önt. A Patroni egyetlen paranccsal újraindíthatja a teljes fürtöt, ami szintén nagyon kényelmes.
  • Az automatikus feladatátvétel működik, és már sikerült nekünk segíteni.
  • PostgreSQL frissítés alkalmazásleállás nélkül. Először frissítenie kell a replikákat az új verzióra, majd módosítania kell a vezetőt a Patroni-fürtben, és frissítenie kell a régi vezetőt. Ebben az esetben megtörténik az automatikus feladatátvétel szükséges tesztelése.

Forrás: will.com

Hozzászólás