Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Indledning

For noget tid siden fik jeg til opgave at udvikle en failover-klynge til PostgreSQL, der opererer i flere datacentre forbundet med fiber inden for samme by og er i stand til at modstå fejl (for eksempel blackout) af ét datacenter. Som en software, der er ansvarlig for fejltolerance, valgte jeg Pacemaker, fordi dette er den officielle løsning fra RedHat til oprettelse af failover-klynger. Det er godt, fordi RedHat giver support til det, og fordi denne løsning er universel (modulær). Med dens hjælp vil det være muligt at give fejltolerance ikke kun for PostgreSQL, men også for andre tjenester, enten ved at bruge standardmoduler eller oprette dem til specifikke behov.

Til denne beslutning opstod et rimeligt spørgsmål: hvor fejltolerant vil en failover-klynge være? For at undersøge dette udviklede jeg en testbænk, der simulerer forskellige fejl på klyngens noder, venter på gendannelse, gendanner den fejlslagne node og fortsætter testningen i en sløjfe. I starten hed dette projekt hapgsql, men med tiden kedede jeg mig med navnet, som kun har én vokal. Derfor begyndte jeg at navngive fejltolerante databaser (og flydende IP'er, der peger på dem) krogan (en karakter fra et computerspil, hvor alle vigtige organer er duplikeret), og noder, klynger og selve projektet er tuchanka (planeten hvor kroganerne bor).

Ledelsen har nu godkendt åbne et projekt for open source-fællesskabet under MIT-licensen. README vil snart blive oversat til engelsk (fordi Pacemaker- og PostgreSQL-udviklerne forventes at være hovedforbrugerne), og jeg besluttede at udgive den gamle russiske version af README (delvis) i form af denne artikel.

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Klynger er implementeret på virtuelle maskiner VirtualBox. I alt vil 12 virtuelle maskiner blive implementeret (36GiB i alt), som danner 4 failover-klynger (forskellige muligheder). De første to klynger består af to PostgreSQL-servere placeret i forskellige datacentre og en fælles server vidne c kvorumsanordning (hostet på en billig virtuel maskine i et tredje datacenter), der løser usikkerhed 50% / 50%ved at afgive sin stemme. Den tredje klynge i tre datacentre: en master, to slaver, nr kvorumsanordning. Den fjerde klynge består af fire PostgreSQL-servere, to pr. datacenter: en master, resten er replikaer og bruger også vidne c kvorumsanordning. Den fjerde overlever fejlen på to servere eller et datacenter. Denne løsning kan om nødvendigt skaleres op til flere replikaer.

Tidsservice ntpd også omkonfigureret til fejltolerance, men den bruger metoden til ntpd (forældreløs tilstand). Delt server vidne fungerer som en central NTP-server, der distribuerer sin tid til alle klynger og synkroniserer derved alle servere med hinanden. Hvis vidne fejler eller viser sig at være isoleret, så vil en af ​​klyngeserverne (inden for klyngen) begynde at distribuere sin tid. Auxiliary caching HTTP-proxy også hævet til vidne, med dens hjælp har andre virtuelle maskiner adgang til Yum-lagre. I virkeligheden vil tjenester som nøjagtig tid og proxy højst sandsynligt blive hostet på dedikerede servere, og i standen de er hostet på vidne kun for at spare antallet af virtuelle maskiner og plads.

versioner

v0. Virker med CentOS 7 og PostgreSQL 11 på VirtualBox 6.1.

Klyngestruktur

Alle klynger er designet til at være placeret i flere datacentre, samlet i ét fladt netværk og skal modstå fejl eller netværksisolering af ét datacenter. Derfor er umuligt bruge til at beskytte mod split-hjerne standard Pacemaker-teknologi kaldet STONITH (Skyd den anden knude i hovedet) eller hegn. Dens essens: Hvis knudepunkterne i klyngen begynder at have mistanke om, at der er noget galt med en eller anden knude, reagerer den ikke eller opfører sig forkert, så slår de den med magt fra "eksterne" enheder, for eksempel et IPMI- eller UPS-kontrolkort. Men dette vil kun fungere i tilfælde, hvor de fortsætter med at arbejde med en enkelt fejl på IPMI-serveren eller UPS'en. Den planlægger også at beskytte mod en meget mere katastrofal fejl, når hele datacentret svigter (f.eks. er strømløs). Og med sådan et afslag, alt stonith-enheder (IPMI, UPS osv.) virker heller ikke.

I stedet er systemet baseret på ideen om et kvorum. Alle noder har en stemme, og kun dem, der ser mere end halvdelen af ​​alle noder, kan arbejde. Dette tal "halv + 1" kaldes kvorum. Hvis quorumet ikke er nået, så beslutter noden, at den er i netværksisolation og skal slukke for sine ressourcer, dvs. sådan er det split-hjerne beskyttelse. Hvis softwaren, der er ansvarlig for denne adfærd, ikke virker, så burde en vagthund, for eksempel baseret på IPMI, fungere.

Hvis antallet af noder er lige (en klynge i to datacentre), så kan den såkaldte usikkerhed opstå 50% / 50% (fifty fifty) når netværksisolering deler klyngen nøjagtigt i to. Derfor tilføjes det for et lige antal noder kvorumsanordning - en krævende dæmon, der kan køres på den billigste virtuelle maskine i det tredje datacenter. Han giver sin stemme til et af segmenterne (som han ser), og løser derved 50%/50% usikkerheden. Den server, hvor kvorumsenheden vil køre, ringede jeg til vidne (terminologi fra repmgr, jeg kunne lide det).

Ressourcer kan flyttes fra sted til sted, for eksempel fra defekte servere til servere, der kan serviceres, eller efter kommando af systemadministratorer. For at kunderne skal vide, hvor de ressourcer, de har brug for, er placeret (hvor skal de oprette forbindelse?), flydende IP (flydende IP). Det er de IP'er, som Pacemaker kan flytte rundt på noderne (alt er i et fladt netværk). Hver af dem symboliserer en ressource (tjeneste) og vil være placeret, hvor du skal oprette forbindelse for at få adgang til denne tjeneste (i vores tilfælde databasen).

Tuchanka1 (komprimeret skema)

Struktur

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Tanken var, at vi har mange små databaser med lav belastning, for hvilke det er urentabelt at opretholde en dedikeret slaveserver i hot standby-tilstand til skrivebeskyttede transaktioner (der er ikke behov for et sådant spild af ressourcer).

Hvert datacenter har én server. Hver server har to PostgreSQL-instanser (i PostgreSQL-terminologi kaldes de clusters, men for at undgå forvirring vil jeg kalde dem instanser (i analogi med andre databaser), og jeg vil kun kalde Pacemaker-clusters clusters). Én instans fungerer i mastertilstand, og kun den leverer tjenester (kun float IP fører til den). Den anden instans fungerer som en slave for det andet datacenter og vil kun levere tjenester, hvis masteren svigter. Da det meste af tiden kun en af ​​de to instanser (masteren) vil levere tjenester (udføre anmodninger), er alle serverressourcer optimeret til masteren (hukommelsen allokeres til shared_buffers cachen osv.), men således at den anden instans har også nok ressourcer (omend til ikke-optimalt arbejde gennem filsystemets cache), hvis et af datacentrene svigter. Slaven leverer ikke tjenester (udfører ikke skrivebeskyttede anmodninger) under normal klyngedrift, så der er ingen krig om ressourcer med masteren på den samme maskine.

I tilfælde af to knudepunkter er fejltolerance kun mulig med asynkron replikering, da med synkron replikering vil svigt af slaven føre til standsning af masteren.

manglende vidne

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

manglende vidne (kvorumsanordning) Jeg vil kun overveje for Tuchanka1-klyngen, den samme historie vil være med alle de andre. Hvis vidnet fejler, vil intet ændre sig i klyngestrukturen, alt vil fortsætte med at fungere på samme måde, som det fungerede. Men kvorummet bliver 2 ud af 3, og derfor vil enhver næste fiasko være fatal for klyngen. Det skal stadig gøres akut.

Afvisning Tuchanka1

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Fejl i et af datacentrene til Tuchanka1. I dette tilfælde vidne afgiver sin stemme til den anden knude i det andet datacenter. Der bliver den tidligere slave til en master, som et resultat, begge mastere arbejder på den samme server, og begge deres float-IP'er peger på dem.

Tuchanka2 (klassisk)

Struktur

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Det klassiske skema med to noder. Mesteren arbejder på den ene, slaven arbejder på den anden. Begge kan udføre anmodninger (slaven er kun skrivebeskyttet), så begge peges på af float-IP: krogan2 er masteren, krogan2s1 er slaven. Både masteren og slaven vil have fejltolerance.

I tilfælde af to noder er fejltolerance kun mulig med asynkron replikering, fordi med synkron replikering vil fejlen i slaven føre til stop af masteren.

Afvisning Tuchanka2

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Hvis et af datacentrene svigter vidne stemme på den anden. På det eneste fungerende datacenter vil masteren blive hævet, og begge float-IP'er vil pege på den: master og slave. Naturligvis skal instansen konfigureres på en sådan måde, at den har tilstrækkelige ressourcer (forbindelsesgrænser osv.) til samtidig at acceptere alle forbindelser og anmodninger fra master og slave float IP. Det vil sige, at den under normal drift skal have en tilstrækkelig margin til grænser.

Tuchanka4 (mange slaver)

Struktur

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Allerede en anden yderlighed. Der er databaser, der har mange skrivebeskyttede anmodninger (et typisk tilfælde af et højt belastet websted). Tuchanka4 er en situation, hvor der kan være tre eller flere slaver til at håndtere sådanne anmodninger, men stadig ikke for mange. Med et meget stort antal slaver vil det være nødvendigt at opfinde et hierarkisk replikeringssystem. I minimumstilfældet (på billedet) har hvert af de to datacentre to servere, som hver har en PostgreSQL-instans.

Et andet træk ved denne ordning er, at det allerede er muligt at organisere én synkron replikering her. Den er konfigureret til at replikere, hvis det er muligt, til et andet datacenter og ikke til en replika i samme datacenter som masteren. Masteren og hver slave er angivet med en float IP. For godt, mellem slaverne vil det være nødvendigt at foretage en form for balancering af anmodninger sql proxyfor eksempel på klientsiden. Forskellige typer klienter kan kræve forskellige typer af sql proxy, og kun klientudviklerne ved, hvem der har brug for hvilken. Denne funktionalitet kan implementeres enten af ​​en ekstern dæmon eller af et klientbibliotek (forbindelsespulje) osv. Alt dette ligger uden for rækkevidden af ​​database-failover-klyngen (failover SQL proxy kan implementeres uafhængigt sammen med klient-failover).

Afvisning Tuchanka4

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Hvis et datacenter (dvs. to servere) fejler, stemmer vidne for det andet. Som et resultat arbejder to servere i det andet datacenter: masteren arbejder på den ene, og master float IP peger på den (for at modtage læse-skrive-anmodninger); og en slave med synkron replikering kører på den anden server, og en af ​​slave-float-IP'erne peger på den (for skrivebeskyttede anmodninger).

Den første ting at bemærke: ikke alle slave-float-IP'er fungerer, men kun én. Og for at kunne arbejde korrekt med det, vil det være nødvendigt at sql proxy omdirigeret alle anmodninger til den eneste tilbageværende float-IP; og hvis sql proxy nej, du kan liste alle float IP-slaver adskilt af kommaer i forbindelses-URL'en. I så fald med libpq forbindelsen vil være til den første fungerende IP, som det sker i det automatiske testsystem. Måske i andre biblioteker, for eksempel JDBC, vil dette ikke fungere og er nødvendigt sql proxy. Dette gøres, fordi float IP for slaver er forbudt at stige samtidigt på én server, så de er jævnt fordelt på slaveservere, hvis der er flere af dem.

For det andet: Selv i tilfælde af et datacenterfejl vil synkron replikering blive opretholdt. Og selvom der opstår en sekundær fejl, dvs. en af ​​de to servere fejler i det resterende datacenter, vil klyngen, selvom den holder op med at levere tjenester, stadig beholde information om alle de forpligtede transaktioner, som den bekræftede forpligtelsen for (der vil være ingen tabsinformation om sekundær fejl).

Tuchanka3 (3 datacentre)

Struktur

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Dette er en klynge til en situation, hvor der er tre fuldt fungerende datacentre, som hver har en fuldt fungerende databaseserver. I dette tilfælde kvorumsanordning ikke brug for. En master arbejder i et datacenter, og slaver arbejder i de to andre. Replikering er synkron, skriv ANY (slave1, slave2), det vil sige, at klienten modtager en commit-bekræftelse, når nogen af ​​slaverne er den første til at svare, at han har accepteret commit. Ressourcer peges på af en float IP for master og to for slaver. I modsætning til Tuchanka4 er alle tre float-IP'er fejltolerante. For at balancere skrivebeskyttede SQL-forespørgsler kan du bruge sql proxy (med separat fejltolerance), eller tildel en slave-IP float til halvdelen af ​​klienterne og den anden til den anden halvdel.

Afvisning Tuchanka3

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Hvis et af datacentrene svigter, er der to tilbage. I den ene hæves master- og float-IP'en fra masteren, i den anden hæves slave- og begge slave-float-IP'er (instansen skal have en dobbelt ressourcemargen for at acceptere alle forbindelser fra begge slave-float-IP'er). Synkron replikering mellem mastere og slaver. Desuden vil klyngen gemme oplysninger om begåede og bekræftede transaktioner (der vil ikke være noget tab af information) i tilfælde af ødelæggelse af to datacentre (hvis de ikke ødelægges på samme tid).

Jeg besluttede ikke at inkludere en detaljeret beskrivelse af filstrukturen og implementeringen. Hvis du vil lege, kan du læse alt dette i README. Jeg giver kun en beskrivelse af automatisk test.

Automatisk testsystem

For at kontrollere fejltolerancen af ​​klynger med efterligning af forskellige fejl blev der lavet et automatisk testsystem. Lanceret af et script test/failure. Scriptet kan tage antallet af klynger, som du vil teste, som parametre. For eksempel denne kommando:

test/failure 2 3

vil kun teste den anden og tredje klynge. Hvis parametre ikke er specificeret, testes alle klynger. Alle klynger testes parallelt, og resultatet vises i tmux-panelet. Tmux bruger en dedikeret tmux-server, så scriptet kan køres fra under standard-tmux, hvilket resulterer i en indlejret tmux. Jeg anbefaler at bruge terminalen i et stort vindue og med en lille skrifttype. Inden testen starter, rulles alle virtuelle maskiner tilbage til et øjebliksbillede på det tidspunkt, hvor scriptet slutter setup.

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Terminalen er opdelt i kolonner i henhold til antallet af testede klynger, som standard (i skærmbilledet) er der fire af dem. Jeg vil beskrive indholdet af kolonnerne med Tuchanka2 som eksempel. Panelerne på skærmbilledet er nummererede:

  1. Det er her teststatistikker vises. Højttalere:
    • svigt — navnet på den test (funktion i scriptet), der emulerer fejlen.
    • reaktion — den aritmetiske middeltid i sekunder, for hvilken klyngen har genoprettet sin ydeevne. Det måles fra begyndelsen af ​​scriptet, der emulerer fejlen, og indtil det øjeblik, hvor klyngen genopretter sin sundhed og er i stand til at fortsætte med at levere tjenester. Hvis tiden er meget kort, for eksempel seks sekunder (dette sker i klynger med flere slaver (Tuchanka3 og Tuchanka4)), betyder det, at fejlen endte på en asynkron slave og ikke påvirkede ydeevnen på nogen måde, der var ingen klyngetilstandsafbrydere.
    • afvigelse - viser spredningen (nøjagtigheden) af værdien reaktion efter standardafvigelsesmetoden.
    • tælle Hvor mange gange denne test er blevet udført.
  2. En kort log giver dig mulighed for at evaluere, hvad klyngen gør i øjeblikket. Iterationens (test-) nummer, tidsstemplet og operationsnavnet vises. For lang udførelse (> 5 minutter) indikerer en form for problem.
  3. hjerte (hjerte) er det aktuelle tidspunkt. Til visuel præstationsvurdering mestre den aktuelle tid skrives konstant til dens tabel ved hjælp af masterens float-IP. Hvis det lykkes, vises resultatet i dette panel.
  4. slå (puls) - "aktuel tid", som tidligere blev optaget af scriptet hjerte at mestre, læs nu fra slave gennem sin flydende IP. Giver dig mulighed for visuelt at vurdere ydeevnen af ​​en slave og replikering. Der er ingen slaver med float IP i Tuchanka1 (der er ingen slaver, der leverer tjenester), men der er to forekomster (DB), så det vil ikke blive vist her slåOg hjerte anden instans.
  5. Overvågning af klyngens tilstand ved hjælp af hjælpeprogrammet pcs mon. Viser strukturen, fordelingen af ​​ressourcer efter noder og anden nyttig information.
  6. Den viser systemovervågning fra hver virtuel klyngemaskine. Der kan være flere sådanne paneler - hvor mange virtuelle maskiner har klyngen. To grafer CPU-belastning (to processorer i virtuelle maskiner), virtuel maskine navn, Systembelastning (kaldet Load Average, fordi det var i gennemsnit over 5, 10 og 15 minutter), procesdata og hukommelsesallokering.
  7. Sporing af scriptet, der udfører testene. I tilfælde af en funktionsfejl - en pludselig afbrydelse af arbejdet eller en endeløs ventecyklus - her kan du se årsagen til denne adfærd.

Test udføres i to trin. Først gennemgår scriptet alle typer tests og vælger tilfældigt en virtuel maskine, som denne test skal anvendes på. Derefter udføres en endeløs testcyklus, virtuelle maskiner og en funktionsfejl vælges tilfældigt hver gang. Pludselig afbrydelse af testscriptet (nederste panel) eller en endeløs venteløkke på noget (> 5 minutter tid til at fuldføre én operation, dette kan ses i sporet) indikerer, at nogle af testene på denne klynge har mislykkedes.

Hver test består af følgende operationer:

  1. Start af en funktion, der emulerer en fejl.
  2. Klar? - venter på genoprettelse af klyngens helbred (når alle tjenester er udført).
  3. Timeout for klyngendannelse vises (reaktion).
  4. Fix - klyngen er "repareret". Hvorefter den skulle vende tilbage til en fuldt funktionsdygtig tilstand og klar til næste fejl.

Her er en liste over tests med en beskrivelse af, hvad de gør:

  • Gaffelbombe: Skaber "Out of memory" med en gaffelbombe.
  • Løbet tør for plads: harddisken er fuld. Men testen er ret symbolsk, med den ubetydelige belastning, der skabes under test, når harddisken løber over, svigter PostgreSQL normalt ikke.
  • Postgres-DRÆB: dræber PostgreSQL med kommandoen killall -KILL postgres.
  • postgres-STOP: hænger PostgreSQL med kommandoen killall -STOP postgres.
  • Sluk: "deaktiverer" den virtuelle maskine med kommandoen VBoxManage controlvm "виртуалка" poweroff.
  • Nulstil: genindlæser den virtuelle maskine med kommandoen VBoxManage controlvm "виртуалка" reset.
  • SBD STOP: suspenderer SBD-dæmonen med kommandoen killall -STOP sbd.
  • Lukke ned: via SSH sender en kommando til den virtuelle maskine systemctl poweroff, lukker systemet elegant ned.
  • fjerne linket: netværksisolering, kommando VBoxManage controlvm "виртуалка" setlinkstate1 off.

Afslut test enten med standard tmux kommandoen "kill-window" ctrl-b&, eller ved kommandoen "detach-client" ctrl-bd: samtidig afsluttes testen, tmux lukkes, virtuelle maskiner er slukket.

Problemer identificeret under test

  • I dette øjeblik vagthund daemon sbd håndterer at stoppe observerede dæmoner, men ikke fryse dem. Og som følge heraf er fejlfunktionerne forkert løst, hvilket kun fører til en frysning Corosync и Pacemaker, men ikke hængende SBD. Til check Corosync har allerede PR # 83 (på GitHub kl SBD), accepteret i filialen Master. De lovede (i PR#83), at der ville være noget lignende for Pacemaker, det håber jeg pr Redhat 8 vil gøre. Men sådanne "fejl" er spekulative, let efterlignede kunstigt ved hjælp af f.eks. killall -STOP corosyncmen mødes aldrig i det virkelige liv.

  • У Pacemaker i versionen til 7 CentOS forkert indstillet sync_timeout у kvorumsanordning, som resultat hvis en node fejlede, genstartede den anden node med en vis sandsynlighed, hvortil mesteren skulle flytte. Hærdet ved forstørrelse sync_timeout у kvorumsanordning under implementering (i script setup/setup1). Denne ændring blev ikke accepteret af udviklerne Pacemaker, i stedet lovede de at omarbejde infrastrukturen på en sådan måde (i en eller anden ubestemt fremtid), at denne timeout beregnes automatisk.

  • Hvis du under databasekonfigurationen har angivet det LC_MESSAGES (tekstbeskeder) Unicode kan bruges f.eks. ru_RU.UTF-8, derefter ved opstart Postgres i et miljø, hvor lokaliteten ikke er UTF-8, f.eks. i et tomt miljø (her pacemaker+pgsqlms(paf) starter Postgres), At i loggen i stedet for UTF-8 bogstaver vil der være spørgsmålstegn. PostgreSQL-udviklerne blev aldrig enige om, hvad de skulle gøre i dette tilfælde. Det koster, skal du sætte LC_MESSAGES=en_US.UTF-8 når du konfigurerer (opretter) en DB-instans.

  • Hvis wal_receiver_timeout er indstillet (som standard er det 60s), så når du tester PostgreSQL-STOP på masteren i tuchanka3 og tuchanka4 klynger Replikering opretter ikke forbindelse til en ny master. Replikering der er synkron, så ikke kun slaven stopper, men også den nye master. Fås ved at indstille wal_receiver_timeout=0 ved konfiguration af PostgreSQL.

  • Jeg observerede lejlighedsvis PostgreSQL-replikation hængende i ForkBomb-testen (hukommelsesoverløb). Efter ForkBomb kan slaver nogle gange ikke oprette forbindelse til den nye master igen. Jeg har kun set dette i tuchanka3 og tuchanka4 klynger, hvor masteren hang på grund af det faktum, at replikering er synkron. Problemet gik over af sig selv efter noget lang tid (ca. to timer). Mere forskning er nødvendig for at løse dette. Symptomerne ligner den tidligere fejl, som er forårsaget af en anden årsag, men med de samme konsekvenser.

Krogan billede taget fra afvigende Art med forfatterens tilladelse:

Modellering af failover-klynger baseret på PostgreSQL og Pacemaker

Kilde: www.habr.com

Tilføj en kommentar