Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Sot, disponueshmëria e lartë e shërbimeve kërkohet gjithmonë dhe kudo, jo vetëm në projekte të mëdha të shtrenjta. Faqet përkohësisht të padisponueshme me mesazhin "Më falni, mirëmbajtja është në vazhdim" janë gjetur ende, por zakonisht shkaktojnë një buzëqeshje nënçmuese. Le t'i shtojmë kësaj jete në re, kur për të nisur një server shtesë ju nevojitet vetëm një telefonatë në API dhe nuk keni nevojë të mendoni për funksionimin "hardware". Dhe nuk ka më asnjë justifikim pse një sistem kritik nuk u ndërtua në mënyrë të besueshme duke përdorur teknologji të grupimeve dhe tepricë.

Ne do t'ju tregojmë se cilat zgjidhje kemi konsideruar për të siguruar besueshmërinë e bazave të të dhënave në shërbimet tona dhe në çfarë kemi arritur. Plus një demonstrim me përfundime të gjera.

Trashëgimia në arkitekturën me disponueshmëri të lartë

Kjo shihet edhe më mirë në kontekstin e zhvillimit të sistemeve të ndryshme me burim të hapur. Zgjidhjet e vjetra u detyruan të shtonin teknologji me disponueshmëri të lartë ndërsa kërkesa u rrit. Dhe cilësia e tyre ndryshonte. Zgjidhjet e gjeneratës së ardhshme vendosin disponueshmërinë e lartë në thelb të arkitekturës së tyre. Për shembull, MongoDB pozicionon grupimin si rastin e tij kryesor të përdorimit. Klasteri shkallëzohet horizontalisht, gjë që është një avantazh i fortë konkurrues i kësaj DBMS.

Le të kthehemi te PostgreSQL. Ky është një nga projektet më të vjetra me burim të hapur, publikimi i parë i të cilit u zhvillua në vitin 95 të shekullit të kaluar. Për një kohë të gjatë, ekipi i projektit nuk e konsideronte disponueshmërinë e lartë si një problem që duhej të adresohej nga sistemi. Prandaj, teknologjia e riprodhimit për krijimin e kopjeve të të dhënave u bë e integruar vetëm në versionin 8.2 në 2006, por ishte e bazuar në skedarë (transportimi i regjistrave). Në vitin 2010, versioni 9.0 prezantoi përsëritjen e transmetimit dhe është baza për krijimin e një shumëllojshmërie të gjerë grupimesh. Kjo, në fakt, është shumë befasuese për njerëzit që njihen me PostgreSQL pas Enterprise SQL ose NoSQL moderne - zgjidhja standarde nga komuniteti është thjesht një çift master-kopje me përsëritje sinkron ose asinkron. Në të njëjtën kohë, në magazinë, ndërrimi i masterit bëhet me dorë, dhe çështja e ndërrimit të klientëve gjithashtu propozohet të zgjidhet në mënyrë të pavarur.

Si vendosëm të bënim PostgreSQL të besueshme dhe çfarë zgjodhëm për këtë

Sidoqoftë, PostgreSQL nuk do të ishte bërë kaq popullor nëse nuk do të kishte një numër të madh projektesh dhe mjetesh që ndihmojnë në ndërtimin e një zgjidhjeje tolerante ndaj gabimeve që nuk kërkon vëmendje të vazhdueshme. Në re Mail.ru Cloud Solutions Serverët e vetëm PostgreSQL (MCS) dhe çiftet master-replica me replikim asinkron janë të disponueshëm që nga fillimi i DBaaS.

Natyrisht, ne donim ta bënim jetën më të lehtë për të gjithë dhe të vëmë në dispozicion një instalim PostgreSQL që mund të shërbente si bazë për shërbime shumë të disponueshme, pa pasur nevojë të monitoronim vazhdimisht dhe të zgjoheshim natën për të bërë ndryshimin. Në këtë segment ka zgjidhje të vjetra të provuara dhe një gjeneratë shërbimesh të reja që përdorin zhvillimet më të fundit.

Sot, problemi i disponueshmërisë së lartë nuk qëndron në tepricë (kjo është e vetëkuptueshme), por në konsensus - algoritmi i zgjedhjes së Udhëheqësit. Më shpesh, aksidentet e mëdha ndodhin jo për shkak të mungesës së serverëve, por për shkak të problemeve me konsensusin: nuk është zgjedhur një drejtues i ri, dy drejtues janë shfaqur në qendra të ndryshme të të dhënave, etj. Shembull - një aksident në një grupim Github MySQL - shkruan ata pas vdekjes së detajuar.

Baza matematikore në këtë çështje është shumë serioze. Nga njëra anë, ekziston Teorema CAP, që vendos kufizime teorike në mundësitë e ndërtimit të zgjidhjeve HA, nga ana tjetër, algoritme të vërtetuara matematikisht për përcaktimin e konsensusit, si p.sh. Paxos и trap. Mbi këtë bazë, ekzistojnë DCS mjaft të njohura (sistemet e konsensusit të decentralizuar) - Zookeeper, etcd, Consul. Prandaj, nëse sistemi i vendimmarrjes funksionon në një lloj algoritmi, të shkruar në mënyrë të pavarur, duhet ta trajtoni atë me kujdes ekstrem. Pasi analizuam një numër të madh sistemesh, u vendosëm në Patroni, një sistem me burim të hapur i zhvilluar kryesisht nga Zalando.

Si një digresion lirik, do të them se kemi marrë në konsideratë edhe zgjidhje shumë-mjeshtërore, domethënë grupime që mund të shkallëzohen horizontalisht për regjistrim. Megjithatë, për dy arsye kryesore ata vendosën të mos krijojnë një grup të tillë. Së pari, zgjidhje të tilla kanë kompleksitet të lartë dhe, në përputhje me rrethanat, më shumë dobësi. Do të jetë e vështirë për të gjetur një zgjidhje të qëndrueshme për të gjitha rastet. Së dyti, në këtë rast PostgreSQL pushon së qeni i pastër (vendas), disa funksione nuk do të jenë të disponueshme dhe disa aplikacione mund të kenë gabime të fshehura gjatë funksionimit.

Patroni

Pra, si funksionon Patroni? Zhvilluesit nuk e rishpikën rrotën dhe propozuan përdorimin e një prej zgjidhjeve të provuara DCS si bazë. Të gjitha çështjet me sinkronizimin e konfigurimeve, zgjedhjen e liderit dhe kuorumin i janë lënë atij. Ne zgjodhëm etcd për këtë.

Më pas, Patroni merret me aplikimin e saktë të të gjitha cilësimeve në PostgreSQL dhe cilësimet e replikimit, si dhe ekzekutimin e komandave në switchover dhe failover (d.m.th., ndërrimi i rregullt dhe emergjent i masterit). Në mënyrë të veçantë në renë kompjuterike MCS, ju mund të krijoni një grup të një masteri, një kopje sinkrone dhe një ose më shumë kopje asinkrone. Prania e një kopjeje sinkrone siguron sigurinë e të dhënave në të paktën 2 serverë, dhe është kjo kopje që do të jetë "master kandidati" kryesor.

Meqenëse etcd është vendosur në të njëjtët serverë, numri i rekomanduar i serverëve është 3 ose 5 për kuorum optimal. Një grup i tillë shkallëzohet horizontalisht për lexim (kam shkruar më lart për shkallëzimin për të shkruar). Sidoqoftë, kini parasysh se kopjet asinkrone janë të prirura për të vonuar, veçanërisht nën ngarkesa të larta.

Përdorimi i kopjeve të tilla të leximit (gatishmëria e nxehtë) justifikohet për detyra raportimi ose analitike dhe lehtëson ngarkesën në serverin kryesor.

Nëse dëshironi të bëni vetë një grup të tillë, do t'ju duhet:

  • përgatitni 3 ose më shumë serverë, konfiguroni adresimin IP dhe rregullat e murit të zjarrit ndërmjet tyre;
  • instaloni paketa për shërbimet etcd, Patroni, PostgreSQL;
  • konfiguroni grupin etcd;
  • konfiguroni shërbimin patroni për të punuar me PostgreSQL.

Kjo do të thotë, në total, duhet të kompozoni saktë një duzinë skedarësh konfigurimi dhe të mos bëni gabim askund. Për këtë ju duhet patjetër të përdorni një mjet të menaxhimit të konfigurimit, siç është Ansible, për shembull. Megjithatë, nuk ka ende një balancues shumë të disponueshëm TCP. Bërja e tij është një punë më vete.

Për ata që kanë nevojë për një grup të gatshëm, por nuk duan të ndërhyjnë me të gjitha këto, ne u përpoqëm të thjeshtojmë jetën dhe bëmë një grup të gatshëm në Patroni në renë tonë, ju mund ta provoni atë falas. Përveç vetë grupit, ne bëmë:

  • Balancuesi TCP; në porte të ndryshme ajo gjithmonë tregon për master aktual, kopje sinkron ose asinkron, përkatësisht;
  • API për ndërrimin e masterit aktiv Patroni.

Ato mund të aksesohen nëpërmjet API-së së resë kompjuterike MCS dhe konsolës së uebit.

demonstrim

Për të testuar aftësitë e një grupi PostgreSQL në cloud MCS, le të shohim se si sillet një aplikacion i drejtpërdrejtë në rast të problemeve me DBMS.

Më poshtë është kodi për një aplikacion që do të regjistrojë ngjarje artificiale dhe do ta raportojë atë në ekran. Në rast gabimesh, ai do ta raportojë këtë dhe do të vazhdojë punën e tij në një unazë derisa ta ndalojmë atë me kombinimin 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")

Aplikacioni kërkon që PostgreSQL të funksionojë. Le të krijojmë një grup në cloud MCS duke përdorur API. Në një terminal të rregullt, ku ndryshorja OS_TOKEN përmban një shenjë për të hyrë në API (mund të merret me komandën openstack token issue), ne do të shtypim komandat e mëposhtme:

Krijo një grup:

cat <<EОF > 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

Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Kur grupi kalon në statusin AKTIVE, të gjitha fushat do të marrin vlerat aktuale - grupi është gati.

Në GUI:

Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Le të përpiqemi të lidhemi dhe të krijojmë një tabelë:

psql -h 89.208.87.38 -U admin -d myproddb
Password for user admin:
psql (11.1, server 10.7)
Type "help" for 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=>

Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Në aplikacion do të tregojmë cilësimet aktuale për t'u lidhur me PostgreSQL. Ne do të specifikojmë adresën e balancuesit TCP, duke eliminuar kështu nevojën për të kaluar manualisht në adresën kryesore. Le ta nisim. Siç mund ta shihni, ngjarjet janë regjistruar me sukses në bazën e të dhënave.

Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Kalimi kryesor i planifikuar

Tani le të testojmë funksionimin e aplikacionit tonë gjatë një ndërprerësi kryesor të planifikuar:

Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Ne po monitorojmë aplikacionin. Ne shohim që aplikacioni është me të vërtetë i ndërprerë, por duhen vetëm disa sekonda, në këtë rast të veçantë, maksimumi 9.

Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Përplasje me makinë

Tani le të përpiqemi të simulojmë përplasjen e një makine virtuale, master aktual. Ju thjesht mund të fikni makinën virtuale përmes ndërfaqes Horizon, por kjo do të ishte një mbyllje e rregullt. Një kalim i tillë do të përpunohet nga të gjitha shërbimet, përfshirë Patroni.

Ne kemi nevojë për një mbyllje të paparashikueshme. Prandaj, i kërkova administratorëve tanë të mbyllin makinën virtuale - master aktual - në një mënyrë jo standarde për qëllime testimi.

Si ndërtuam një grup të besueshëm PostgreSQL në Patroni

Në të njëjtën kohë, aplikacioni ynë vazhdoi të funksionojë. Natyrisht, një ndërrim i tillë urgjent i masterit nuk mund të kalojë pa u vënë re.

2019-03-29 10:45:56.071234
Connection opened to PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logged a value, overall count: 453
Connection closed
2019-03-29 10:45:59.205463
Connection opened to PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logged a value, overall count: 454

Connection closed
2019-03-29 10:46:02.661440
Error while connecting to PostgreSQL server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.

Caught error:
 local variable 'connection' referenced before assignment
……………………………………………………….. - здесь какое-то количество ошибок
2019-03-29 10:46:30.930445
Error while connecting to PostgreSQL server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.

Caught error:
 local variable 'connection' referenced before assignment
2019-03-29 10:46:31.954399
Connection opened to PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logged a value, overall count: 455
Connection closed
2019-03-29 10:46:35.409800
Connection opened to PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logged a value, overall count: 456
Connection closed
^Cexit

Siç mund ta shihni, aplikacioni ishte në gjendje të vazhdonte punën e tij në më pak se 30 sekonda. Po, një numër i caktuar përdoruesish të shërbimit do të kenë kohë të vërejnë probleme. Sidoqoftë, ky është një dështim serioz i serverit; kjo nuk ndodh shumë shpesh. Në këtë rast, një person (administrator) vështirë se do të kishte pasur kohë të reagonte aq shpejt, përveç nëse ai ishte ulur në tastierë gati me një skenar komutues.

Prodhim

Më duket se një grup i tillë ofron një avantazh të jashtëzakonshëm për administratorët. Në fakt, prishjet dhe dështimet serioze të serverëve të bazës së të dhënave nuk do të jenë të dukshme për aplikacionin dhe, në përputhje me rrethanat, për përdoruesit. Nuk do të duhet të rregulloni asgjë me nxitim dhe të kaloni në konfigurime të përkohshme, serverë, etj. Dhe nëse një zgjidhje e tillë përdoret si një shërbim i gatshëm në cloud, atëherë nuk do të keni nevojë të humbni kohë për ta përgatitur atë. Do të jetë e mundur të bëni diçka më interesante.

Burimi: www.habr.com

Bleni një host të besueshëm për faqet me mbrojtje DDoS, serverë VPS VDS 🔥 Bleni hosting të besueshëm të faqeve të internetit me mbrojtje DDoS, servera VPS VDS | ProHoster