Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Straipsnyje papasakosiu, kaip mes priartėjome prie PostgreSQL atsparumo gedimams problemos, kodėl tai mums tapo svarbu ir kas galiausiai atsitiko.

Mes turime labai apkrautą paslaugą: 2,5 milijono vartotojų visame pasaulyje, 50 100+ aktyvių vartotojų kasdien. Serveriai yra Amazonėje viename Airijos regione: nuolat veikia 50+ skirtingų serverių, iš kurių beveik XNUMX yra su duomenų bazėmis.

Visa užpakalinė programa yra didelė monolitinė būseną atitinkanti „Java“ programa, kuri palaiko nuolatinį žiniatinklio lizdo ryšį su klientu. Kai keli vartotojai vienu metu dirba vienoje plokštėje, visi jie mato pokyčius realiu laiku, nes kiekvieną pakeitimą įrašome į duomenų bazę. Per sekundę savo duomenų bazėse gauname apie 10 80 užklausų. Esant didžiausiai apkrovai Redis, per sekundę rašome 100–XNUMX XNUMX užklausų.
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Kodėl mes perėjome iš Redis į PostgreSQL

Iš pradžių mūsų paslauga dirbo su Redis – raktinių reikšmių saugykla, kuri saugo visus duomenis serverio RAM.

Redis privalumai:

  1. Didelis atsako greitis, nes viskas saugoma atmintyje;
  2. Lengva kurti atsargines kopijas ir replikuoti.

„Redis“ trūkumai mums:

  1. Realių sandorių nėra. Mes bandėme juos imituoti mūsų programos lygiu. Deja, tai ne visada veikė gerai ir reikėjo parašyti labai sudėtingą kodą.
  2. Duomenų kiekį riboja atminties kiekis. Didėjant duomenų kiekiui, padidės atmintis ir galiausiai susidursime su pasirinkto egzemplioriaus ypatybėmis, todėl AWS reikia sustabdyti paslaugą, kad pakeistume egzemplioriaus tipą.
  3. Būtina nuolat palaikyti žemą delsos lygį, nes. turime labai daug užklausų. Optimalus vėlavimo lygis mums yra 17-20 ms. 30–40 ms lygiu gauname ilgus atsakymus į užklausas iš mūsų programos ir paslaugos pablogėjimo. Deja, mums taip nutiko 2018 metų rugsėjį, kai vienas iš atvejų su Redis kažkodėl gavo 2 kartus daugiau delsos nei įprastai. Norėdami išspręsti problemą, sustabdėme paslaugą vidury dienos dėl neplaninės priežiūros ir pakeitėme probleminį Redis egzempliorių.
  4. Nesunku gauti duomenų neatitikimų net ir esant nedidelėms kodo klaidoms, o tada praleisti daug laiko rašant kodą šiems duomenims pataisyti.

Atsižvelgėme į minusus ir supratome, kad reikia pereiti prie ko nors patogesnio, su įprastomis operacijomis ir mažesne priklausomybe nuo delsos. Atliko tyrimą, išanalizavo daugybę variantų ir pasirinko PostgreSQL.

Jau 1,5 metų pereiname prie naujos duomenų bazės ir perkėlėme tik nedidelę dalį duomenų, todėl dabar dirbame vienu metu su Redis ir PostgreSQL. Daugiau informacijos apie duomenų perkėlimo ir perjungimo tarp duomenų bazių etapus parašyta mano kolegos straipsnis.

Kai pirmą kartą pradėjome judėti, mūsų programa dirbo tiesiogiai su duomenų baze ir pasiekė pagrindinį Redis ir PostgreSQL. „PostgreSQL“ klasterį sudarė pagrindinis ir replika su asinchronine replikacija. Štai kaip atrodė duomenų bazės schema:
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

PgBouncer diegimas

Kol mes judėjome, produktas taip pat vystėsi: daugėjo vartotojų ir serverių, kurie dirbo su PostgreSQL, pradėjo trūkti ryšių. „PostgreSQL“ kiekvienam ryšiui sukuria atskirą procesą ir sunaudoja išteklius. Ryšių skaičių galite padidinti iki tam tikro taško, priešingu atveju yra galimybė gauti neoptimalų duomenų bazės našumą. Idealus variantas tokioje situacijoje būtų pasirinkti ryšio tvarkyklę, kuri stovės priešais bazę.

Turėjome dvi ryšio tvarkyklės parinktis: Pgpool ir PgBouncer. Tačiau pirmasis nepalaiko transakcinio darbo su duomenų baze režimo, todėl pasirinkome PgBouncer.

Sukūrėme tokią darbo schemą: mūsų aplikacija pasiekia vieną PgBouncer, už kurio yra PostgreSQL meistrai, o už kiekvieno pagrindinio kompiuterio yra viena kopija su asinchronine replikacija.
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Tuo pačiu metu negalėjome saugoti viso duomenų kiekio „PostgreSQL“ ir mums buvo svarbus darbo su duomenų baze greitis, todėl pradėjome „PostgreSQL“ dalyti programos lygiu. Aukščiau aprašyta schema yra gana patogi tam: pridedant naują PostgreSQL shardą, pakanka atnaujinti PgBouncer konfigūraciją ir programa iš karto gali dirbti su naujuoju shardu.

PgBouncer failover

Ši schema veikė iki to momento, kai mirė vienintelis PgBouncer egzempliorius. Esame AWS, kur visi egzemplioriai veikia naudojant aparatinę įrangą, kuri periodiškai miršta. Tokiais atvejais egzempliorius tiesiog perkeliamas į naują aparatinę įrangą ir vėl veikia. Taip atsitiko su PgBouncer, bet jis tapo nepasiekiamas. Šio kritimo rezultatas – mūsų paslauga nepasiekiama 25 minutes. AWS rekomenduoja tokioms situacijoms naudoti vartotojo pusės atleidimą, kuris tuo metu mūsų šalyje nebuvo įgyvendintas.

Po to rimtai pagalvojome apie PgBouncer ir PostgreSQL klasterių atsparumą gedimams, nes panaši situacija gali atsitikti su bet kuriuo mūsų AWS paskyros egzemplioriumi.

PgBouncer gedimų tolerancijos schemą sukūrėme taip: visi programų serveriai pasiekia tinklo apkrovos balansavimo priemonę, už kurios yra du PgBouncer. Kiekvienas „PgBouncer“ žiūri į tą patį „PostgreSQL“ pagrindinį kiekvienos skilties pagrindą. Jei AWS egzemplioriaus strigtis vėl įvyksta, visas srautas nukreipiamas per kitą PgBouncer. „Network Load Balancer“ perkrovą teikia AWS.

Ši schema leidžia lengvai pridėti naujų PgBouncer serverių.
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Sukurkite „PostgreSQL“ failų perkėlimo klasterį

Spręsdami šią problemą svarstėme įvairius variantus: savarankiškai parašytas failover, repmgr, AWS RDS, Patroni.

Savarankiškai parašyti scenarijai

Jie gali stebėti pagrindinio kompiuterio darbą ir, jam sugedus, perkelti kopiją į pagrindinį kompiuterį ir atnaujinti PgBouncer konfigūraciją.

Šio metodo privalumai yra maksimalus paprastumas, nes jūs patys rašote scenarijus ir tiksliai suprantate, kaip jie veikia.

Trūkumai:

  • Valdytojas galėjo nemirė, vietoj to galėjo įvykti tinklo gedimas. Failover, to nežinodamas, pateiks kopiją meistrui, o senasis meistras dirbs toliau. Dėl to mes gausime du serverius pagrindinio vaidmens ir nežinosime, kuris iš jų turi naujausius duomenis. Ši situacija taip pat vadinama smegenų padalijimu;
  • Likome be atsakymo. Mūsų konfigūracijoje pagrindinis ir viena kopija, po perjungimo, kopija pereina į pagrindinį ir mes nebeturime kopijų, todėl turime rankiniu būdu pridėti naują kopiją;
  • Mums reikia papildomo perkėlimo operacijos stebėjimo, o turime 12 PostgreSQL skeveldrų, o tai reiškia, kad turime stebėti 12 grupių. Padidėjus skeveldrų skaičiui, taip pat turite nepamiršti atnaujinti failų perkėlimo.

Savarankiškai parašytas perjungimas atrodo labai sudėtingas ir reikalauja nereikšmingo palaikymo. Turint vieną PostgreSQL klasterį, tai būtų lengviausias pasirinkimas, tačiau jis nesikeičia, todėl mums netinka.

Repmgr

„PostgreSQL“ klasterių replikacijos tvarkyklė, kuri gali valdyti „PostgreSQL“ klasterio veikimą. Tuo pačiu metu jame nėra automatinio perjungimo iš dėžutės, todėl darbui turėsite parašyti savo „įvyniojimą“ ant gatavo sprendimo. Taigi viskas gali pasirodyti dar sudėtingiau nei su savarankiškai parašytais scenarijais, todėl mes net nebandėme Repmgr.

AWS RDS

Palaiko viską, ko mums reikia, moka daryti atsargines kopijas ir palaiko ryšių telkinį. Jis turi automatinį perjungimą: kai pagrindinis miršta, replika tampa nauju pagrindiniu, o AWS pakeičia dns įrašą į naują pagrindinį, o kopijos gali būti skirtinguose AZ.

Trūkumai yra tai, kad trūksta tikslių koregavimų. Kaip tikslaus derinimo pavyzdys: mūsų egzemplioriai turi apribojimus tcp ryšiams, kurių, deja, negalima padaryti naudojant RDS:

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

Be to, AWS RDS yra beveik dvigubai brangesnis už įprastą egzemplioriaus kainą, o tai buvo pagrindinė priežastis atsisakyti šio sprendimo.

Patroni

Tai yra „Python“ šablonas, skirtas „PostgreSQL“ valdyti su gera dokumentacija, automatiniu perkėlimu ir šaltinio kodu „github“.

Patroni privalumai:

  • Kiekvienas konfigūracijos parametras yra aprašytas, aišku, kaip jis veikia;
  • Automatinis perjungimas veikia iš karto;
  • Parašyta python, o kadangi mes patys daug rašome python, tai mums bus lengviau spręsti problemas ir, galbūt, net padėti vystyti projektą;
  • Visiškai valdo PostgreSQL, leidžia vienu metu keisti konfigūraciją visuose klasterio mazguose ir, jei klasterį reikia paleisti iš naujo, kad būtų pritaikyta nauja konfigūracija, tai galima padaryti dar kartą naudojant Patroni.

Trūkumai:

  • Iš dokumentacijos neaišku, kaip teisingai dirbti su PgBouncer. Nors sunku tai pavadinti minusu, nes Patroni užduotis yra valdyti PostgreSQL, o kaip vyks ryšiai su Patroni jau yra mūsų problema;
  • Yra keletas „Patroni“ diegimo didelėse apimties pavyzdžių, tuo tarpu yra daug pavyzdžių, kaip įdiegti nuo nulio.

Todėl pasirinkome „Patroni“, kad sukurtume perkėlimo grupę.

Patroni įgyvendinimo procesas

Prieš „Patroni“ turėjome 12 „PostgreSQL“ fragmentų, kurių konfigūracija buvo viena pagrindinė ir viena kopija su asinchroniniu replikavimu. Programų serveriai duomenų bazes pasiekė per tinklo apkrovos balansavimo priemonę, už kurios buvo du egzemplioriai su PgBouncer, o už jų buvo visi PostgreSQL serveriai.
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Norėdami įdiegti „Patroni“, turėjome pasirinkti paskirstytos saugyklos klasterio konfigūraciją. Patroni dirba su paskirstytomis konfigūracijos saugojimo sistemomis, tokiomis kaip etcd, Zookeeper, Consul. Rinkoje ką tik turime pilnavertį konsulų klasterį, kuris veikia kartu su Vault ir jo nebenaudojame. Puiki priežastis pradėti naudoti Consul pagal paskirtį.

Kaip Patroni dirba su konsulu

Turime „Consul“ klasterį, kurį sudaro trys mazgai, ir „Patroni“ klasterį, kurį sudaro lyderis ir kopija (Patroni kalboje šeimininkas vadinamas klasterio lyderiu, o vergai – replikomis). Kiekvienas Patroni klasterio egzempliorius nuolat siunčia konsului informaciją apie klasterio būklę. Todėl iš Consul visada galite sužinoti dabartinę Patroni klasterio konfigūraciją ir kas šiuo metu yra lyderis.

Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Norėdami prijungti „Patroni“ prie „Consul“, pakanka išstudijuoti oficialią dokumentaciją, kurioje teigiama, kad reikia nurodyti pagrindinį kompiuterį http arba https formatu, atsižvelgiant į tai, kaip dirbame su „Consul“, ir ryšio schemą, pasirinktinai:

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

Atrodo paprasta, bet čia prasideda spąstai. Su Consul dirbame saugiu ryšiu per https ir mūsų ryšio konfigūracija atrodys taip:

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

Bet tai neveikia. Paleidžiant Patroni negali prisijungti prie Consul, nes vis tiek bando pereiti per http.

Patroni šaltinio kodas padėjo išspręsti problemą. Gerai, kad parašyta python. Pasirodo, pagrindinio kompiuterio parametras jokiu būdu nėra analizuojamas, o protokolas turi būti nurodytas schemoje. Štai kaip mums atrodo darbinis konfigūracijos blokas darbui su Consul:

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

konsulas-šablonas

Taigi, konfigūracijai pasirinkome saugyklą. Dabar turime suprasti, kaip PgBouncer pakeis savo konfigūraciją keičiant lyderį Patroni klasteryje. Į šį klausimą dokumentuose atsakymo nėra, nes. ten iš esmės darbas su PgBouncer neaprašytas.

Ieškodami sprendimo, radome straipsnį (deja, pavadinimo nepamenu), kuriame buvo rašoma, kad Сonsul-template labai padėjo suporuoti PgBouncer ir Patroni. Tai paskatino mus ištirti, kaip veikia „Consul-template“.

Paaiškėjo, kad „Consul-template“ nuolat stebi „Consul“ esančio „PostgreSQL“ klasterio konfigūraciją. Pasikeitus lyderiui, jis atnaujina PgBouncer konfigūraciją ir siunčia komandą ją įkelti iš naujo.

Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Didelis šablono pliusas yra tai, kad jis saugomas kaip kodas, todėl pridedant naują shardą užtenka atlikti naują commit ir automatiškai atnaujinti šabloną, palaikant Infrastructure as code principą.

Nauja architektūra su Patroni

Dėl to gavome tokią darbo schemą:
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Visi taikomųjų programų serveriai pasiekia balansuotoją → už jo yra du PgBouncer egzemplioriai → kiekviename egzemplioriuje paleidžiamas Consul šablonas, kuris stebi kiekvieno Patroni klasterio būseną ir stebi PgBouncer konfigūracijos, kuri siunčia užklausas esamam lyderiui, tinkamumą. kiekvieno klasterio.

Rankinis testavimas

Paleidome šią schemą prieš paleisdami ją nedidelėje bandomojoje aplinkoje ir patikrinome automatinio perjungimo veikimą. Jie atidarė lentą, perkėlė lipduką ir tuo metu „nužudė“ klasterio lyderį. AWS tai taip paprasta, kaip išjungti egzempliorių per konsolę.

Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Lipdukas grįžo per 10-20 sekundžių ir vėl pradėjo normaliai judėti. Tai reiškia, kad „Patroni“ klasteris veikė tinkamai: pakeitė lyderį, išsiuntė informaciją „Consul“, o „Consul-template“ iš karto paėmė šią informaciją, pakeitė PgBouncer konfigūraciją ir išsiuntė komandą perkrauti.

Kaip išgyventi esant didelei apkrovai ir kuo mažiau prastovų?

Viskas veikia puikiai! Tačiau kyla naujų klausimų: kaip tai veiks esant didelei apkrovai? Kaip greitai ir saugiai viską išvynioti gamyboje?

Bandymo aplinka, kurioje atliekame apkrovos testavimą, padeda atsakyti į pirmąjį klausimą. Ji visiškai identiška gamybai pagal architektūrą ir sugeneravo bandymų duomenis, kurių apimtis apytiksliai prilygsta gamybai. Nusprendžiame tiesiog „nužudyti“ vieną iš „PostgreSQL“ meistrų testo metu ir pažiūrėti, kas atsitiks. Tačiau prieš tai svarbu patikrinti automatinį sukimąsi, nes šioje aplinkoje turime keletą PostgreSQL skeveldrų, todėl prieš pradedant gamybą gausime puikų konfigūracijos scenarijų testavimą.

Abi užduotys atrodo ambicingos, tačiau turime PostgreSQL 9.6. Ar galime iš karto atnaujinti į 11.2?

Nusprendžiame tai padaryti dviem veiksmais: pirmiausia atnaujinti į 2, tada paleisti Patroni.

PostgreSQL atnaujinimas

Norėdami greitai atnaujinti PostgreSQL versiją, naudokite parinktį -k, kuriame diske sukuriamos standžiosios nuorodos ir nereikia kopijuoti jūsų duomenų. Naudojant 300–400 GB, atnaujinimas trunka 1 sekundę.

Turime daug šukių, todėl atnaujinimą reikia atlikti automatiškai. Norėdami tai padaryti, parašėme Ansible žaidimų knygą, kurioje už mus tvarkomas visas atnaujinimo procesas:

/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='

Čia svarbu pažymėti, kad prieš pradėdami naujinimą turite jį atlikti naudodami parametrą --patikrintikad įsitikintumėte, jog galite atnaujinti. Mūsų scenarijus taip pat pakeičia konfigūracijas atnaujinimo metu. Mūsų scenarijus buvo baigtas per 30 sekundžių, o tai yra puikus rezultatas.

Paleiskite „Patroni“.

Norėdami išspręsti antrąją problemą, tiesiog pažiūrėkite į Patroni konfigūraciją. Oficialioje saugykloje yra pavyzdinė konfigūracija su initdb, kuri yra atsakinga už naujos duomenų bazės inicijavimą, kai pirmą kartą paleidžiate Patroni. Bet kadangi mes jau turime paruoštą duomenų bazę, mes tiesiog pašalinome šią skiltį iš konfigūracijos.

Kai pradėjome diegti Patroni jau esamame PostgreSQL klasteryje ir jį paleisti, susidūrėme su nauja problema: abu serveriai pradėjo veikti kaip lyderiai. Patroni nieko nežino apie ankstyvą klasterio būseną ir bando paleisti abu serverius kaip dvi atskiras grupes tuo pačiu pavadinimu. Norėdami išspręsti šią problemą, turite ištrinti katalogą su duomenimis apie vergą:

rm -rf /var/lib/postgresql/

Tai reikia padaryti tik vergui!

Kai prijungiama švari kopija, „Patroni“ sukuria bazinės atsarginės kopijos lyderį ir atkuria ją į kopiją, o tada pasiveja esamą būseną pagal „wallog“ žurnalus.

Kitas sunkumas, su kuriuo susidūrėme, yra tai, kad visi PostgreSQL klasteriai pagal numatytuosius nustatymus yra pavadinti pagrindiniais. Kai kiekvienas klasteris nieko nežino apie kitą, tai yra normalu. Bet kai norite naudoti Patroni, visos grupės turi turėti unikalų pavadinimą. Sprendimas yra pakeisti klasterio pavadinimą „PostgreSQL“ konfigūracijoje.

apkrovos testas

Pradėjome testą, kuris imituoja naudotojo patirtį lentose. Kai apkrova pasiekė mūsų vidutinę dienos vertę, pakartojome lygiai tą patį testą, išjungėme vieną egzempliorių su PostgreSQL lyderiu. Automatinis perjungimas veikė taip, kaip tikėjomės: „Patroni“ pakeitė lyderį, „Consul-template“ atnaujino „PgBouncer“ konfigūraciją ir išsiuntė komandą įkelti iš naujo. Remiantis mūsų grafikais Grafana, buvo aišku, kad yra 20–30 sekundžių vėlavimų ir nedidelis kiekis klaidų iš serverių, susijusių su prisijungimu prie duomenų bazės. Tai yra normali situacija, tokios vertės yra priimtinos mūsų perjungimui ir yra tikrai geresnės nei paslaugos prastovos.

Patroni pristatymas į gamybą

Dėl to mes sukūrėme tokį planą:

  • Įdiekite „Consul“ šabloną „PgBouncer“ serveriuose ir paleiskite;
  • PostgreSQL naujinimai į 11.2 versiją;
  • Pakeiskite klasterio pavadinimą;
  • Patroni klasterio pradžia.

Tuo pačiu metu mūsų schema leidžia mums beveik bet kuriuo metu padaryti pirmąjį tašką, mes galime pašalinti kiekvieną PgBouncer iš darbo paeiliui ir įdiegti bei paleisti konsulinį šabloną. Taip ir padarėme.

Norėdami greitai įdiegti, mes naudojome Ansible, nes jau išbandėme visas žaidimų knygas bandomojoje aplinkoje, o viso scenarijaus vykdymo laikas buvo nuo 1,5 iki 2 minučių kiekvienam fragmentui. Galėtume pateikti viską paeiliui į kiekvieną skeveldrą nestabdydami paslaugos, tačiau kiekvieną PostgreSQL turėtume išjungti kelioms minutėms. Tokiu atveju vartotojai, kurių duomenys yra šioje skeveldėje, šiuo metu negali visiškai dirbti, o tai mums nepriimtina.

Išeitis iš šios situacijos buvo planinė priežiūra, kuri vyksta kas 3 mėnesius. Tai suplanuotų darbų langas, kai visiškai išjungiame paslaugą ir atnaujiname duomenų bazės egzempliorius. Iki kito lango buvo likusi savaitė, o mes nusprendėme tiesiog palaukti ir ruoštis toliau. Laukimo metu papildomai apsisaugojome: kiekvienai PostgreSQL skedei iškėlėme atsarginę kopiją, jei nepavyktų išsaugoti naujausių duomenų, ir kiekvienai daliai pridėjome naują egzempliorių, kuris turėtų tapti nauja kopija Patroni klasteryje, kad nebūtų vykdoma komanda ištrinti duomenis . Visa tai padėjo sumažinti klaidų riziką.
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Iš naujo paleidome paslaugą, viskas veikė kaip priklauso, vartotojai dirbo toliau, tačiau grafikuose pastebėjome neįprastai didelę Consul serverių apkrovą.
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Kodėl mes to nematėme bandymo aplinkoje? Ši problema puikiai iliustruoja, kad būtina vadovautis infrastruktūros kaip kodo principu ir tobulinti visą infrastruktūrą, nuo testavimo aplinkų iki gamybos. Priešingu atveju labai lengva išspręsti problemą. Kas nutiko? „Consul“ pirmiausia pasirodė gamybinėje, o vėliau bandomojoje aplinkoje, todėl bandomojoje aplinkoje „Consul“ versija buvo aukštesnė nei gamybinėje. Tiesiog viename iš leidimų buvo išspręstas procesoriaus nutekėjimas dirbant su konsuliniu šablonu. Todėl mes tiesiog atnaujinome „Consul“, taip išspręsdami problemą.

Iš naujo paleiskite „Patroni“ klasterį

Tačiau sulaukėme naujos problemos, kurios net neįtarėme. Atnaujindami Consul, mes tiesiog pašaliname Consul mazgą iš klasterio, naudodami komandą consul left → Patroni prisijungia prie kito Consul serverio → viskas veikia. Bet kai pasiekėme paskutinį konsulų grupės egzempliorių ir išsiuntėme jam komandą išeiti iš konsulo, visi „Patroni“ klasteriai tiesiog paleidžiami iš naujo, o žurnaluose pamatėme šią klaidą:

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>

„Patroni“ klasteriui nepavyko gauti informacijos apie savo grupę ir ji buvo paleista iš naujo.

Norėdami rasti sprendimą, susisiekėme su „Patroni“ autoriais per „github“ problemą. Jie pasiūlė patobulinti mūsų konfigūracijos failus:

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

Pavyko pakartoti problemą bandomojoje aplinkoje ir ten išbandėme šias parinktis, bet, deja, jos neveikė.

Problema vis dar lieka neišspręsta. Planuojame išbandyti šiuos sprendimus:

  • Naudokite „Consul-agent“ kiekviename „Patroni“ klasterio egzemplioriuje;
  • Išspręskite problemą kode.

Suprantame, kur įvyko klaida: tikriausiai problema yra numatytojo skirtojo laiko naudojimas, kuris nepaisomas naudojant konfigūracijos failą. Kai paskutinis Consul serveris pašalinamas iš klasterio, visas Consul klasteris pakimba ilgiau nei sekundę, dėl to Patroni negali gauti klasterio būsenos ir visiškai iš naujo paleidžia visą klasterį.

Laimei, daugiau klaidų nepatyrėme.

Patroni naudojimo rezultatai

Sėkmingai paleidę „Patroni“, į kiekvieną klasterį įtraukėme papildomą kopiją. Dabar kiekviename klasteryje yra kvorumo panašumas: vienas lyderis ir dvi kopijos, skirtos apsauginiam tinklui, jei perjungiant smegenis būtų padalintas.
Failover Cluster PostgreSQL + Patroni. Įgyvendinimo patirtis

Patroni gamina daugiau nei tris mėnesius. Per tą laiką jis jau spėjo mums padėti. Neseniai AWS mirė vieno iš klasterių lyderis, veikė automatinis perjungimas, o vartotojai toliau dirbo. Patroni įvykdė savo pagrindinę užduotį.

Nedidelė Patroni naudojimo santrauka:

  • Lengva keisti konfigūraciją. Pakanka pakeisti konfigūraciją viename egzemplioriuje ir jis bus įtrauktas į visą klasterį. Jei norint pritaikyti naują konfigūraciją, reikia paleisti iš naujo, „Patroni“ jums apie tai praneš. Patroni gali iš naujo paleisti visą klasterį viena komanda, o tai taip pat labai patogu.
  • Automatinis perjungimas veikia ir jau spėjo mums padėti.
  • PostgreSQL atnaujinimas be programos prastovos. Pirmiausia turite atnaujinti kopijas į naują versiją, tada pakeisti „Patroni“ klasterio lyderį ir atnaujinti senąjį lyderį. Tokiu atveju atliekamas būtinas automatinio perjungimo testavimas.

Šaltinis: www.habr.com

Добавить комментарий