Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Tänapäeval on teenuste kõrge kättesaadavus vajalik alati ja igal pool, mitte ainult suurtes kallites projektides. Ajutiselt mitteühendatud veebisaidid, millel on teade "Vabandame, teostatakse tehnilisi töid", on veel levinud, kuid neid vaadatakse tavaliselt halastava naeratusega. Lisame siia elu pilvedes, kus täiendava serveri käivitamiseks on vajalik vaid üks API-kõne, samas ei pea muretsema „rauda” haldamise pärast. Nii et ei jää enam õigustusi, miks kriitilist süsteemi ei ole usaldusväärselt loodud, kasutades klustertehnoloogiaid ja varundamist.

Kätkeme, milliseid lahendusi me oleme kaalunud andmebaaside usaldusväärsuse tagamiseks oma teenustes ja millistele järeldustele oleme jõudnud. Pluss demo kaugeltulenevate järeldustega.

Legasi kõrge kättesaadavuse arhitektuuris

Seda on veel selgem, kui vaatame erinevate avatud lähtekoodiga süsteemide arengut. Vanemad lahendused pidid lisama kõrge kättesaadavuse tehnoloogiaid vastavalt kasvavale nõudlusele, mille kvaliteet oli erinev. Uue põlvkonna lahendused sisaldavad kõrge kättesaadavuse oma arhitektuuri aluseks. Näiteks positsioneerib MongoDB klastrit peamise kasutusvõimalusena. Klaster skaleerub horisontaalselt, mis on selle andmebaasisüsteemi tugev konkurentsieelis.

Tagasi PostgreSQL juurde. See on üks vanimaid ja populaarsemaid avatud lähtekoodiga projekte, mille esialgne versioon ilmus 1995. aastal. Projekti meeskond pikka aega ei pidanud kõrget kättesaadavust süsteemist tulenevaks ülesandeks. Seetõttu sai koopia loomise replikatsioonitehnoloogia sisseehitatud alles versioonis 8.2 2006. aastal, kuid see oli failide (log shipping) alusel. 2010. aastal ilmus versioon 9.0, mille puhul on aktiivne replikatsioon ja mis on aluseks erinevate klastrite loomisele. See üllatab inimesi, kes tutvuvad PostgreSQL-iga pärast Enterprise SQL-i või kaasaegseid NoSQL-i — kogukonna standardlahendus on lihtsalt paar master-replica koos sünkroonsete või asünkroonsete replikatsioonidega. Samuti toimub masteri vahetamine käsitsi, ja kliendi vahetuse küsimus jääb samuti lahendamiseks kliendi enda kanda.

Kuidas me otsustasime, et teeme usaldusväärse PostgreSQL-i, ja mida me selleks valisime

Siiski ei oleks PostgreSQL saanud nii populaarseks, kui poleks olnud tohutut hulka projekte ja tööriistu, mis aitavad luua tõrkeohutust lahendust, mis ei nõua pidevat tähelepanu. Pilves Mail.ru Cloud Solutions (MCS) DBaaS-i käivitamisest alates oli saadaval üksik Postgres SQL-server ja paar master-replika asünkroonses replikatsioonis.

Muidugi soovisime kõigi elu lihtsamaks teha ja muuta PostgreSQL-i paigaldamine kergesti kättesaadavaks, et see saaks olla aluseks kõrge saadavusega teenustele, mille eest ei peaks pidevalt jälgima ega öösel üles ärkama, et vahetust teha. Selles segmendis on nii vanad ja usaldusväärsed lahendused kui ka uus põlvkond tööriistu, mis kasutavad uusimaid edusamme.

Tänapäeval seisab kõrge saadavuse probleem silmitsi mitte varudega (see on iseenesestmõistetav), vaid konsensusega — liidri valimise algoritmiga (Leader election). Suured õnnetused juhtuvad tihti mitte serverite puudumise tõttu, vaid konsensuse probleemide tõttu: uus liider ei olnud valitud, kaks liidrit ilmusid erinevatesse andmekeskustesse jne. Näide - Github'i MySQL-klastri rike — nad kirjutasid detailse postmorti.

Matemaatiline alus selles küsimuses on väga tõsine. Ühest küljest on olemas CAP teoreem, mis seabus teoreetilisi piiranguid HA-lahenduste ehitamise võimalustele, teiselt poolt – matemaatiliselt tõestatud konsensusalgoritmid, nagu Paxos ja Raft. Selle alusel eksisteerivad suhteliselt populaarsed DCS (detsentraliseeritud konsensuse süsteemid) – Zookeeper, etcd, Consul. Seetõttu, kui otsustusprotsess töötab mõnel enda kirjutatud algoritmil, tuleb sellele äärmiselt ettevaatlikult läheneda. Pärast suure hulga süsteemide analüüsi oleme peatunud Patroni – avatud lähtekoodiga süsteemi, mille peamine arendaja on Zalando.

Kuna lühiülevaates ütlen, et me vaatasime ka multi-master lahendusi, st klastreid, mida saab kirjutamiseks horisontaalselt skaleerida. Kuid kahest peamisest põhjusest otsustasime sellist klastrit mitte luua. Esiteks, sellistel lahendustel on kõrge keerukus ja seega rohkem haavatavaid kohti. Kõigi olukordade jaoks on raske luua stabiilset lahendust. Teiseks, sellisel juhul lakkab PostgreSQL olemast puhas (native), mõned funktsioonid on kätte saamata, mõnedel rakendustel võivad tekkida varjatud vead.

Patroni

Nii et, kuidas Patroni töötab? Arendajad ei hakanud jalgrattaga leiutama ja pakkusid aluseks kasutada üht tõestatud DCS-lahendust. Sellele allutatakse kõik küsimused, mis puudutavad konfiguratsioonide sünkroniseerimist, juhi valikut ja kvoorumi. Meie valisime selle jaoks etcd.

Edasi teeb Patroni õigesti kõigi se設定ste rakendamise PostgreSQL-is ja replikatsiooni seadistamine ning käskude täitmine switchover ja failover (st ettenähtud ja erakorralise meistri vahetamise). Konkreetselt MCS-is saab luua klastrit meistrist, sünkroonsest replikast ja ühest või mitmest asünkroonsest replikast. Sünkroonsed replikad tagavad andmete säilimise vähemalt 2 serveris ning just see replik jääb peamiseks 'meistriks kandideerijaks'.

Kuna etcd taasalustatakse samadel serveritel, on soovitatav serverite arv 3 või 5, optimaalsete kvoorumi väärtuste jaoks. Selline klaster skaleerub horisontaalselt lugemiseks (kirjutamise skaleerimist olen maininud eespool). Siiski tuleb arvestada, et asünkroonsed replikad kipuvad jääma maha, eriti kõrge koormuse ajal.

Hot standby replikatsioonide kasutamine on põhjendatud aruandluse või analüüsi ülesannete jaoks ning vähendab peaserveri koormust.

Kui soovite sellise klastrit ise luua, vajate:

  • kolme või enama serveri ettevalmistamist, IP-aadresside seadistamist ja tulemüürireeglite loomist nende vahel;
  • etcd, Patroni, PostgreSQL teenuste paketide installimist;
  • etcd klastrite seadistamist;
  • patroni teenuse seadistamist PostgreSQL-iga töötamiseks.

See tähendab, et peate kokku panema kümneid konfiguratsioonifaile ning mitte kuskil eksima. Selle jaoks tasub kindlasti kasutada konfiguratsioonihalduse tööriista, näiteks Ansible. Lisaks puudub siiani kõrge kättesaadavusega TCP-balasija. Selle loomine on eraldi töö.

Neile, kellele on vajalik valmis klaster, kuid kes ei soovi kaevuda, oleme püüdnud elu lihtsustada ja loonud meie pilves valmis klastrit Patronil, mida saab tasuta proovida. Klastri kõrval oleme loonud:

  • TCP-balasija; erinevatel portidel osutab see alati praegusele meistrile, sõltumata sellest, kas see on sünkroonne või asünkroonne replikaat;
  • API aktiivse meistri Patroni vahetamiseks.

Neid saab integreerida nii MCS-i pilve API kaudu kui ka veebi konsooli kaudu.

Demos

Et testida PostgreSQL klastrite võimalusi MCS-i pilves, vaatame, kuidas käitub reaalne rakendus andmebaasi probleemide korral.

Järgnevalt on esitatud rakenduse kood, mis logib kunstlikke sündmusi ja kuvab need ekraanil. Viga korral teavitab see veast ja jätkab tööd silmusena, kuni me selle Ctrl + C kombinatsiooniga peatame.

import print_function tulevikust

datetime import datetime
random import randint
sleep import time
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("Ühendus avatud", 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("Logitud väärtus, koguarv: {}".format(record[0]))
    except Exception as error:
        print ("Viga PostgreSQL-iga ühendamisel", error)
    finally:
        if connection:
            cursor.close()
            connection.close()
            print("Ühendus suletud")


if __name__ == '__main__':
    try:
        while True:
            try:
                print(datetime.now())
                main()
                sleep(3)
            except Exception as e:
                print("Tuvastatud viga:n", e)
                sleep(1)
    except KeyboardInterrupt:
        print("väljuda")

Rakenduse tööks on vajalik PostgreSQL. Loome MCS-is klastri, kasutades API-d. Tavalises terminalis, kus keskkonna muutujas OS_TOKEN on API juurdepääsu token (selle saate käsuga openstack token issue), sisestame käsud:

Loome klastri:

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

Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Kui klaster muutub aktiivseks, saavad kõik väljad ajakohased — klaster on valmis.

GUI-s:

Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Proovime ühenduda ja luua tabeli:

psql -h 89.208.87.38 -U admin -d myproddb
Kasutaja admini parool:
psql (11.1, server 10.7)
Tüüpi "help" abiks.

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

Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Rakenduses anname praegused seaded PostgreSQL-iga ühendamiseks. Tõstame TCP-balanseerija aadressi, mis elimineerib vajaduse käsitsi vahetada meistriaadressi. Käivitame selle. Nagu näha, logitakse sündmused edukalt andmebaasi.

Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Planeeritud meistri vahetus

Nüüd testime meie rakenduse toimimist planeeritud meistri vahetuse ajal:

Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Jälgime rakendust. Näeme, et rakenduse töö tõepoolest katkeb, kuid see kestab vaid paar sekundit, antud juhul maksimaalselt 9.

Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Masina rike

Nüüd proovime simuleerida virtuaalse masina, hetke meistri, riket. Võiksime lihtsalt välja lülitada virtuaalse masina Horizon'i liidese kaudu, kuid see oleks tavaline välja lülitamine. Selline vahetus töötatakse läbi kõigi teenuste, sealhulgas Patroni, poolt.

Kuid me vajame ettearvamatut välja lülitamist. Seetõttu palusin meie administraatoritel testimise eesmärgil virtuaalne masin — hetke meister — ebanormaalset viisi välja lülitada.

Kuidas meiehitasime usaldusväärse PostgreSQL klastrite Patronil

Sel ajal jätkas meie rakendus tööd. Loomulikult ei saa selline äkiline meistri vahetus jääda märkamata.

2019-03-29 10:45:56.071234
Ühendus PostgreSQL 10.7-ga avatud x86_64-pc-linux-gnu platvormil, kompileeritud gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logitud väärtus, koguarv: 453
Ühendus suletud
2019-03-29 10:45:59.205463
Ühendus PostgreSQL 10.7-ga avatud x86_64-pc-linux-gnu platvormil, kompileeritud gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logitud väärtus, koguarv: 454

Ühendus suletud
2019-03-29 10:46:02.661440
Viga PostgreSQL serveriga ühenduse loomisel, ühendus sulgus ootamatult
        See tähendab tõenäoliselt, et server lõpetas anomaalselt
        enne või töötlemise ajal.

Püütud viga:
 kohaliku muutuja 'connection' viidatud enne määramist
……………………………………………………….. - siin on mingi hulk vigu
2019-03-29 10:46:30.930445
Viga PostgreSQL serveriga ühenduse loomisel, ühendus sulgus ootamatult
        See tähendab tõenäoliselt, et server lõpetas anomaalselt
        enne või töötlemise ajal.

Püütud viga:
 kohaliku muutuja 'connection' viidatud enne määramist
2019-03-29 10:46:31.954399
Ühendus PostgreSQL 10.7-ga avatud x86_64-pc-linux-gnu platvormil, kompileeritud gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logitud väärtus, koguarv: 455
Ühendus suletud
2019-03-29 10:46:35.409800
Ühendus PostgreSQL 10.7-ga avatud x86_64-pc-linux-gnu platvormil, kompileeritud gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logitud väärtus, koguarv: 456
Ühendus suletud
^Cexit

Nagu näha, suutis rakendus jätkata oma tööd vähem kui 30 sekundi pärast. Jah, mõni teenuse kasutaja märkab tõenäoliselt probleeme. Siiski on see tõsine serveri rike, mis ei juhtu sageli. Samas ei oleks inimene (administraator) tõenäoliselt suutnud reageerida sama kiiresti, kui ta just ei oleks olnud valmis konsoolis koos vahetus scriptiga.

Kokkuvõte

Minu arvates annab selline klaster administraatoritele tohutu eelise. Tegelikult ei näe rakendus tõsiseid rikete ja andmebaasi serverite välja langenud olekuid ning seega ei näe seda ka kasutajad. Ei pea midagi kiirustades parandama ega ajutistele konfiguratsioonidele, serveritele jms üle minema. Ja kui sellist lahendust kasutatakse valmisteenusena pilves, pole ettevalmistamiseks aega raiskamise vajadust. Saate tegeleda millegi huvitavamaga.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster