Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

Danes je visoka dostopnost storitev potrebna povsod in vselej, ne le v velikih dragih projektih. Strani, ki so začasno nedostopne z obvestilom „Opravičujemo se, poteka vzdrževanje“, še vedno obstajajo, a običajno povzročajo zgolj milo nasmešek. Dodajmo k temu življenje v oblakih, kjer je za zagon dodatnega strežnika potrebna le ena API klica, pri čemer ni potrebno razmišljati o „železni“ rabi. In tako ni več opravičil, zakaj kritični sistemi niso bili zasnovani zanesljivo z uporabo klasterskih tehnologij in rezervacij.

Povedali vam bomo, katere rešitve smo preučili za zagotavljanje zanesljivosti podatkovnih baz v naših storitvah in do česa smo prišli. Poleg tega bomo prikazali demoodgovor, ki ponuja daljnosežne zaključke.

Legasi v arhitekturi zagotavljanja visoke dostopnosti

Še bolje je to vidno v okviru razvoja različnih opensource sistemov. Stare rešitve so bile prisiljene dodati tehnologije visoke dostopnosti, ko je povpraševanje naraščalo. Kakovost njihovih rešitev se je zelo razlikovala. Rešitve nove generacije postavljajo visoko dostopnost v središče svoje arhitekture. Na primer, MongoDB postavlja klaster kot glavno možnost uporabe. Klaster se horizontalno širi, kar predstavlja močno konkurenčno prednost te baze podatkov.

Vrnimo se k PostgreSQL. To je eden najstarejših priljubljenih opensource projektov, katerega prvi izid je bil leta 1995. Ekipa projekta dolgo časa ni menila, da je visoka dostopnost naloga, ki ga je treba rešiti s strani sistema. Zato je tehnologija replikacije za ustvarjanje kopij podatkov postala vgrajena šele v različici 8.2 leta 2006, vendar je bila datotečna (log shipping). Leta 2010 je v različici 9.0 prišla tokovna replikacija, ki je osnova za ustvarjanje najrazličnejših klastrov. To pa v resnici zelo preseneča ljudi, ki se seznanjajo s PostgreSQL po Enterprise SQL ali sodobnih NoSQL, saj je standardna rešitev skupnosti preprosto par master-replica s sinhrono ali asinhrono replikacijo. Pri tem je v stoku preklop močnega strežnika izveden ročno, vprašanje preklopa strank pa se ponuja rešiti samostojno.

Kako smo se odločili zgraditi zanesljiv PostgreSQL in kaj smo za to izbrali

Kljub temu PostgreSQL ne bi bil tako priljubljen, če ne bi bilo velikega števila projektov in orodij, ki pomagajo zgraditi odporno rešitev, ki ne zahteva stalnega nadzora. V oblakih Mail.ru Cloud Solutions (MCS) so bili od začetka DBaaS na voljo posamezni strežniki PostgreSQL in pare master-replika z asinhronim replikacijskim procesom.

Seveda smo želeli olajšati življenje vsem in omogočiti namestitev PostgreSQL, ki bi lahko služila kot osnova za visoko razpoložljive storitve, za katero ne bi bilo treba nenehno skrbeti in se prebivati ponoči, da bi izvedli preklop. V tem segmentu so tako stare preverjene rešitve kot nova generacija orodij, ki uporabljajo najnovejša znanja.

Danes težava visoke razpoložljivosti ni v rezervaciji (to je samoumevno), temveč v konsenzu — algoritmu za izbiro vodje (Leader election). Najpogosteje velike okvare ne nastanejo zaradi pomanjkanja strežnikov, ampak zaradi težav s konsenzom: novi vodja ni bil izbran, pred pojavila sta se dva vodje v različnih podatkovnih centrih itd. Primer — okvara v MySQL-klasterju Github — napisali so podroben post mortem.

Matematična osnova pri tem vprašanju je zelo resna. Po eni strani obstaja CAP teorema, ki nalaga teoretične omejitve na možnosti gradnje HA-rešitev, po drugi strani pa matematično dokazane algoritme za določanje konsenza, kot je Paxos in Raft. Na tej osnovi obstoječi precej priljubljeni DCS (sistemi decentraliziranega konsenza) — Zookeeper, etcd, Consul. Zato, če sistem odločanja deluje na nekem svojem algoritmu, ki je bil napisan samostojno, je treba biti zelo previden. Po analizi ogromne količine sistemov smo se odločili za Patroni — opensource-sistem, ki ga večinoma razvija podjetje Zalando.

Kot sem že omenil, smo razmišljali tudi o rešitvah z več glavnimi strežniki, torej o grozdih, ki jih je mogoče horizontalno razširiti za pisanje. Kljub temu smo se zaradi dveh glavnih razlogov odločili, da takšnega grozda ne bomo oblikovali. Prvič, takšne rešitve imajo visoko kompleksnost in posledično več ranljivih mest. Težko bo ugotoviti stabilno rešitev za vse primere. Drugič, v tem primeru PostgreSQL preneha biti čist (nativni), nekatere funkcije ne bodo na voljo, pri nekaterih aplikacijah pa se lahko pojavijo skriti hrošči med delovanjem.

Patroni

Kako torej deluje Patroni? Razvijalci niso izumili kolesa in so kot osnovo uporabili eno izmed preverjenih DCS rešitev. Vse naloge, povezane s sinhronizacijo konfiguracij, izbiro vodje in kvorumom, so mu bile dodeljene. Izbrali smo etcd.

Nato se Patroni ukvarja s pravilno uporabo vseh nastavitev na PostgreSQL in s konfiguracijo replikacije, pa tudi z izvajanjem ukazov za preklop in obnovitev (tj. tako za redno kot tudi za izredne preklope glavnega strežnika). Konkretno v oblaku MCS lahko ustvarite grozd iz glavnega strežnika, sinhrone replikacije ter ene ali več asimetričnih replik. Prisotnost sinhrone replikacije zagotavlja varnost podatkov najmanj na dveh strežnikih, ta replikacija pa bo glavni

Zaradi tega, da se etcd postavi na iste strežnike, je priporočljivo število strežnikov 3 ali 5, za optimalno vrednost kvoruma. Takšen grozd se horizontalno širi za branje (o širjenju za pisanje sem pisal prej). Kljub temu je treba upoštevati, da so asimetrične replikacije nagnjene k zaostajanju, zlasti pri visokih obremenitvah.

Uporaba takšnih replikacij za branje (hot standby) je smiselna za poročanje ali analitiko in razbremeni glavni strežnik.

Če želite sami ustvariti tak grozd, boste potrebovali:

  • pripraviti 3 ali več strežnikov, nastaviti IP-naslove in pravila za požarni zid med njimi;
  • namestiti pakete za storitve etcd, Patroni, PostgreSQL;
  • nastaviti grozd etcd;
  • nastaviti službo patroni za delo s PostgreSQL.

To put it simply, you need to properly create about ten configuration files without making any mistakes. It's definitely worth using a configuration management tool like Ansible, for example. However, there is still no highly available TCP load balancer. Creating one is a separate task.

For those who need a ready-made cluster but don't want to dig into all of this, we have tried to simplify life and created a ready-made cluster on Patroni in our cloud, which can be tested for free. In addition to the cluster itself, we have created:

  • A TCP load balancer; it always points to the current master, whether it's a synchronous or asynchronous replica, depending on the ports.
  • An API for switching the active master of Patroni.

They can be connected both through the MCS cloud API and the web console.

Demo

To test the capabilities of the PostgreSQL cluster in the MCS cloud, let's see how a live application behaves during database problems.

Below is the code for an application that will log artificial events and report this on the screen. In case of errors, it will notify about them and continue its work in a loop until we stop it with Ctrl + C.

from __future__ import print_function

from datetime import datetime
from random import randint
from time import sleep
import psycopg2


def main():
    try:
        connection = psycopg2.connect(user = "admin",
                                      password = "P@ssw0rd",
                                      host = "89.208.87.38",
                                      port = "5432",
                                      database = "myproddb")

        cursor = connection.cursor()
        cursor.execute("SELECT version();")
        record = cursor.fetchone()
        print("Connection opened to", record[0])

        cursor.execute(
            "INSERT INTO log VALUES ({});".format(randint(1, 10000)))
        connection.commit()
        cursor.execute("SELECT COUNT(event_id) from log;")
        record = cursor.fetchone()
        print("Logged a value, overall count: {}".format(record[0]))
    except Exception as error:
        print ("Error while connecting to PostgreSQL", error)
    finally:
        if connection:
            cursor.close()
            connection.close()
            print("Connection closed")


if __name__ == '__main__':
    try:
        while True:
            try:
                print(datetime.now())
                main()
                sleep(3)
            except Exception as e:
                print("Caught error:n", e)
                sleep(1)
    except KeyboardInterrupt:
        print("exit")

The application requires PostgreSQL to operate. Let's create a cluster in the MCS cloud using the API. In a regular terminal, where the OS_TOKEN environment variable contains the token for accessing the API (which can be obtained with the command openstack token issue), we will enter the commands:

Creating a cluster:

cat < pgc10.json
{"cluster":{"name":"postgres10","allow_remote_access":true,"datastore":{"type":"postgresql","version":"10"},"databases":[{"name":"myproddb"}],"users":[{"databases":[{"name":"myproddb"}],"name":"admin","password":"P@ssw0rd"}],"instances":[{"key_name":"shared","availability_zone":"DP1","flavorRef":"d659fa16-c7fb-42cf-8a5e-9bcbe80a7538","nics":[{"net-id":"b91eafed-12b1-4a46-b000-3984c7e01599"}],"volume":{"size":50,"type":"DP1"}},{"key_name":"shared","availability_zone":"DP1","flavorRef":"d659fa16-c7fb-42cf-8a5e-9bcbe80a7538","nics":[{"net-id":"b91eafed-12b1-4a46-b000-3984c7e01599"}],"volume":{"size":50,"type":"DP1"}},{"key_name":"shared","availability_zone":"DP1","flavorRef":"d659fa16-c7fb-42cf-8a5e-9bcbe80a7538","nics":[{"net-id":"b91eafed-12b1-4a46-b000-3984c7e01599"}],"volume":{"size":50,"type":"DP1"}}]}}
EOF

curl -s -H "X-Auth-Token: $OS_TOKEN" 
-H 'Accept: application/json' 
-H 'Content-Type: application/json' 
-d @pgc10.json https://infra.mail.ru:8779/v1.0/ce2a41bbd1434013b85bdf0ba07c770f/clusters

Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

Ko bo кластер прешел в статус ACTIVE, всі поля отримують актуальні значення — кластер готовий.

У графічному інтерфейсі:

Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

Спробуємо підключитися та створити таблицю:

psql -h 89.208.87.38 -U admin -d myproddb
Пароль для користувача admin:
psql (11.1, сервер 10.7)
Введіть "help" для допомоги.

myproddb=> CREATE TABLE log (event_id integer NOT NULL);
CREATE TABLE
myproddb=> INSERT INTO log VALUES (1),(2),(3);
INSERT 0 3
myproddb=> SELECT * FROM log;
 event_id
----------
        1
        2
        3
(3 rows)

myproddb=>

Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

В додатку вкажемо актуальні налаштування для підключення до PostgreSQL. Ми вкажемо адресу TCP-балансувальника, тим самим уникнувши необхідності ручного переключення на адресу майстра. Запустимо його. Як видно, події успішно логуються в базу даних.

Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

Планове переключення майстра

Тепер протестуємо роботу нашого додатку під час планового переключення майстра:

Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

Спостерігаємо за додатком. Бачимо, що робота додатку дійсно переривається, але триває це всього кілька секунд, у цьому конкретному випадку, максимум 9.

Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

Падіння машини

Тепер спробуємо імітювати падіння віртуальної машини, поточного майстра. Можна було б просто вимкнути віртуальну машину через інтерфейс Horizon, але це буде штатне вимкнення. Таке переключення буде оброблене всіма службами, в тому числі, Patroni.

Нам же потрібно непередбачуване вимкнення. Тому я попросив наших адміністраторів у тестових цілях вимкнути віртуальну машину — поточного майстра — нестандартним способом.

Kako smo izgradili pouzdan klaster PostgreSQL na Patroniju.

В той же час продовжувало працювати наше додаток. Природно, таке екстрене переключення майстра не могло пройти непоміченим.

2019-03-29 10:45:56.071234
Se je povezava odprta za PostgreSQL 10.7 na x86_64-pc-linux-gnu, sestavljen z gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Zabeležena vrednost, skupno število: 453
Povezava zaprta
2019-03-29 10:45:59.205463
Se je povezava odprta za PostgreSQL 10.7 na x86_64-pc-linux-gnu, sestavljen z gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Zabeležena vrednost, skupno število: 454

Povezava zaprta
2019-03-29 10:46:02.661440
Napaka pri povezovanju s strežnikom PostgreSQL, povezava je bila nepričakovano zaprta
        To verjetno pomeni, da je strežnik nepravilno končal
        pred ali med obdelavo zahtevka.

Ujeta napaka:
 lokalna spremenljivka 'connection' se sklicuje pred dodelitvijo
……………………………………………………….. - tukaj je nekaj napak
2019-03-29 10:46:30.930445
Napaka pri povezovanju s strežnikom PostgreSQL, povezava je bila nepričakovano zaprta
        To verjetno pomeni, da je strežnik nepravilno končal
        pred ali med obdelavo zahtevka.

Ujeta napaka:
 lokalna spremenljivka 'connection' se sklicuje pred dodelitvijo
2019-03-29 10:46:31.954399
Se je povezava odprta za PostgreSQL 10.7 na x86_64-pc-linux-gnu, sestavljen z gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Zabeležena vrednost, skupno število: 455
Povezava zaprta
2019-03-29 10:46:35.409800
Se je povezava odprta za PostgreSQL 10.7 na x86_64-pc-linux-gnu, sestavljen z gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Zabeležena vrednost, skupno število: 456
Povezava zaprta
^Cizhod

Kot je razvidno, je aplikacija uspela nadaljevati svoje delo v manj kot 30 sekundah. Da, nekateri uporabniki storitve bodo opazili težave. Vendar pa gre za resno okvaro strežnika, kar se ne zgodi pogosto. Človek (administrator) verjetno ne bi uspel reagirati tako hitro, razen če ne bi sedel za konzolo z pripravljenim skriptom za preklop.

Izlaz

Zdi se mi, da takšen klooster daje ogromno prednost za administratorje. V bistvu resne okvare in izpadi strežnikov Baze podatkov ne bodo opazni aplikaciji in posledično uporabniku. Nič ne bo treba hitro popravljati in preklapljati na začasne konfiguracije, strežnike itd. In če bi takšno rešitev uporabili v obliki pripravljene storitve v oblakih, ne bi bilo treba izgubljati časa za njeno pripravo. Lahko se bomo ukvarjali s čim bolj zanimivim.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster