{"id":92570,"date":"2020-08-28T19:42:21","date_gmt":"2020-08-28T17:42:21","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker"},"modified":"2020-08-28T19:42:21","modified_gmt":"2020-08-28T17:42:21","slug":"modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","title":{"rendered":"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h1 id=\"vvedenie\">Wprowadzenie<\/h1>\n<p><\/p>\n<p>Jaki\u015b czas temu postawiono przede mn\u0105 zadanie opracowania klastra o wysokiej dost\u0119pno\u015bci dla <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\">PostgreSQL<\/a><\/noindex>, dzia\u0142aj\u0105cego w kilku centrach danych po\u0142\u0105czonych \u015bwiat\u0142owodem w obr\u0119bie jednego miasta, zdolnego przetrwa\u0107 awari\u0119 (np. wy\u0142\u0105czenie zasilania) jednego z centr\u00f3w danych. Jako oprogramowanie odpowiedzialne za wysok\u0105 dost\u0119pno\u015b\u0107 wybra\u0142em <noindex><a rel=\"nofollow\" href=\"https:\/\/clusterlabs.org\">Pacemaker<\/a><\/noindex>, poniewa\u017c to oficjalne rozwi\u0105zanie od RedHat do tworzenia klastr\u00f3w o wysokiej dost\u0119pno\u015bci. Jego zalet\u0105 jest wsparcie, jakie zapewnia RedHat, oraz to, \u017ce jest to rozwi\u0105zanie uniwersalne (modu\u0142owe). Dzi\u0119ki temu mo\u017cna zapewni\u0107 wysok\u0105 dost\u0119pno\u015b\u0107 nie tylko dla PostgreSQL, ale tak\u017ce dla innych us\u0142ug, wykorzystuj\u0105c standardowe modu\u0142y lub tworz\u0105c je wed\u0142ug specyficznych potrzeb.<\/p>\n<p><\/p>\n<p>Do tego rozwi\u0105zania pojawi\u0142o si\u0119 zasadnicze pytanie: jak bardzo odporny b\u0119dzie klaster o wysokiej dost\u0119pno\u015bci? Aby to zbada\u0107, opracowa\u0142em testowe \u015brodowisko, kt\u00f3re imituje r\u00f3\u017cne awarie w w\u0119z\u0142ach klastra, czeka na przywr\u00f3cenie sprawno\u015bci, naprawia uszkodzony w\u0119ze\u0142 i kontynuuje testowanie w cyklu. Pocz\u0105tkowo projekt nosi\u0142 nazw\u0119 hapgsql, ale z czasem znudzi\u0142o mi si\u0119 to imi\u0119 z jedn\u0105 samog\u0142osk\u0105. Dlatego odpornym bazom danych (i przypisanym do nich float IP) zacz\u0105\u0142em nadawa\u0107 nazw\u0119 <strong>krogan<\/strong> (posta\u0107 z gry komputerowej, w kt\u00f3rej wszystkie wa\u017cne organy s\u0105 zduplikowane), natomiast w\u0119z\u0142y, klastry i sam projekt nazwano <strong>tuchanka<\/strong> (planeta, na kt\u00f3rej \u017cyj\u0105 kroganie).<\/p>\n<p><\/p>\n<p>Obecnie kierownictwo zatwierdzi\u0142o <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/domclick\/tuchanka\">otwarcie projektu dla spo\u0142eczno\u015bci open source na licencji MIT<\/a><\/noindex>. README wkr\u00f3tce zostanie przet\u0142umaczone na j\u0119zyk angielski (poniewa\u017c oczekuje si\u0119, \u017ce g\u0142\u00f3wnymi u\u017cytkownikami b\u0119d\u0105 programi\u015bci Pacemaker i PostgreSQL), a stary rosyjski wariant README postanowi\u0142em opracowa\u0107 (cz\u0119\u015bciowo) w formie tego artyku\u0142u.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/7ebb04b3e56337060e981da319192a28.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Klastry s\u0105 uruchamiane na wirtualnych maszynach <noindex><a rel=\"nofollow\" href=\"https:\/\/www.virtualbox.org\">VirtualBox<\/a><\/noindex>. \u0141\u0105cznie zostanie uruchomionych 12 wirtualnych maszyn (w sumie 36GiB), kt\u00f3re utworz\u0105 4 klastry o wysokiej dost\u0119pno\u015bci (r\u00f3\u017cne opcje). Dwa pierwsze klastry sk\u0142adaj\u0105 si\u0119 z dw\u00f3ch serwer\u00f3w PostgreSQL, kt\u00f3re s\u0105 rozmieszczone w r\u00f3\u017cnych centrach danych oraz wsp\u00f3lnego serwera <em>witness<\/em> c <strong>urz\u0105dzenia quorum<\/strong> (umieszczonego na taniej wirtualnej maszynie w trzecim centrum danych), kt\u00f3ry rozstrzyga niepewno\u015b\u0107 <strong>50%\/50%<\/strong>, oddaj\u0105c sw\u00f3j g\u0142os jednej ze stron. Trzeci klaster znajduje si\u0119 w trzech centrach danych: jeden g\u0142\u00f3wny, dwa podrz\u0119dne, bez <strong>urz\u0105dzenia quorum<\/strong>. Czwarty klaster sk\u0142ada si\u0119 z czterech serwer\u00f3w PostgreSQL, po dwa na centrum danych: jeden g\u0142\u00f3wny, pozosta\u0142e replikami, i r\u00f3wnie\u017c wykorzystuje <em>witness<\/em> c <strong>urz\u0105dzenia quorum<\/strong>. Czwarty wytrzymuje awari\u0119 dw\u00f3ch serwer\u00f3w lub jednego centrum danych. To rozwi\u0105zanie mo\u017ce by\u0107 w razie potrzeby skalowane na wi\u0119ksz\u0105 liczb\u0119 replik.<\/p>\n<p><\/p>\n<p>Us\u0142uga dok\u0142adnego czasu <noindex><a rel=\"nofollow\" href=\"https:\/\/www.ntp.org\">ntpd<\/a><\/noindex> r\u00f3wnie\u017c zosta\u0142 przystosowany do awaryjno\u015bci, ale tam stosuje si\u0119 metod\u0119 samego <code>ntpd<\/code> (<em>orphan mode<\/em>). Og\u00f3lny serwer <em>witness<\/em> pe\u0142ni rol\u0119 centralnego serwera NTP, rozprowadzaj\u0105c sw\u00f3j czas wszystkim klastrom, tym samym synchronizuj\u0105c wszystkie serwery ze sob\u0105. Je\u015bli <em>witness<\/em> wyjdzie z u\u017cytku lub zostanie odizolowany, wtedy sw\u00f3j czas zacznie rozprowadza\u0107 jeden z serwer\u00f3w klastra (wewn\u0105trz klastra). Pomocniczy pami\u0119ciowy <strong>HTTP proxy<\/strong> r\u00f3wnie\u017c zosta\u0142 uruchomiony na <em>witness<\/em>, dzi\u0119ki niemu pozosta\u0142e maszyny wirtualne maj\u0105 dost\u0119p do repozytori\u00f3w Yum. W rzeczywisto\u015bci takie us\u0142ugi, jak dok\u0142adny czas i proxy, z pewno\u015bci\u0105 b\u0119d\u0105 umieszczone na dedykowanych serwerach, a w te\u015bcie s\u0105 usytuowane na <em>witness<\/em> tylko dla oszcz\u0119dno\u015bci liczby maszyn wirtualnych i miejsca.<\/p>\n<p><\/p>\n<h1 id=\"versii\">Wersje<\/h1>\n<p><\/p>\n<p>v0. Dzia\u0142a z CentOS 7 i PostgreSQL 11 na VirtualBox 6.1.<\/p>\n<p><\/p>\n<h1 id=\"struktura-klasterov\">Struktura klastr\u00f3w<\/h1>\n<p><\/p>\n<p>Wszystkie klastry s\u0105 przeznaczone do umieszczania w kilku centrach danych, po\u0142\u0105czone w jedn\u0105 p\u0142ask\u0105 sie\u0107 i musz\u0105 wytrzyma\u0107 awari\u0119 lub izolacj\u0119 sieci jednego centrum danych. Dlatego <strong>niemo\u017cliwe<\/strong> u\u017cycie w celu ochrony przed <strong>split-brain<\/strong> standardowej technologii Pacemaker, kt\u00f3ra nazywa si\u0119 <em>STONITH<\/em> (Shoot The Other Node In The Head) albo <em>fencing<\/em>. Jej istota polega na tym, \u017ce je\u015bli w\u0119z\u0142y w klastrze zaczynaj\u0105 podejrzewa\u0107, \u017ce z kt\u00f3rym\u015b w\u0119z\u0142em dzieje si\u0119 co\u015b z\u0142ego, on nie odpowiada lub dzia\u0142a nieprawid\u0142owo, to skutecznie go od\u0142\u0105czaj\u0105 przez \u201ezewn\u0119trzne\u201d urz\u0105dzenia, takie jak kontroler IPMI lub UPS. Ale to zadzia\u0142a tylko w przypadkach, gdy przy jednorazowej awarii serwera IPMI lub UPS nadal b\u0119d\u0105 dzia\u0142a\u0107. Tutaj planowana jest ochrona przed znacznie bardziej katastrofaln\u0105 awari\u0105, gdy odmawia (na przyk\u0142ad zostaje odci\u0119te zasilanie) ca\u0142e centrum danych. A przy takiej awarii wszystkie <em>stonith<\/em>-urz\u0105dzenia (IPMI, UPS itp.) r\u00f3wnie\u017c nie b\u0119d\u0105 dzia\u0142a\u0107.<\/p>\n<p><\/p>\n<p>Zamiast tego podstaw\u0105 systemu jest idea kworum. Wszystkie w\u0119z\u0142y maj\u0105 g\u0142os i mog\u0105 pracowa\u0107 tylko te, kt\u00f3re widz\u0105 wi\u0119cej ni\u017c po\u0142ow\u0119 wszystkich w\u0119z\u0142\u00f3w. Ta liczba \u201epo\u0142owa+1\u201d nazywa si\u0119 <strong>kworum<\/strong>. Je\u015bli quorum nie zostanie osi\u0105gni\u0119ty, w\u0119ze\u0142 uznaje, \u017ce znajduje si\u0119 w izolacji sieciowej i powinien wy\u0142\u0105czy\u0107 swoje zasoby, tzn. jest to taka <strong>ochrona przed split-brain<\/strong>. Je\u015bli oprogramowanie odpowiedzialne za takie zachowanie nie dzia\u0142a, powinien zadzia\u0142a\u0107 watchdog, na przyk\u0142ad oparty na IPMI.<\/p>\n<p><\/p>\n<p>Je\u015bli liczba w\u0119z\u0142\u00f3w jest parzysta (klaster w dw\u00f3ch centrach danych), mo\u017ce wyst\u0105pi\u0107 tak zwana niejednoznaczno\u015b\u0107 <strong>50%\/50%<\/strong> (<em>50-50<\/em>), kiedy izolacja sieciowa dzieli klaster dok\u0142adnie na p\u00f3\u0142. Dlatego dla parzystej liczby w\u0119z\u0142\u00f3w dodaje si\u0119 <strong>urz\u0105dzenia quorum<\/strong> \u2014 ma\u0142o wymagaj\u0105cy demon, kt\u00f3ry mo\u017ce by\u0107 uruchomiony na najta\u0144szej wirtualce w trzecim centrum danych. Daje sw\u00f3j g\u0142os jednemu z segment\u00f3w (kt\u00f3ry widzi) i tym samym rozwi\u0105zuje niejednoznaczno\u015b\u0107 50%\/50%. Serwer, na kt\u00f3rym zostanie uruchomione urz\u0105dzenie quorum, nazwa\u0142em <em>witness<\/em> (terminologia z repmgr, podoba mi si\u0119).<\/p>\n<p><\/p>\n<p>Zasoby mog\u0105 przemieszcza\u0107 si\u0119 z miejsca na miejsce, na przyk\u0142ad z uszkodzonych serwer\u00f3w na sprawne, lub na polecenie administrator\u00f3w. Aby klienci wiedzieli, gdzie znajduj\u0105 si\u0119 potrzebne im zasoby (gdzie si\u0119 pod\u0142\u0105czy\u0107?), u\u017cywane s\u0105 <em>p\u0142ywaj\u0105ce IP<\/em> (<strong>float IP<\/strong>). To s\u0105 IP, kt\u00f3re Pacemaker mo\u017ce przenosi\u0107 pomi\u0119dzy w\u0119z\u0142ami (wszystko znajduje si\u0119 w p\u0142askiej sieci). Ka\u017cdy z nich symbolizuje zas\u00f3b (us\u0142ug\u0119) i b\u0119dzie znajdowa\u0107 si\u0119 tam, gdzie nale\u017cy si\u0119 pod\u0142\u0105czy\u0107, aby uzyska\u0107 dost\u0119p do tej us\u0142ugi (w naszym przypadku do bazy danych).<\/p>\n<p><\/p>\n<h2 id=\"tuchanka1-shema-s-uplotneniem\">Tuchanka1 (schemat ze spr\u0119\u017ceniem)<\/h2>\n<p><\/p>\n<h3 id=\"struktura\">Struktura<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/5651238e36f4af1c32f117191cf30261.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pomys\u0142 polega\u0142 na tym, \u017ce mamy wiele ma\u0142ych baz danych o niskim obci\u0105\u017ceniu, dla kt\u00f3rych nieop\u0142acalne jest utrzymywanie wydzielonego serwera slave w trybie hot standby dla transakcji tylko do odczytu (brak potrzeby takiego marnotrawstwa zasob\u00f3w).<\/p>\n<p><\/p>\n<p>W ka\u017cdym centrum danych znajduje si\u0119 jeden serwer. Na ka\u017cdym serwerze s\u0105 dwa instancje PostgreSQL (w terminologii PostgreSQL nazywane s\u0105 one klastrami, ale dla unikni\u0119cia zamieszania b\u0119d\u0119 je nazywa\u0142 instancjami, a klastry Pacemaker klastry). Jedna instancja dzia\u0142a w trybie master, i tylko ona \u015bwiadczy us\u0142ugi (tylko na ni\u0105 prowadzi float IP). Druga instancja dzia\u0142a jako slave dla drugiego centrum danych i b\u0119dzie \u015bwiadczy\u0107 us\u0142ugi tylko w przypadku awarii swojego mastera. Poniewa\u017c wi\u0119ksz\u0105 cz\u0119\u015b\u0107 czasu us\u0142ugi (wykonywanie zapyta\u0144) b\u0119dzie \u015bwiadczy\u0107 tylko jedna instancja z dw\u00f3ch (master), wszystkie zasoby serwera s\u0105 optymalizowane dla mastera (przydzielana jest pami\u0119\u0107 na bufor cache shared_buffers itd.), ale tak, aby na drug\u0105 instancj\u0119 tak\u017ce wystarczy\u0142o zasob\u00f3w (nawet do pracy w trybie nieoptymalnym przez cache systemu plik\u00f3w) na wypadek awarii jednego z centr\u00f3w danych. Slave nie \u015bwiadczy us\u0142ug (nie wykonuje zapyta\u0144 typu read only) przy normalnej pracy klastra, aby nie dosz\u0142o do walki o zasoby z masterem na tej samej maszynie.<\/p>\n<p><\/p>\n<p>W przypadku dw\u00f3ch w\u0119z\u0142\u00f3w odporno\u015b\u0107 na awarie jest mo\u017cliwa tylko przy asynchronicznej replikacji, poniewa\u017c przy synchronizowanej awaria slave'a spowoduje zatrzymanie mastera.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-witness\">Awaria witness<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/3c046d13c0c6839de297827ca3a8928b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Awaria witness (<em>urz\u0105dzenia quorum<\/em>) rozwa\u017c\u0119 tylko dla klastra Tuchanka1, w przypadku wszystkich pozosta\u0142ych b\u0119dzie ta sama historia. Przy awarii witness w strukturze klastra nic si\u0119 nie zmieni, wszystko b\u0119dzie dzia\u0142a\u0142o tak, jak dot\u0105d. Ale kworum stanie si\u0119 r\u00f3wne 2 z 3, i dlatego ka\u017cda kolejna awaria b\u0119dzie fatalna dla klastra. I tak czy inaczej trzeba b\u0119dzie szybko naprawi\u0107.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka1\">Awaria Tuchanka1<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/112957293bd682428115e4e93c9f1a96.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Awaria jednego z centr\u00f3w danych dla Tuchanka1. W takim przypadku <em>witness<\/em> przekazuje sw\u00f3j g\u0142os drugiemu w\u0119z\u0142owi w drugim centrum danych. Tam by\u0142y slave przekszta\u0142ca si\u0119 w mastera, w wyniku czego na jednym serwerze dzia\u0142aj\u0105 oba mastera i na nich wskazuj\u0105 obie ich float IP.<\/p>\n<p><\/p>\n<h2 id=\"tuchanka2-klassicheskaya\">Tuchanka2 (klasyczny)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-1\">Struktura<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/c3af368f823fbd580b4ebb14cc87c750.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Klasyczny schemat z dw\u00f3ch w\u0119z\u0142\u00f3w. Na jednym dzia\u0142a master, na drugim slave. Oba mog\u0105 wykonywa\u0107 zapytania (slave tylko read only), wi\u0119c na obu wskazuj\u0105 float IP: krogan2 \u2014 na master, krogan2s1 \u2014 na slave. Odporno\u015b\u0107 na awarie b\u0119dzie zar\u00f3wno dla mastera, jak i dla slave'a.<\/p>\n<p><\/p>\n<p>W przypadku dw\u00f3ch w\u0119z\u0142\u00f3w odporno\u015b\u0107 na awarie jest mo\u017cliwa tylko przy asynchronicznej replikacji, poniewa\u017c przy synchronizowanej awaria slave'a spowoduje zatrzymanie mastera.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka2\">Awaria Tuchanka2<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/79bfcaf88c96d8ee16767dcef53741c1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Przy awarii jednego z centr\u00f3w danych <em>witness<\/em> g\u0142osuje na drugi. Na jedynym dzia\u0142aj\u0105cym centrum danych zostanie uruchomiony master, a oba float IP: masterowy i roboczy b\u0119d\u0105 do niego wskazywa\u0107. Oczywi\u015bcie instancja musi by\u0107 skonfigurowana w taki spos\u00f3b, aby mia\u0142a wystarczaj\u0105ce zasoby (limity pod po\u0142\u0105czenia itp.), aby jednocze\u015bnie przyjmowa\u0107 wszystkie po\u0142\u0105czenia i \u017c\u0105dania od masterowego i roboczego float IP. Oznacza to, \u017ce przy normalnej pracy powinna mie\u0107 wystarczaj\u0105cy zapas limit\u00f3w.<\/p>\n<p><\/p>\n<h2 id=\"tuchanka4-mnogo-rabov\">Tuchanka4 (wiele robot\u00f3w)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-2\">Struktura<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/17819fd97847f0573d429e422d799bc1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To ju\u017c inny ekstremum. S\u0105 bazy danych, kt\u00f3re otrzymuj\u0105 bardzo du\u017co \u017c\u0105da\u0144 tylko do odczytu (typowy przypadek wysoko obci\u0105\u017conej strony internetowej). Tuchanka4 to sytuacja, w kt\u00f3rej mo\u017ce by\u0107 trzech lub wi\u0119cej robot\u00f3w do obs\u0142ugi takich \u017c\u0105da\u0144, ale nie za du\u017co. Przy bardzo du\u017cej liczbie robot\u00f3w b\u0119dzie trzeba wymy\u015bli\u0107 hierarchiczny system replikacji. W minimalnym przypadku (na obrazku) w ka\u017cdym z dw\u00f3ch centr\u00f3w danych znajduj\u0105 si\u0119 po dwa serwery, z kt\u00f3rych ka\u017cdy ma jedn\u0105 instancj\u0119 PostgreSQL.<\/p>\n<p><\/p>\n<p>Kolejn\u0105 cech\u0105 tego schematu jest to, \u017ce mo\u017cna ju\u017c zorganizowa\u0107 jedn\u0105 synchronizowan\u0105 replikacj\u0119. Jest ona skonfigurowana tak, aby replikowa\u0107, w miar\u0119 mo\u017cliwo\u015bci, do innego centrum danych, a nie do repliki w tym samym centrum danych, gdzie znajduje si\u0119 master. Na mastera i na ka\u017cdego robota wskazuje float IP. W zasadzie mi\u0119dzy robotami nale\u017ca\u0142oby zrealizowa\u0107 r\u00f3wnowa\u017cenie \u017c\u0105da\u0144. <em>sql proxy<\/em>, na przyk\u0142ad, po stronie klienta. R\u00f3\u017cnym typom klient\u00f3w mo\u017ce by\u0107 potrzebny r\u00f3\u017cny typ <em>sql proxy<\/em>, i tylko programi\u015bci klient\u00f3w wiedz\u0105, kto czego potrzebuje. Ta funkcjonalno\u015b\u0107 mo\u017ce by\u0107 zrealizowana zar\u00f3wno jako zewn\u0119trzny demon, jak i biblioteka klienta (connection pool) itd. Wszystko to wykracza poza temat systemu baz danych odpornego na awarie (odporno\u015b\u0107 <em>SQL proxy<\/em> mo\u017ce by\u0107 realizowana niezale\u017cnie, razem z odporno\u015bci\u0105 klienta).<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka4\">Awaria Tuchanka4<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/e005ae90ffd63abdb272012b94735618.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W przypadku awarii jednego centrum danych (tzn. dw\u00f3ch serwer\u00f3w) witness g\u0142osuje na drugi. W rezultacie w drugim centrum danych dzia\u0142aj\u0105 dwa serwery: na jednym dzia\u0142a master, a na niego wskazuje masterowy float IP (do przyjmowania \u017c\u0105da\u0144 read-write); a na drugim serwerze dzia\u0142a robot z synchronizowan\u0105 replikacj\u0105, a na niego wskazuje jeden z roboczych float IP (do \u017c\u0105da\u0144 tylko do odczytu).<\/p>\n<p><\/p>\n<p>Pierwsz\u0105 rzecz\u0105, kt\u00f3r\u0105 nale\u017cy odnotowa\u0107: roboczym float IP b\u0119dzie tylko jeden, a aby poprawnie z nim dzia\u0142a\u0107, b\u0119dzie trzeba, aby <em>sql proxy<\/em> przekierowywa\u0142 wszystkie zapytania na jedyny pozosta\u0142y adres float IP; a je\u015bli <em>sql proxy<\/em> nie, to mo\u017cna wymieni\u0107 wszystkie adresy float IP niewolnik\u00f3w oddzielaj\u0105c je przecinkiem w URL do po\u0142\u0105czenia. W takim przypadku z <em>libpq<\/em> po\u0142\u0105czenie b\u0119dzie na pierwszym dzia\u0142aj\u0105cym IP, tak jest zrobione w systemie automatycznego testowania. Mo\u017ce si\u0119 okaza\u0107, \u017ce w innych bibliotekach, na przyk\u0142ad JDBC, mo\u017ce to nie zadzia\u0142a\u0107 i b\u0119dzie potrzebne <em>sql proxy<\/em>. Zosta\u0142o to zrobione, poniewa\u017c dla float IP niewolnik\u00f3w obowi\u0105zuje zakaz jednoczesnego uruchamiania na jednym serwerze, aby by\u0142y r\u00f3wnomiernie rozdzielane mi\u0119dzy serwery niewolnik\u00f3w, je\u015bli dzia\u0142a ich kilka.<\/p>\n<p><\/p>\n<p>Drugie: nawet w przypadku awarii centrum danych synchronizowana replikacja b\u0119dzie zachowana. A nawet je\u015bli nast\u0105pi wt\u00f3rna awaria, czyli w pozosta\u0142ym centrum danych jeden z dw\u00f3ch serwer\u00f3w ulegnie awarii, klaster, mimo \u017ce przestanie \u015bwiadczy\u0107 us\u0142ugi, nadal zachowa informacje o wszystkich zakommitowanych transakcjach, dla kt\u00f3rych wyda\u0142 potwierdzenie o commicie (nie b\u0119dzie utraty informacji w przypadku wt\u00f3rnej awarii).<\/p>\n<p><\/p>\n<h2 id=\"tuchanka3-3-data-centra\">Tuchanka3 (3 centra danych)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-3\">Struktura<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/e11f9884b92fe20a63b5080ae8c7f82b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To klaster na sytuacj\u0119, gdy s\u0105 trzy w pe\u0142ni dzia\u0142aj\u0105ce centra danych, w ka\u017cdym z nich dzia\u0142a w pe\u0142ni dzia\u0142aj\u0105cy serwer bazy danych. W takim przypadku <em>urz\u0105dzenia quorum<\/em> nie jest potrzebny. W jednym centrum danych dzia\u0142a master, w dw\u00f3ch innych \u2014 niewolnicy. Replikacja jest synchronizowana, typu ANY (slave1, slave2), co oznacza, \u017ce klient otrzyma potwierdzenie commitu, gdy kt\u00f3rykolwiek z niewolnik\u00f3w jako pierwszy odpowie, \u017ce przyj\u0105\u0142 commit. Na zasoby wskazuje jeden float IP dla mastera i dwa dla niewolnik\u00f3w. W przeciwie\u0144stwie do Tuchanka4 wszystkie trzy float IP s\u0105 odporne na awarie. Do balansowania zapyta\u0144 SQL w trybie tylko do odczytu mo\u017cna u\u017cy\u0107 <em>sql proxy<\/em> (z osobn\u0105 odporno\u015bci\u0105 na awarie), lub przydzieli\u0107 jednej po\u0142owie klient\u00f3w jeden niewolniczy float IP, a drugiej po\u0142owie \u2014 drugi.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka3\">Awaria Tuchanka3<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/1e61158be3c23742384d3621e8f7896b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W przypadku awarii jednego z centr\u00f3w danych pozostaj\u0105 dwa. W jednym dzia\u0142a master i float IP od mastera, w drugim \u2014 niewolnik i oba niewolnicze float IP (na instancji powinien by\u0107 podw\u00f3jny zapas zasob\u00f3w, aby przyj\u0105\u0107 wszystkie po\u0142\u0105czenia z obu niewolniczych float IP). Mi\u0119dzy masterem a niewolnikiem jest synchronizowana replikacja. Ponadto klaster zachowa informacje o zakommitowanych i potwierdzonych transakcjach (nie b\u0119dzie utraty informacji) w przypadku zniszczenia dw\u00f3ch centr\u00f3w danych (je\u015bli nie zostan\u0105 zniszczone jednocze\u015bnie).<\/p>\n<p><\/p>\n<p><em>Nie zamieszcza\u0142em szczeg\u00f3\u0142owego opisu struktury plik\u00f3w i wdra\u017cania. Kto chce si\u0119 pobawi\u0107, mo\u017ce to wszystko przeczyta\u0107 w README. Przedstawiam tylko opis automatycznego testowania.<\/em><\/p>\n<p><\/p>\n<h1 id=\"sistema-avtomaticheskogo-testirovaniya\">System automatycznego testowania<\/h1>\n<p><\/p>\n<p>Aby sprawdzi\u0107 odporno\u015b\u0107 klastr\u00f3w przy symulacji r\u00f3\u017cnych usterek, stworzono system automatycznego testowania. Uruchamiany jest za pomoc\u0105 skryptu <code>test\/failure<\/code>. Skrypt mo\u017ce przyjmowa\u0107 jako parametry numery klastr\u00f3w, kt\u00f3re chce si\u0119 przetestowa\u0107. Na przyk\u0142ad, to polecenie:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">test\/failure 2 3<\/code><\/pre>\n<p><\/p>\n<p>b\u0119dzie testowa\u0107 tylko drugi i trzeci klaster. Je\u015bli parametry nie s\u0105 podane, b\u0119d\u0105 testowane wszystkie klastry. Wszystkie klastry s\u0105 testowane r\u00f3wnolegle, a wyniki wy\u015bwietlane s\u0105 w panelu tmux. Tmux u\u017cywa dedykowanego serwera tmux, wi\u0119c skrypt mo\u017cna uruchamia\u0107 z domy\u015blnego tmux, co daje zagnie\u017cd\u017cony tmux. Rekomenduj\u0119 u\u017cycie terminala w du\u017cym oknie i z ma\u0142\u0105 czcionk\u0105. Przed rozpocz\u0119ciem testowania wszystkie wirtualne maszyny s\u0105 przywracane do migawki w momencie zako\u0144czenia skryptu. <code>setup<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/b546bab1ebbbe365991e1ff3d1667237.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Terminal jest podzielony na kolumny wed\u0142ug liczby testowanych klastr\u00f3w, domy\u015blnie (na zrzucie ekranu) jest ich cztery. Zawarto\u015b\u0107 kolumn opisz\u0119 na przyk\u0142adzie Tuchanka2. Panel na zrzucie ekranu jest ponumerowany:<\/p>\n<p><\/p>\n<ol>\n<li>Tutaj wy\u015bwietlane s\u0105 statystyki test\u00f3w. Kolumny:\n<ul>\n<li><strong>failure<\/strong> \u2014 nazwa testu (funkcji w skrypcie), kt\u00f3ry emuluje awari\u0119.<\/li>\n<li><strong>reaction<\/strong> \u2014 \u015bredni czas w sekundach, w jakim klaster przywr\u00f3ci\u0142 swoj\u0105 funkcjonalno\u015b\u0107. Mierzony jest od pocz\u0105tku dzia\u0142ania skryptu, emuluj\u0105cego awari\u0119, do momentu, gdy klaster przywraca swoj\u0105 funkcjonalno\u015b\u0107 i jest w stanie nadal \u015bwiadczy\u0107 us\u0142ugi. Je\u015bli czas jest bardzo kr\u00f3tki, na przyk\u0142ad sze\u015b\u0107 sekund (co zdarza si\u0119 w klastrach z wieloma pracownikami (Tuchanka3 i Tuchanka4)), oznacza to, \u017ce awaria wyst\u0105pi\u0142a na asynchronicznym pracowniku i w \u017caden spos\u00f3b nie wp\u0142yn\u0119\u0142a na dzia\u0142anie, a zmiany stanu klastra nie mia\u0142y miejsca.<\/li>\n<li><strong>deviation<\/strong> \u2014 pokazuje rozrzut (dok\u0142adno\u015b\u0107) warto\u015bci <strong>reaction<\/strong> metod\u0105 \u201eodchylenie standardowe\u201d.<\/li>\n<li><strong>count<\/strong> \u2014 ile razy test zosta\u0142 wykonany.<\/li>\n<\/ul>\n<\/li>\n<li>Kr\u00f3tki dziennik pozwala oceni\u0107, czym zajmuje si\u0119 klaster w danym momencie. Wy\u015bwietlany jest numer iteracji (testu), znacznik czasu oraz nazwa operacji. Zbyt d\u0142ugie wykonanie (&gt; 5 minut) sygnalizuje jaki\u015b problem.<\/li>\n<li><strong>heart<\/strong> (serce) \u2014 bie\u017c\u0105cy czas. Dla wizualnej oceny wydajno\u015bci <em>mistrzowie<\/em> do jego tabeli stale wpisywane jest bie\u017c\u0105ce czas za pomoc\u0105 float IP mistrza. W przypadku sukcesu wynik zostaje wy\u015bwietlony w tym panelu.<\/li>\n<li><strong>beat<\/strong> (puls) \u2014 \u201ebie\u017c\u0105cy czas\u201d, kt\u00f3ry wcze\u015bniej by\u0142 zapisany przez skrypt <strong>heart<\/strong> do mistrza, teraz odczytywany jest z <em>niewolnika<\/em> za pomoc\u0105 jego float IP. Pozwala wizualnie oceni\u0107 wydajno\u015b\u0107 niewolnika i replikacji. W Tuchanka1 nie ma niewolnik\u00f3w z float IP (brak niewolnik\u00f3w \u015bwiadcz\u0105cych us\u0142ugi), ale s\u0105 dwa instancje (Baza Danych), dlatego tutaj wy\u015bwietlane b\u0119dzie nie <strong>beat<\/strong>, a <strong>heart<\/strong> drugiej instancji.<\/li>\n<li>Monitorowanie stanu klastra za pomoc\u0105 narz\u0119dzia <code>pcs mon<\/code>. Pokazuje struktur\u0119, rozk\u0142ad zasob\u00f3w po w\u0119z\u0142ach oraz inne przydatne informacje.<\/li>\n<li>Tutaj wy\u015bwietlane jest monitorowanie systemowe z ka\u017cdej wirtualki klastra. Takich paneli mo\u017ce by\u0107 wi\u0119cej \u2013 tyle, ile wirtualek w klastrze. Dwa wykresy <em>Obci\u0105\u017cenie CPU<\/em> (w wirtualkach po dwa procesory), nazwa wirtualki, <em>Obci\u0105\u017cenie systemu<\/em> (nazywane jako Load Average, poniewa\u017c jest u\u015brednione za 5, 10 i 15 minut), dane o procesach oraz rozk\u0142ad pami\u0119ci.<\/li>\n<li>\u015aledzenie skryptu, wykonuj\u0105cego testy. W przypadku usterki \u2014 nag\u0142ego przerwania pracy lub niesko\u0144czonej p\u0119tli oczekiwania \u2014 mo\u017cna tutaj zobaczy\u0107 przyczyn\u0119 takiego zachowania.<\/li>\n<\/ol>\n<p><\/p>\n<p>Testowanie odbywa si\u0119 w dw\u00f3ch etapach. Najpierw skrypt przechodzi przez wszystkie rodzaje test\u00f3w, losowo wybieraj\u0105c wirtualk\u0119, do kt\u00f3rej ten test zostanie zastosowany. Nast\u0119pnie wykonywana jest niesko\u0144czona p\u0119tla testowania, wirtualki i usterka s\u0105 za ka\u017cdym razem wybierane losowo. Nagle zako\u0144czenie skryptu testowania (dolny panel) lub niesko\u0144czona p\u0119tla oczekiwania na co\u015b (&gt; 5 minut czasu wykonania jednej operacji, co wida\u0107 w \u015bledzeniu) sugeruje, \u017ce kt\u00f3ry\u015b z test\u00f3w w tym klastrze nie powi\u00f3d\u0142 si\u0119.<\/p>\n<p><\/p>\n<p>Ka\u017cdy test sk\u0142ada si\u0119 z nast\u0119puj\u0105cych operacji:<\/p>\n<p><\/p>\n<ol>\n<li>Uruchomienie funkcji, emuluj\u0105cej usterk\u0119.<\/li>\n<li><strong>Gotowe?<\/strong> \u2014 oczekiwanie na przywr\u00f3cenie funkcjonalno\u015bci klastra (gdy \u015bwiadczone s\u0105 wszystkie us\u0142ugi).<\/li>\n<li>Wy\u015bwietlane jest czas oczekiwania na przywr\u00f3cenie klastra (<em>reaction<\/em>).<\/li>\n<li><strong>Napraw<\/strong> \u2014 klaster \u201enaprawia si\u0119\u201d. Po czym powinien wr\u00f3ci\u0107 do pe\u0142nej funkcjonalno\u015bci i gotowo\u015bci na nast\u0119pn\u0105 usterk\u0119.<\/li>\n<\/ol>\n<p><\/p>\n<p>Oto lista test\u00f3w z opisem, co one robi\u0105:<\/p>\n<p><\/p>\n<ul>\n<li><strong>ForkBomb<\/strong>: tworzy &quot;Brak pami\u0119ci&quot; za pomoc\u0105 bomby forkowej.<\/li>\n<li><strong>OutOfSpace<\/strong>: zape\u0142nia dysk twardy. Jednak test ma charakter raczej symboliczny przy tej znikomym obci\u0105\u017ceniu, kt\u00f3re powstaje podczas testowania, przy zape\u0142nieniu dysku twardego, zwykle nie nast\u0119puje awaria PostgreSQL.<\/li>\n<li><strong>Postgres-KILL<\/strong>: zabija PostgreSQL poleceniem <code>killall -KILL postgres<\/code>.<\/li>\n<li><strong>Postgres-STOP<\/strong>: zawiesza PostgreSQL poleceniem <code>killall -STOP postgres<\/code>.<\/li>\n<li><strong>PowerOff<\/strong>: \u201ewy\u0142\u0105cza\u201d wirtualn\u0105 maszyn\u0119 poleceniem <code>VBoxManage controlvm &quot;maszyna wirtualna&quot; poweroff<\/code>.<\/li>\n<li><strong>Reset<\/strong>: restartuje wirtualn\u0105 maszyn\u0119 poleceniem <code>VBoxManage controlvm &quot;maszyna wirtualna&quot; reset<\/code>.<\/li>\n<li><strong>SBD-STOP<\/strong>: zawiesza demon SBD poleceniem <code>killall -STOP sbd<\/code>.<\/li>\n<li><strong>ShutDown<\/strong>: wysy\u0142a na wirtualn\u0105 maszyn\u0119 polecenie przez SSH <code>systemctl poweroff<\/code>, system dzia\u0142a poprawnie.<\/li>\n<li><strong>UnLink<\/strong>: izolacja sieciowa, polecenie <code>VBoxManage controlvm &quot;maszyna wirtualna&quot; setlinkstate1 off<\/code>.<\/li>\n<\/ul>\n<p><\/p>\n<p>Zako\u0144czenie testowania za pomoc\u0105 standardowego polecenia tmux &quot;kill-window&quot; <strong>Ctrl-b &amp;<\/strong>, lub polecenia &quot;detach-client&quot; <strong>Ctrl-b d<\/strong>: w tym czasie testy s\u0105 ko\u0144czone, tmux si\u0119 zamyka, wirtualne maszyny s\u0105 wy\u0142\u0105czane.<\/p>\n<p><\/p>\n<h1 id=\"vyyavlennye-pri-testirovanii-problemy\">Zidentyfikowane problemy podczas test\u00f3w<\/h1>\n<p><\/p>\n<ul>\n<li>\n<p>Na chwil\u0119 obecn\u0105 <em>demon watchdog sbd<\/em> wykonuje zatrzymanie monitorowanych demon\u00f3w, ale nie ich zawieszenie. I w konsekwencji, niepoprawnie s\u0105 traktowane awarie prowadz\u0105ce do zawieszenia tylko <em>Corosync<\/em> i <em>Pacemaker<\/em>, ale przy tym nie zawieszaj\u0105ce <em>sbd<\/em>. Aby sprawdzi\u0107 <em>Corosync<\/em> wi\u0119c z pomoc\u0105 tej kolekcji certyfikat\u00f3w mo\u017cna zbudowa\u0107 \u0142a\u0144cuch i uwierzytelni\u0107 witryn\u0119 internetow\u0105. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClusterLabs\/sbd\/pull\/83\"><strong>PR#83<\/strong> (na GitHubie w <em>sbd<\/em>)<\/a><\/noindex>, zaakceptowane w ga\u0142\u0119zi <em>master<\/em>. Obiecali (w PR#83), \u017ce dla Pacemaker b\u0119dzie co\u015b podobnego, mam nadziej\u0119, \u017ce do <em>RedHat 8<\/em> to zrealizuj\u0105. Ale takie \u201eusterki\u201d s\u0105 teoretyczne, \u0142atwo je odtworzy\u0107 sztucznie przy pomocy na przyk\u0142ad <code>killall -STOP corosync<\/code>, ale nigdy nie wyst\u0119puj\u0105 w rzeczywisto\u015bci.<\/p>\n<p>\n<\/li>\n<li>\n<p>U <em>Pacemaker<\/em> w wersji dla <em>CentOS 7<\/em> niepoprawnie ustawiony jest <em>sync_timeout<\/em> u <em>urz\u0105dzenia quorum<\/em>, w rezultacie <noindex><a rel=\"nofollow\" href=\"https:\/\/lists.clusterlabs.org\/pipermail\/users\/2019-August\/026145.html\">przy awarii jednego w\u0119z\u0142a z pewnym prawdopodobie\u0144stwem resetowa\u0142 si\u0119 r\u00f3wnie\u017c drugi w\u0119ze\u0142<\/a><\/noindex>, na kt\u00f3ry powinien przej\u015b\u0107 master. To zosta\u0142o naprawione przez zwi\u0119kszenie <em>sync_timeout<\/em> u <em>urz\u0105dzenia quorum<\/em> podczas wdra\u017cania (w skrypcie <code>setup\/setup1<\/code>). Ta poprawka nie zosta\u0142a zaakceptowana przez deweloper\u00f3w <em>Pacemaker<\/em>, zamiast tego obiecali przekszta\u0142ci\u0107 infrastruktur\u0119 w taki spos\u00f3b (w nieokre\u015blonej przysz\u0142o\u015bci), aby ten timeout by\u0142 obliczany automatycznie.<\/p>\n<p>\n<\/li>\n<li>\n<p>Je\u015bli przy konfigurowaniu bazy danych wskazano, \u017ce w <code>LC_MESSAGES<\/code> (wiadomo\u015bci tekstowe) mo\u017ce by\u0107 u\u017cywany Unicode, na przyk\u0142ad, <code>ru_RU.UTF-8<\/code>, to przy uruchamianiu <em>postgres<\/em> w \u015brodowisku, gdzie locale nie jest UTF-8, na przyk\u0142ad, w pustym \u015brodowisku (tutaj <em>pacemaker<\/em>+<em>pgsqlms<\/em>(paf) uruchamia <em>postgres<\/em>), to <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/13FE0F7C-5140-499C-8C2E-0BE64BC3A48B%40ya.ru\">w logu zamiast liter UTF-8 pojawi\u0105 si\u0119 znaki zapytania<\/a><\/noindex>. Deweloperzy PostgreSQL nadal nie doszli do zgody, co w takim przypadku zrobi\u0107. Mo\u017cna to obej\u015b\u0107, nale\u017cy ustawi\u0107 <code>LC_MESSAGES=en_US.UTF-8<\/code> podczas konfigurowania (tworzenia) instancji bazy danych.<\/p>\n<p>\n<\/li>\n<li>\n<p>Je\u015bli ustawiono wal_receiver_timeout (domy\u015blnie 60s), to podczas testu PostgreSQL-STOP na g\u0142\u00f3wnym serwerze w klastrach tuchanka3 i tuchanka4 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/60590EC6-4062-4F25-A49C-3948ED2A7D47%40ya.ru\">nie nast\u0119puje ponowne po\u0142\u0105czenie replikacji z nowym g\u0142\u00f3wnym serwerem.<\/a><\/noindex>. Replikacja jest tam synchronizowana, wi\u0119c zatrzymuje si\u0119 nie tylko pracownik, ale tak\u017ce nowy g\u0142\u00f3wny serwer. Mo\u017cna to obej\u015b\u0107, ustawiaj\u0105c wal_receiver_timeout=0 podczas konfiguracji PostgreSQL.<\/p>\n<p>\n<\/li>\n<li>\n<p>Rzadko zaobserwowano zawieszanie replikacji w PostgreSQL podczas testu ForkBomb (przepe\u0142nienie pami\u0119ci). <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/60590EC6-4062-4F25-A49C-3948ED2A7D47%40ya.ru\">Po ForkBomb czasami pracownicy mog\u0105 nie ponownie po\u0142\u0105czy\u0107 si\u0119 z nowym g\u0142\u00f3wnym serwerem.<\/a><\/noindex>. Spotka\u0142em si\u0119 z tym tylko w klastrach tuchanka3 i tuchanka4, gdzie z powodu synchronizowanej replikacji zawiesi\u0142 si\u0119 g\u0142\u00f3wny serwer. Problem ust\u0119powa\u0142 sam, po jakim\u015b d\u0142u\u017cszym czasie (oko\u0142o dw\u00f3ch godzin). Wymaga to dodatkowego badania, aby to naprawi\u0107. Objawy przypominaj\u0105 poprzedni b\u0142\u0105d, kt\u00f3ry jest spowodowany inn\u0105 przyczyn\u0105, ale ma identyczne konsekwencje.<\/p>\n<p>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>Obraz krogan zosta\u0142 wzi\u0119ty z <noindex><a rel=\"nofollow\" href=\"http:\/\/fav.me\/d8fo42n\">Deviant Art<\/a><\/noindex> za zgod\u0105 autora:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelowanie odpornych klastr\u00f3w bazuj\u0105cych na PostgreSQL i Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/ded1ead387814d97d84d0fb89e025386.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/516538\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0430\u0445, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0445 \u043e\u043f\u0442\u043e\u0432\u043e\u043b\u043e\u043a\u043d\u043e\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0433\u043e\u0440\u043e\u0434\u0430, \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u0439 \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0431\u0435\u0441\u0442\u043e\u0447\u0438\u0432\u0430\u043d\u0438\u0435) \u043e\u0434\u043d\u043e\u0433\u043e \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0430. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043e\u0444\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c, \u0432\u044b\u0431\u0440\u0430\u043b Pacemaker, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0442 RedHat \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432. \u041e\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0442\u0435\u043c, \u0447\u0442\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":92571,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-92570","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\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.\" \/>\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\/pl\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\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\u041c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u043d\u0430 \u0431\u0430\u0437\u0435 PostgreSQL \u0438 Pacemaker | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker\" \/>\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=\"2020-08-28T17:42:21+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-28T17:42:21+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\udd47Modelowanie klastr\u00f3w odpornych na awarie z wykorzystaniem PostgreSQL i Pacemaker | ProHoster","description":"Wprowadzenie Jaki\u015b czas temu postawiono przede mn\u0105 zadanie opracowania klastra odpornego na awarie dla PostgreSQL.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","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\u041c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u043d\u0430 \u0431\u0430\u0437\u0435 PostgreSQL \u0438 Pacemaker | ProHoster","og:description":"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","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":"2020-08-28T17:42:21+00:00","article:modified_time":"2020-08-28T17:42:21+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"92570","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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:06:03","updated":"2022-09-29 15:28:29","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/92570","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=92570"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/92570\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/92571"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=92570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=92570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=92570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}