{"id":35706,"date":"2019-10-31T22:05:50","date_gmt":"2019-10-31T19:05:50","guid":{"rendered":"https:\/\/prohoster.info\/blog\/otkazoustojchivyj-klaster-postgresql-patroni-opyt-vnedreniya\/"},"modified":"2026-05-18T20:58:46","modified_gmt":"2026-05-18T18:58:46","slug":"otkazoustojchivyj-klaster-postgresql-patroni-opyt-vnedreniya","status":"publish","type":"post","link":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/otkazoustojchivyj-klaster-postgresql-patroni-opyt-vnedreniya","title":{"rendered":"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Selles artiklis r\u00e4\u00e4gin, kuidas me l\u00e4henesime PostgreSQL-i t\u00f5rke taastamise k\u00fcsimusele, miks see meile oluline oli ja mis l\u00f5puks v\u00e4lja tuli.<\/p>\n<p>Meil on suure koormusega teenus: 2,5 miljonit kasutajat \u00fcle kogu maailma, 50K+ aktiivset kasutajat igap\u00e4evaselt. Serverid asuvad Amazones \u00fches Iiri regioonis: t\u00f6\u00f6s on pidevalt 100+ erinevat serverit, neist peaaegu 50 on andmebaasidega.<\/p>\n<p>Kogu backend on suur monoliitne stateful-rakendus Java-s, mis hoiab pidevat websocketi \u00fchendust kliendiga. Kui mitu kasutajat t\u00f6\u00f6tab samal tahvelarvutil, n\u00e4evad nad k\u00f5iki muudatusi reaalajas, kuna iga muudatus salvestatakse andmebaasi. Meil on umbes 10K p\u00e4ringut sekundis meie andmebaasidele. Tipukoormuse ajal kirjutame Redis-i 80-100K p\u00e4ringut sekundis.<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/443f85815b0560fade7db5b639942935.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><br \/>\n<a rel=\"nofollow\" name=\"habracut\"><\/a><\/p>\n<h2>Miks me l\u00e4ksime Redisilt PostgreSQL-ile \u00fcle<\/h2>\n<p>Alguses t\u00f6\u00f6tas meie teenus Redisiga, v\u00f5tme-v\u00e4\u00e4rtus salvestuss\u00fcsteemiga, mis hoiab k\u00f5iki andmeid m\u00e4lus <a href=\"https:\/\/prohoster.info\/et\/server\/\">serverilt<\/a>.<\/p>\n<p>Redis'i plussid:<\/p>\n<ol>\n<li>K\u00f5rge vastamiskiirus, kuna k\u00f5ik on m\u00e4lus;<\/li>\n<li>Mugav varukoopiate ja replikatsioonide tegemine.<\/li>\n<\/ol>\n<p>Redis'i miinused meie jaoks:<\/p>\n<ol>\n<li>Tegelikke tehinguid ei ole. Proovisime neid simuleerida meie rakenduse tasemel. Kahjuks ei t\u00f6\u00f6tanud see alati h\u00e4sti ja n\u00f5udis v\u00e4ga keerulise koodi kirjutamist.<\/li>\n<li>Andmete maht on piiratud m\u00e4lumahu j\u00e4rgi. Kui andmete hulk suureneb, kasvab m\u00e4lu ja l\u00f5puks j\u00f5uame valitud instantsi omaduste piiridesse, mis AWS-is n\u00f5uab meie teenuse peatamist instantsi t\u00fc\u00fcbi muutmiseks.<\/li>\n<li>Peame pidevalt hoidma madalat latentsus taset, kuna meil on v\u00e4ga palju p\u00e4ringuid. Meie jaoks optimaalne viivituse tase on 17-20 ms. 30-40 ms tasemel saame pika vastuse p\u00e4ringutele meie rakenduse eest ja teenuse halvenemise. Kahjuks juhtus see meil septembris 2018, kui \u00fcks Redis-i instants sai mingil p\u00f5hjusel viivituse, mis oli kaks korda suurem kui tavaliselt. Probleemi lahendamiseks peatasime teenuse t\u00f6\u00f6p\u00e4eva keskel etten\u00e4gematuks hoolduseks ja vahetasime probleemse Redis-i instantsi.<\/li>\n<li>Andmete konsistentsuse kadumine on lihtne isegi v\u00e4ikeste vigade korral koodis ja seej\u00e4rel v\u00f5ib kuluda palju aega nende andmete parandamiseks vajaliku koodi kirjutamiseks.<\/li>\n<\/ol>\n<p>Me v\u00f5tsime arvesse puudusi ja m\u00f5istsime, et peame liikuma millegi mugavama suunas, normaalsemate tehingute ja v\u00e4iksema s\u00f5ltuvusega latentsusest. Tegime uuringu, anal\u00fc\u00fcsisime mitmeid valikuid ja valisime PostgreSQL.<\/p>\n<p>Uuele andmebaasile oleme \u00fcle kolinud juba 1,5 aastat ja edastanud vaid v\u00e4ikese osa andmetest, seega t\u00f6\u00f6tame praegu samal ajal Redis'i ja PostgreSQL'iga. Rohkem etappidest ja andmete \u00fcleviimisest andmebaaside vahel on kirjutatud <a href=\"https:\/\/habr.com\/ru\/company\/miro\/blog\/437826\/\" rel=\"nofollow\">minu kolleegi artiklis<\/a>.<\/p>\n<p>Kui me alles alustasime \u00fcleminekut, t\u00f6\u00f6tas meie rakendus otse andmebaasiga ja p\u00f6\u00f6rdus Redis'i ja PostgreSQL'i poole. PostgreSQL klaster koosnes peakontorist ja as\u00fcnkroneeritud replikast. Nii n\u00e4gi v\u00e4lja andmebaaside t\u00f6\u00f6 skeem:<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/674dd77de4c8b48a946c9f64c0b2fdd1.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<h2>PgBouncer'i rakendamine<\/h2>\n<p>Kuna me \u00fclemineku k\u00e4igus arendasime ka toodet: kasutajate arv ja PostgreSQL'iga t\u00f6\u00f6tavate serverite arv suurenes, ja meil hakkas puuduma \u00fchendusi. PostgreSQL loob iga \u00fchenduse jaoks eraldi protsessi ja tarbib ressursse. \u00dchenduste arvu v\u00f5ib suurendada teatud piirini, vastasel juhul on oht saada alatehnilise t\u00f6\u00f6 andmebaas. Sellises olukorras oleks ideaalne valida \u00fchendusehaldur, mis paigaldataks andmebaasi ette.<\/p>\n<p>Meil oli kaks valikut \u00fchendusehalduriks: Pgpool ja PgBouncer. Kuid esimene ei toeta andmebaasi tehingure\u017eiimi, seet\u00f5ttu valisime PgBouncer'i.<\/p>\n<p>Seadsime \u00fcles j\u00e4rgmise t\u00f6\u00f6 skeemi: meie rakendus p\u00f6\u00f6rdub \u00fche PgBouncer'i poole, mille taga on PostgreSQL'i peamised serverid, ja iga peamise konto taga on \u00fcks as\u00fcnkroneeritud replik.<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/dabcb7f6006520c4fec85fb925e8975e.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>Samal ajal ei saanud me salvestada kogu andmevoogu PostgreSQL'i ja meile oli oluline andmebaasi t\u00f6\u00f6 kiirus, seega hakkasime PostgreSQL'i andmebaasi sharding'iga rakenduse tasemel. \u00dclaltoodud skeem on selle jaoks suhteliselt mugav: uue shard'i lisamisel on PostgreSQL'i konfiguratsiooni lihtsalt uuendada ja rakendus v\u00f5ib kohe uue shard'iga t\u00f6\u00f6tada.<\/p>\n<h3>PgBouncer'i talitlush\u00e4iretunne<\/h3>\n<p>See skeem t\u00f6\u00f6tas seni, kuni ainus PgBouncer'i instants hetkel ei kadunud. Oleme AWS-is, kus k\u00f5ik instantsid t\u00f6\u00f6tavad riistvaral, mis aeg-ajalt kukub. Sellistel juhtudel liigub instants lihtsalt uuele riistvarale ja t\u00f6\u00f6tab j\u00e4lle. Nii juhtus ka PgBouncer'i puhul, kuid see muutus k\u00e4ttesaamatuks. Selle purunemise tulemuseks oli meie teenuse t\u00f5rge 25 minutiks. AWS soovitab selliste olukordade jaoks kasutada kasutaja poolel \u00fcleliiksust, mida meie hetkel ei olnud rakendanud.<\/p>\n<p>P\u00e4rast seda hakkasime t\u00f5siselt m\u00f5tlema PgBouncer'i ja PostgreSQL'i klastrite t\u00f6\u00f6kindlusele, sest sarnane olukord v\u00f5is korduda mis tahes meie AWS kontol asuvas instantsis.<\/p>\n<p>PgBouncer'i t\u00f6\u00f6kindluse skeemi ehitasime j\u00e4rgmiselt: k\u00f5ik rakendusserverid p\u00f6\u00f6rduvad Network Load Balancer'i poole, mille taga on kaks PgBouncer'it. Iga PgBouncer vaatab sama master PostgreSQL'i igas shardis. Kui situatsioon AWS-i instantsi kukkumisega kordub, suunatakse kogu liiklus teise PgBouncer'i kaudu. Network Load Balancer'i t\u00f6\u00f6kindlust tagab AWS.<\/p>\n<p>See skeem v\u00f5imaldab probleemideta lisada uusi PgBouncer'e.<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/2c1f1e7d9f7be4fdeb43858520d55e36.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<h2>T\u00f6\u00f6kindla PostgreSQL'i klusteri loomine<\/h2>\n<p>Selle probleemi lahendamisel kaalume erinevaid valikuid: isetehtud failover, repmgr, AWS RDS, Patroni.<\/p>\n<h3>Isetehitatud skriptid<\/h3>\n<p>Saavad j\u00e4lgida master'i t\u00f6\u00f6d ja, kui see kukub, t\u00f5sta replikatsioon master'iks ja uuendada PgBouncer'i konfiguratsiooni.<\/p>\n<p>Selle l\u00e4henemise plussid on maksimaalne lihtsus, sest kirjutate ise skripte ja m\u00f5istate t\u00e4pselt, kuidas need t\u00f6\u00f6tavad.<\/p>\n<p>Miinused:<\/p>\n<ul>\n<li>Master ei pruugi olla surnud, v\u00f5ib olla ka v\u00f5rgu t\u00f5rge. Failover, teadmata sellest, t\u00f5ukab replikatsiooni master'iks, samas kui vana master j\u00e4tkab t\u00f6\u00f6tamist. Tulemuseks on, et meil on kaks serverit master'i rollis ja me ei tea, millel on viimased aktiivsed andmed. Sellist olukorda nimetatakse ka split-brain'iks.<\/li>\n<li>J\u00e4ime ilma replikast. Meie konfiguratsioonis on master ja \u00fcks replikatsioon, p\u00e4rast \u00fcleviimist t\u00f5ukatakse replikatsioon master'iks ja meil ei ole enam replikasid, seega peame k\u00e4sitsi lisama uue replikatsiooni.<\/li>\n<li>On vajalik t\u00e4iendav failover'i t\u00f6\u00f6tamise j\u00e4lgimine, samas on meil 12 PostgreSQL'i shard'i, seega peame j\u00e4lgima 12 klastrit. Kui shard'ide arv suureneb, ei tohi unustada failover'it uuendada.<\/li>\n<\/ul>\n<p>Kohandatud failover tundub v\u00e4ga keeruline ja n\u00f5uab mitte triviaalset tuge. \u00dche PostgreSQL-klastriga on see k\u00f5ige lihtsam variant, kuid see ei ole skaleeritav, seega meie jaoks ei sobi.<\/p>\n<h3>Repmgr<\/h3>\n<p>PostgreSQL klastrite replikatsiooni haldaja, mis oskab hallata PostgreSQL klastri t\u00f6\u00f6d. Samas puudub selles automaatne failover \u201ekarbist v\u00e4lja\u201d, seega on vajalik kirjutada selle valmis lahenduse peale oma \u201e\u00fcmberpakend\u201d. Nii et k\u00f5ik v\u00f5ib osutuda isegi keerulisemaks kui kohandatud skriptide puhul, seega ei proovinud me isegi Repmgr.<\/p>\n<h3>AWS RDS<\/h3>\n<p>Toetab k\u00f5ike vajalikku meie jaoks, oskab teha varukoopiaid ja toetab \u00fchenduste basseini. Omab automaatset vahetust: kui master sureb, muutub replikast uus master ja AWS muudab dns-kirje uuele masterile, samal ajal kui replikad v\u00f5ivad olla erinevates AZ-des.<\/p>\n<p>Puudustena v\u00f5ib v\u00e4lja tuua peente seadete puudumise. N\u00e4iteks peene seadistusena on meie instantsidel TCP-\u00fchenduste jaoks piirangud, mida kahjuks RDS-is teha ei saa:<\/p>\n<pre><code class=\"python\">net.ipv4.tcp_keepalive_time=10\nnet.ipv4.tcp_keepalive_intvl=1\nnet.ipv4.tcp_keepalive_probes=5\nnet.ipv4.tcp_retries2=3\n<\/code><\/pre>\n<p>Lisaks on AWS RDS hind peaaegu kaks korda kallim kui tava hind instantside puhul, mis oli ka peamine p\u00f5hjus selle lahenduse k\u00e4est \u00e4ra \u00fctlemiseks.<\/p>\n<h3>Patronit<\/h3>\n<p>See on Pythonis kirjutatud mall PostgreSQL haldamiseks, millel on hea dokumentatsioon, automaatne failover ja source code GitHubis.<\/p>\n<p>Patroni plussid:<\/p>\n<ul>\n<li>Iga seadistuse parameeter on kirjas, on selge, kuidas mis t\u00f6\u00f6tab;<\/li>\n<li>Automaatne failover t\u00f6\u00f6tab karbist v\u00e4lja;<\/li>\n<li>Kirjutatud Pythonis ja kuna me ise kirjutame palju Pythonis, siis on meil lihtsam lahendada probleeme ja v\u00f5ib-olla isegi aidata projekti arengus;<\/li>\n<li>Haldab t\u00e4ielikult PostgreSQL-i, v\u00f5imaldab muuta konfiguratsiooni kohe k\u00f5igil klastrinoodidel, ja kui uue konfiguratsiooni kasutamiseks on vajalik klastrit taask\u00e4ivitada, saab seda taas teha Patroni abil.<\/li>\n<\/ul>\n<p>Miinused:<\/p>\n<ul>\n<li>Dokumentatsioonist ei ole selge, kuidas \u00f5igesti PgBounceriga t\u00f6\u00f6tada. Kuigi seda on keeruline miinuseks pidada, sest Patroni \u00fclesanne on hallata PostgreSQL-i, ja kuidas \u00fchendused Patronisse j\u00f5uavad, on juba meie probleem;<\/li>\n<li>Patroni rakendamise n\u00e4idiseid on v\u00e4he suurte koguste puhul, samas on palju n\u00e4iteid rakendamise algusest.<\/li>\n<\/ul>\n<p>Kokkuv\u00f5ttes valisime k\u00f5rgema usaldusv\u00e4\u00e4rsuse klastri loomiseks just Patroni.<\/p>\n<h2>Patroni rakendamise protsess<\/h2>\n<p>Enne Patronit oli meil 12 PostgreSQL shard'i konfiguratsioonis, kus oli \u00fcks meister ja \u00fcks replikatsioon as\u00fcnkroonse replikatsiooniga. Rakenduste serverid kasutasid andmebaase Network Load Balancer'i kaudu, mille taga olid kaks PgBouncer'i instantsi, ja nende taga k\u00f5ik PostgreSQL serverid.<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/8e5350d2466311593e11add30d5b1bdc.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>Patroni rakendamiseks pidime valima klastrite konfiguratsiooni jaotatud salvestuse. Patroni t\u00f6\u00f6tab jaotatud konfiguratsioonide salvestuss\u00fcsteemidega nagu etcd, Zookeeper ja Consul. Meil on tootmises t\u00e4ielik Consul klaster, mis t\u00f6\u00f6tab koos Vault'iga ja me ei kasuta seda muul viisil. Suurep\u00e4rane v\u00f5imalus hakata Consulit sihip\u00e4raselt kasutama.<\/p>\n<h3>Kuidas Patroni t\u00f6\u00f6tab koos Consuliga<\/h3>\n<p>Meil on Consul klaster, mis koosneb kolmest s\u00f5lmest ja Patroni klaster, mis koosneb \u00fclemast ja replikast (Patronis nimetatakse meistrit klastrite \u00fclemaks ja koopiaid replikateks). Iga Patroni klastrite instants saadab pidevalt Consulile teavet klastrite oleku kohta. Seet\u00f5ttu on Consul'is alati v\u00f5imalik teada saada hetke Patroni klastrite konfiguratsiooni ja kes on antud hetkel \u00fclem.<\/p>\n<p><img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/3234594b363904424fdce64c9d77fca5.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>Patroni \u00fchendamiseks Consuliga piisab ametliku dokumentatsiooni uurimisest, kus on kirjas, et tuleb n\u00e4idata hosti http v\u00f5i https formaadis, olenevalt meie t\u00f6\u00f6viisist Consuliga, ja \u00fchenduse skeemi, valikuline:<\/p>\n<pre><code class=\"plaintext\">host: Consul'i l\u00f5pp-punkti host:port, formaadis: http(s):\/\/host:port\nscheme: (valikuline) http v\u00f5i https, vaikev\u00e4\u00e4rtuseks on http<\/code><\/pre>\n<p>See tundub lihtne, kuid siin algavad probleemid. Consul'iga t\u00f6\u00f6tame kaitstud \u00fchenduse kaudu https kaudu ja meie \u00fchenduse konfigureerimine n\u00e4eb v\u00e4lja j\u00e4rgmine:<\/p>\n<pre><code class=\"python\">consul:\n  host: https:\/\/server.production.consul:8080 \n  verify: true\n  cacert: {{ consul_cacert }}\n  cert: {{ consul_cert }}\n  key: {{ consul_key }}<\/code><\/pre>\n<p>Kuid see ei t\u00f6\u00f6ta. Patroni k\u00e4ivitamisel ei saa see Consul'iga \u00fchendust, sest ta proovib ikkagi minna http kaudu.<\/p>\n<p>Probleemi lahendamine osutus annetatud Patroni l\u00e4htekoodiks. Hea, et see on kirjutatud python'is. Selgub, et parameetrit host ei parsita, vaid protokoll tuleb n\u00e4idata skeemis. Nii n\u00e4eb v\u00e4lja t\u00f6\u00f6tav konfiguratsiooniblokk Consul'iga t\u00f6\u00f6tamiseks meie jaoks:<\/p>\n<pre><code class=\"python\">consul:\n  host: server.production.consul:8080\n  scheme: https\n  verify: true\n  cacert: {{ consul_cacert }}\n  cert: {{ consul_cert }}\n  key: {{ consul_key }}<\/code><\/pre>\n<h3>Consul-template<\/h3>\n<p>Nii, me oleme valinud konfiguratsioonide mahuti. N\u00fc\u00fcd tuleb m\u00f5ista, kuidas PgBouncer muudab oma konfiguratsiooni, kui Patroni klastris liider vahetub. Selle kohta dokumentatsioonis vastust ei leidu, kuna PgBouncer'i kasutamine ei ole seal p\u00f5hjalikult kirjeldatud.<\/p>\n<p>Lahendust otsides leidsime artikli (pealkirja, kahjuks, ei m\u00e4leta), kus kirjutati, et Consul-template aitas v\u00e4ga h\u00e4sti PgBouncer'i ja Patroni vahel. See suunaski meid uurima Consul-template'i t\u00f6\u00f6d.<\/p>\n<p>Selgus, et Consul-template j\u00e4lgib pidevalt PostgreSQL klastri konfiguratsiooni Consulis. Liidri vahetamisel uuendab ta PgBouncer'i konfiguratsiooni ja saadab k\u00e4su selle taask\u00e4ivitamiseks.<\/p>\n<p><img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/6cf92996a127bb6637ab81dc45fdd60a.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>Suur pluss template'i juures on see, et see on salvestatud koodina, seega on uue shardi lisamisel piisav teha uus commit ja automaatse protsessiga template uuendada, toetades Infrastructure as Code p\u00f5him\u00f5tet.<\/p>\n<h3>Uus arhitektuur Patroniga<\/h3>\n<p>Tulemuseks saime j\u00e4rgmise t\u00f6\u00f6skeemi:<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/bf9a9eff675a26039e3f76b16c6cd713.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>K\u00f5ik rakenduse serverid p\u00f6\u00f6rduvad tasakaalustaja poole \u2192 selle taga on kaks PgBouncer'i instantsi \u2192 igal instantsil t\u00f6\u00f6tab Consul-template, mis j\u00e4lgib iga Patroni klastri olekut ja hoolitseb PgBouncer'i konfi ajakohasuse eest, suunates p\u00e4ringud iga klastri aktiivsele liidrile.<\/p>\n<h3>K\u00e4sitsi testimine<\/h3>\n<p>Enne tootmist l\u00f5puleviimist k\u00e4ivitasime selle skeemi v\u00e4ikeses testkeskkonnas ja kontrollisime automaatse vahetamise toimimist. Avastasime tahvli, liikusime kleebise \u00fcmber ja samal ajal 'tapsime' klastri liidri. AWS-is piisab selleks instantsi konsoliga v\u00e4lja l\u00fclitamisest.<\/p>\n<p><img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/d670fe373b774f1b52bfd8a8c3b53a21.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>Kleebis naases 10-20 sekundi jooksul tagasi, ja seej\u00e4rel hakkas uuesti normaalselt liikuma. See t\u00e4hendab, et Patroni klaster tegutses \u00f5igesti: vahetas liidri, edastas teabe Consulisse ja Consul-template haaras kohe selle teabe, asendas PgBouncer'i konfiguratsiooni ja saatis reload k\u00e4su.<\/p>\n<h2>Kuidas ellu j\u00e4\u00e4da k\u00f5rge koormuse all ja hoida minimaalset seisuaja?<\/h2>\n<p>K\u00f5ik t\u00f6\u00f6tab suurep\u00e4raselt! Ent tekivad uued k\u00fcsimused: Kuidas see t\u00f6\u00f6tab k\u00f5rge koormuse all? Kuidas kiiresti ja ohutult k\u00f5ik tootmisse viia?<\/p>\n<p>Esimesele k\u00fcsimusele vastamiseks aitab meid testkeskkond, kus viime l\u00e4bi koormustestimise. See on t\u00e4ielikult identne tootmisuuendusele arhitektuurilt ja sisaldab genereeritud testandmeid, mille maht on ligikaudu sama kui tootmises. Me otsustame lihtsalt 'tappa' \u00fche PostgreSQL meistritest testimise ajal ja vaadata, mis juhtub. Kuid enne seda on oluline kontrollida automaatset \u00fcmberpaigutamist, kuna sellel keskkonnas on meil mitu PostgreSQL shard'i, seega saame suurep\u00e4rase konfigureerimisskriptide testimise enne tootmist.<\/p>\n<p>M\u00f5lemad \u00fclesanded n\u00e4evad ambitsioonikad v\u00e4lja, kuid meil on PostgreSQL 9.6. Kas me v\u00f5iks kohe 11.2 versioonile \u00fcle minna?<\/p>\n<p>Otsustame teha seda kahes etapis: esmalt uuendame versiooni 11.2 peale, seej\u00e4rel k\u00e4ivitame Patroni.<\/p>\n<h3>PostgreSQL uuendamine<\/h3>\n<p>PostgreSQL versiooni kiireks uuendamiseks tuleb kasutada valikut <b>-k<\/b>, mille puhul luuakse k\u00f5vakettale hard link ja teie andmete kopeerimine ei ole vajalik. 300\u2013400 GB suuruste andmebaaside puhul kestab uuendamine 1 sekund.<\/p>\n<p>Meil on palju shard'e, seega peab uuendamine toimuma automaatselt. Selleks oleme kirjutanud Ansible playbook'i, mis teostab kogu uuendamise protsessi meie eest:<\/p>\n<pre><code class=\"plaintext\">\/usr\/lib\/postgresql\/11\/bin\/pg_upgrade \n&lt;b&gt;--link &lt;\/b&gt;\n--old-datadir=&#039;&#039; --new-datadir=&#039;&#039; \n --old-bindir=&#039;&#039;  --new-bindir=&#039;&#039; \n --old-options=&#039; -c config_file=&#039; \n --new-options=&#039; -c config_file=&#039;<\/code><\/pre>\n<p>Siinkohal on oluline m\u00e4rkida, et enne uuenduse k\u00e4ivitamist tuleb see teha parameetriga <b>\u2013check<\/b>, et olla kindel uuenduse v\u00f5imalikuses. Samuti meie skript asendab konfiguratsioone uuenduse ajaks. Meie skript t\u00e4itis \u00fclesande 30 sekundiga, see on suurep\u00e4rane tulemus.<\/p>\n<h3>Patroni k\u00e4ivitamine<\/h3>\n<p>Teise probleemi lahendamiseks piisab Patroni konfiguratsiooni vaatamisest. Ametlikus hoidlas on olemas n\u00e4idiskonfiguratsioon koos initdb'ga, mis vastutab uue andmebaasi initsialiseerimise eest Patroni esmakordsel k\u00e4ivitamisel. Kuid kuna meil on juba valmis andmebaas, siis lihtsalt kustutasime selle osa konfiguratsioonist.<\/p>\n<p>Kui me hakkasime Patroni installima juba olemasolevale PostgreSQL klastrile ja seda k\u00e4ivitama, siis kokku puutusime uue probleemiga: m\u00f5lemad serverid k\u00e4ivitusid juhtidena. Patroni ei tea klastrite varasemast olekust ja proovib k\u00e4ivitada m\u00f5lemat serverit kui kahte eraldi klastri samu nimesid. Selle probleemi lahendamiseks on vajalik kustutada slave'i andmed direktorium:<\/p>\n<pre><code class=\"plaintext\">rm -rf \/var\/lib\/postgresql\/<\/code><\/pre>\n<p><b>Seda tuleb teha ainult slave'il!<\/b><\/p>\n<p>Puhta replika \u00fchendamisel teeb Patroni basebackup'i juhist ja taastab selle replikale, seej\u00e4rel hoiab see ajakohast seisundit wal-logide kaudu.<\/p>\n<p>Veel raskusi, millega silmitsi seisime, oli see, et k\u00f5ik PostgreSQL klastrid on vaikimisi nimega main. Kui iga klaster ei tea teistest, siis on k\u00f5ik korras. Kuid kui soovite kasutada Patronit, peavad k\u00f5ik klastrid omama ainulaadset nime. Lahendus on muuta PostgreSQL konfiguratsioonis klastri nime.<\/p>\n<h3>Koormustest<\/h3>\n<p>L\u00e4ksime testima, simuleerides kasutajate t\u00f6\u00f6d foorumites. Kui koormus j\u00f5udis meie keskmisele p\u00e4evasele tasemele, kordasime t\u00e4pselt sama testi, kus katkestasime \u00fche instance'i, millel oli PostgreSQL juht. Automaatne failover toimis ootusp\u00e4raselt: Patron vahetas juhti, Consul-template uuendas PgBounceri konfiguratsiooni ja saatis reload-k\u00e4su. Meie Grafanas olevad graafikud n\u00e4itasid, et esines 20-30 sekundi viivitusi ja m\u00f5ningaid vigu serveritest, mis olid seotud andmebaasi \u00fchendamisega. See on normaalne olukord, sellised n\u00e4itajad on meie failoveri jaoks vastuv\u00f5etavad ja kindlasti parem kui teenuse seiskumine.<\/p>\n<h2>Patroni k\u00e4itamine tootmises<\/h2>\n<p>Kokkuv\u00f5ttes saime j\u00e4rgmise plaani:<\/p>\n<ul>\n<li>Consul-template'i paigaldamine PgBounceri serveritesse ja k\u00e4ivitamine;<\/li>\n<li>PostgreSQL v\u00e4rskendamine versioonile 11.2;<\/li>\n<li>Klastri nime muutmine;<\/li>\n<li>Patroni klastri k\u00e4ivitamine.<\/li>\n<\/ul>\n<p>Samas v\u00f5imaldab meie skeem teha esimese punkti praktiliselt igal ajal, saame j\u00e4rjestikku iga PgBounceri t\u00f6\u00f6lt eemaldada ja teha selle jaoks Consul-template'i paigaldamise ja k\u00e4ivitamise. Just seda me tegime.<\/p>\n<p>Kiireks juurutamiseks kasutasime Ansible'i, kuna k\u00f5ik playbookid olime juba testkeskkonnas kontrollinud, ning kogu stsenaariumi t\u00e4itmise aeg oli iga shard'i jaoks 1,5 kuni 2 minutit. Saime k\u00f5ik j\u00e4rjestikku igale shard'ile juurutada ilma meie teenuse seiskamiseta, kuid pidime iga PostgreSQL m\u00f5neks minutiks v\u00e4lja l\u00fclitama. Sel juhul ei saaks kasutajad, kelle andmed on sellel shard'il, samaaegselt t\u00f6\u00f6tada, mis meie jaoks pole vastuv\u00f5etav.<\/p>\n<p>Situatsioonist p\u00e4\u00e4semiseks toimus planeeritud hooldus, mis meil toimub iga 3 kuu tagant. See on aeg, mil teeme t\u00e4iesti v\u00e4lja meie teenuse ning uuendame andmebaasi instantsid. J\u00e4\u00e4nud oli n\u00e4dal j\u00e4rgmise aknani ja otsustasime lihtsalt oodata ning valmistuda. Ootamise ajal tegime t\u00e4iendavaid ettevaatusabin\u00f5usid: iga PostgreSQL shard'i jaoks t\u00f5ime \u00fcles varureplika juhuks, kui midagi l\u00e4heks valesti, et s\u00e4ilitada viimaseid andmeid, ja lisasime iga shardi jaoks uue instantsi, millest peaks saama uus replik Patroni klastris, et mitte t\u00e4ita k\u00e4su andmete kustutamiseks. See k\u00f5ik aitas minimeerida vea riski.<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/29e5c5f50dbfebfe5665fa0aeb009728.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>Taask\u00e4ivitame oma teenuse, k\u00f5ik t\u00f6\u00f6tas nagu peab, kasutajad j\u00e4tkasid t\u00f6\u00f6d, kuid graafikutel m\u00e4rkasime ebanormaalset k\u00f5rget koormust Consul-serveritele.<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/af0eef9ac235706c0aac62d2e1ee179d.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>Miks me ei n\u00e4inud seda testkeskkonnas? See probleem illustreerib v\u00e4ga h\u00e4sti, et on vajalik j\u00e4rgida infrastruktuuri kui koodi p\u00f5him\u00f5tet ja t\u00e4iendada kogu infrastruktuuri alates testkeskkondadest kuni tootmiseni. Vastasel juhul on v\u00e4ga lihtne sattuda sellisesse probleemisse nagu meil. Mis juhtus? Consul ilmus esmalt tootmisesse ja alles sitten testkeskkondades, mille tulemusena testkeskkondade versioon Consulist oli k\u00f5rgem kui tootmises. \u00dches versioonide v\u00e4ljaandes lahendati CPU leke, kui t\u00f6\u00f6tati consul-template'iga. Seet\u00f5ttu uuendusime lihtsalt Consulit, lahendades nii probleemi.<\/p>\n<h3>Taask\u00e4ivita Patroni klaster<\/h3>\n<p>Kuid me sattusime uude probleemisse, millest me isegi ei kahtlustanud. Consuli uuendamise k\u00e4igus kustutame lihtsalt Consuli s\u00f5lme klastrist k\u00e4suga consul leave \u2192 Patroni \u00fchendub teise Consul-serveriga \u2192 k\u00f5ik t\u00f6\u00f6tab. Kuid kui j\u00f5udsime viimase instantsi Consuli klastrisse ja saatasime talle k\u00e4su consul leave, taask\u00e4ivitusid k\u00f5ik Patroni klastrid ja logides n\u00e4gime j\u00e4rgmist viga:<\/p>\n<pre><code class=\"plaintext\">VIGA: get_cluster\nJ&auml;lgimine (viimane kutse viimasena):\n...\nRetryFailedError: &#039;&Uuml;letatud korduse t&auml;htaeg&#039;\nVIGA: Viga suhtlemisel DCS-iga\n&lt;b&gt;LOG: andmebaasis&uuml;steem on v&auml;lja l&uuml;litatud&lt;\/b&gt;<\/code><\/pre>\n<p>Patroni klaster ei suutnud saada teavet oma klastri kohta ja taask\u00e4ivitati.<\/p>\n<p>Lahenduse leidmiseks p\u00f6\u00f6rdusime Patroni autorite poole GitHubi kaudu. Nad soovitasid meie konfiguratsioonifailide t\u00e4iustusi:<\/p>\n<pre><code class=\"python\">consul:\n consul.checks: []\nbootstrap:\n dcs:\n   retry_timeout: 8<\/code><\/pre>\n<p>Me suutsime probleemi testkeskkonnas uuesti esitada ja testisime seal neid parameetreid, kuid kahjuks need ei toiminud.<\/p>\n<p>Probleem j\u00e4\u00e4b endiselt lahendamata. Planeerime proovida j\u00e4rgmisi lahendusi:<\/p>\n<ul>\n<li>Kasutada Consul-agent'i igas Patroni klastris asuvas instantsis;<\/li>\n<li>Parandada probleem koodis.<\/li>\n<\/ul>\n<p>Meile on teada vea tekkimise koht: t\u00f5en\u00e4oliselt on probleem default timeout'i kasutamises, mida ei \u00fcmbers\u00f5ideta konfiguratsioonifailis. Kui viimane Consul server eemaldatakse klastri seest, j\u00e4\u00e4b kogu Consul-klaster hanguma, mis kestab kauem kui sekund, mist\u00f5ttu ei saa Patroni klastri seisundit m\u00e4\u00e4rata ja k\u00e4ivitab kogu klastri t\u00e4ielikult uuesti.<\/p>\n<p>\u00d5nneks ei ole me kokku puutunud millegi muuga, mis viga tekitaks.<\/p>\n<h2>Patroni kasutamise tulemused<\/h2>\n<p>P\u00e4rast Patroni edukat k\u00e4ivitamist lisasime igasse klastrisse \u00fche t\u00e4iendava replitseerimise. N\u00fc\u00fcd on igas klastris mingi kuorum: \u00fcks juht ja kaks replitseerimist, et tagada ohutus split-braini korral vahetamise ajal.<br \/>\n<img decoding=\"async\" style=\"display: block; margin: 0 auto;\" src=\"\/wp-content\/uploads\/2019\/06\/3bb4c0495fea274b04edd2e99b59eacb.png\" alt=\"T\u00f5rketaluv PostgreSQL klaster + Patroni. Rakendamise kogemus\" \/><\/p>\n<p>Tootmises on Patroni t\u00f6\u00f6tanud \u00fcle kolme kuu. Selle aja jooksul on see meid juba aidanud. Hiljuti suri AWS-is \u00fche klastri juht, automaatne failover toimis ja kasutajad j\u00e4tkasid t\u00f6\u00f6d. Patroni t\u00e4itis oma peamist \u00fclesannet.<\/p>\n<p><b>V\u00e4ike kokkuv\u00f5te Patroni kasutamisest:<\/b><\/p>\n<ul>\n<li>Konfiguratsiooni muutmise mugavus. Piisab konfiguratsiooni muutmisest \u00fchel instantsil ja see t\u00f5mmatakse kogu klastrisse. Kui uue konfiguratsiooni rakendamiseks on vajalik taask\u00e4ivitamine, siis Patroni annab sellest teada. Patroni saab kogu klastrit taask\u00e4ivitada \u00fche k\u00e4suga, mis on samuti v\u00e4ga mugav.<\/li>\n<li>Automaatne failover t\u00f6\u00f6tab ja on meid juba aidanud.<\/li>\n<li>PostgreSQL uuendamine ilma rakenduse seisaku. Esiteks tuleb uuendada replitseerimise uus versioon, seej\u00e4rel vahetada klastri Patronis juht ja uuendada vana juhti. Sellega kaasneb vajalik automaatse failoveri testimine.<\/li>\n<\/ul>\n<p>Allikas: <a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/miro\/blog\/457326\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u043a \u0432\u043e\u043f\u0440\u043e\u0441\u0443 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 PostgreSQL, \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0441\u0442\u0430\u043b\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u0432\u0430\u0436\u043d\u043e \u0438 \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c. \u0423 \u043d\u0430\u0441 \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441: 2,5 \u043c\u043b\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043c\u0438\u0440\u0443, 50\u041a+ \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043a\u0430\u0436\u0434\u044b\u0439 \u0434\u0435\u043d\u044c. \u0421\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 Amazone \u0432 \u043e\u0434\u043d\u043e\u043c \u0440\u0435\u0433\u0438\u043e\u043d\u0435 \u0418\u0440\u043b\u0430\u043d\u0434\u0438\u0438: \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e 100+ \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432, \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e\u0447\u0442\u0438 50 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":26749,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35706","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u043a \u0432\u043e\u043f\u0440\u043e\u0441\u0443 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 PostgreSQL, \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0441\u0442\u0430\u043b\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u0432\u0430\u0436\u043d\u043e \u0438 \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/otkazoustojchivyj-klaster-postgresql-patroni-opyt-vnedreniya\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 PostgreSQL + Patroni. \u041e\u043f\u044b\u0442 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u043a \u0432\u043e\u043f\u0440\u043e\u0441\u0443 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 PostgreSQL, \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0441\u0442\u0430\u043b\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u0432\u0430\u0436\u043d\u043e \u0438 \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/otkazoustojchivyj-klaster-postgresql-patroni-opyt-vnedreniya\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:05:50+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-05-18T18:58:46+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47 T\u00f5rke- ja usaldusv\u00e4\u00e4rne PostgreSQL klaster + Patroni. Rakendamise kogemus | ProHoster","description":"Selles artiklis r\u00e4\u00e4gin, kuidas me l\u00e4henesime PostgreSQL-i t\u00f5rke taastamise k\u00fcsimusele, miks see meile oluline oli ja mis l\u00f5puks v\u00e4lja tuli.","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/otkazoustojchivyj-klaster-postgresql-patroni-opyt-vnedreniya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 PostgreSQL + Patroni. \u041e\u043f\u044b\u0442 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f | ProHoster","og:description":"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u043a \u0432\u043e\u043f\u0440\u043e\u0441\u0443 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 PostgreSQL, \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0441\u0442\u0430\u043b\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u0432\u0430\u0436\u043d\u043e \u0438 \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.","og:url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/otkazoustojchivyj-klaster-postgresql-patroni-opyt-vnedreniya","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:05:50+00:00","article:modified_time":"2026-05-18T18:58:46+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35706","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 00:26:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:51:06","updated":"2026-01-22 00:26:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/35706","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=35706"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/35706\/revisions"}],"predecessor-version":[{"id":172654,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/35706\/revisions\/172654"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/26749"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=35706"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=35706"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=35706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}