Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Innledning

For en tid siden fikk jeg i oppgave å utvikle en failover-klynge for PostgreSQL, som opererer i flere datasentre koblet sammen med optisk fiber innenfor en by, og er i stand til å motstå en feil (for eksempel blackout) i ett datasenter. Som programvaren som er ansvarlig for feiltoleranse, valgte jeg Pacemakerfordi dette er den offisielle løsningen fra RedHat for å lage failover-klynger. Det er bra fordi RedHat gir støtte for det, og fordi denne løsningen er universell (modulær). Med dens hjelp vil det være mulig å sikre feiltoleranse ikke bare for PostgreSQL, men også for andre tjenester, enten ved å bruke standardmoduler eller lage dem for spesifikke behov.

Denne avgjørelsen reiste et rimelig spørsmål: hvor feiltolerant vil en failover-klynge være? For å undersøke dette utviklet jeg en testbenk som simulerer ulike feil på klyngenodene, venter på at tjenesten skal gjenopprettes, gjenoppretter den mislykkede noden og fortsetter å teste i en sløyfe. Dette prosjektet ble opprinnelig kalt hapgsql, men etter hvert ble jeg lei av navnet, som bare hadde én vokal. Derfor begynte jeg å kalle feiltolerante databaser (og flytende IP som peker til dem) krogan (en karakter fra et dataspill der alle viktige organer er duplisert), og noder, klynger og selve prosjektet er tuchanka (planeten der kroganene bor).

Nå har ledelsen tillatt åpne prosjektet for åpen kildekode-fellesskapet under MIT-lisensen. README vil snart bli oversatt til engelsk (fordi det forventes at hovedforbrukerne vil være Pacemaker og PostgreSQL-utviklere), og jeg bestemte meg for å presentere den gamle russiske versjonen av README (delvis) i form av denne artikkelen.

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Klynger distribueres på virtuelle maskiner VirtualBox. Totalt 12 virtuelle maskiner (36GiB totalt) vil bli distribuert, som danner 4 feiltolerante klynger (ulike alternativer). De to første klyngene består av to PostgreSQL-servere, som er plassert i forskjellige datasentre, og en felles server Vitne c quorumsenhet (hostet på en billig virtuell maskin i et tredje datasenter), noe som løser usikkerhet 50% / 50%, gi din stemme til et av partiene. Tredje klynge i tre datasentre: en master, to slaver, nei quorumsenhet. Den fjerde klyngen består av fire PostgreSQL-servere, to per datasenter: en master, resten replikaer, og bruker også Vitne c quorumsenhet. Den fjerde tåler feil på to servere eller ett datasenter. Denne løsningen kan skaleres til et større antall kopier om nødvendig.

Nøyaktig tidsservice ntpd også rekonfigurert for feiltoleranse, men den bruker selve metoden ntpd (foreldreløs modus). Delt server Vitne fungerer som en sentral NTP-server, og distribuerer tiden til alle klynger, og synkroniserer derved alle servere med hverandre. Hvis Vitne mislykkes eller blir isolert, vil en av klyngeserverne (innenfor klyngen) begynne å distribuere tiden sin. Hjelpebufring HTTP proxy også hevet til Vitne, med dens hjelp har andre virtuelle maskiner tilgang til Yum-depoter. I virkeligheten vil tjenester som nøyaktig tid og proxyer mest sannsynlig være vert på dedikerte servere, men i standen de er vert på Vitne bare for å spare antall virtuelle maskiner og plass.

versjoner

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

Klyngestruktur

Alle klynger er designet for å være plassert i flere datasentre, kombinert til ett flatt nettverk og må tåle feil eller nettverksisolering av et enkelt datasenter. Derfor er umulig bruk for beskyttelse mot delt hjerne standard Pacemaker-teknologi kalt STONITH (Skyt den andre noden i hodet) eller fekting. Dens essens: hvis nodene i klyngen begynner å mistenke at noe er galt med en node, den ikke svarer eller oppfører seg feil, slår de den av med tvang gjennom "eksterne" enheter, for eksempel et IPMI- eller UPS-kontrollkort . Men dette vil bare fungere i tilfeller der IPMI- eller UPS-serveren fortsetter å fungere i tilfelle en enkelt feil. Her planlegger vi å beskytte mot en mye mer katastrofal feil, når hele datasenteret svikter (for eksempel mister strøm). Og med et slikt avslag, alt stonith-enheter (IPMI, UPS, etc.) vil heller ikke fungere.

I stedet er systemet basert på ideen om quorum. Alle noder har en stemme, og bare de som kan se mer enn halvparten av alle noder kan fungere. Denne mengden "halv + 1" kalles quorum. Hvis quorum ikke er nådd, bestemmer noden at den er i nettverksisolasjon og må slå av ressursene sine, dvs. dette er hva det er delt hjernebeskyttelse. Hvis programvaren som er ansvarlig for denne oppførselen ikke fungerer, må en vakthund, for eksempel basert på IPMI, jobbe.

Hvis antall noder er partall (en klynge i to datasentre), kan det oppstå såkalt usikkerhet 50% / 50% (femti femti) når nettverksisolasjon deler klyngen nøyaktig i to. Derfor, for et jevnt antall noder, legger vi til quorumsenhet er en lite krevende demon som kan lanseres på den billigste virtuelle maskinen i et tredje datasenter. Han gir sin stemme til et av segmentene (som han ser), og løser dermed 50%/50% usikkerheten. Jeg navnga serveren som quorumsenheten vil bli lansert på Vitne (terminologi fra repmgr, jeg likte det).

Ressurser kan flyttes fra sted til sted, for eksempel fra defekte servere til friske, eller etter kommando fra systemadministratorer. Slik at kundene vet hvor ressursene de trenger er plassert (hvor skal de koble til?), flytende IP (flytende IP). Dette er IP-er som Pacemaker kan flytte rundt på noder (alt er på et flatt nettverk). Hver av dem symboliserer en ressurs (tjeneste) og vil være plassert der du må koble til for å få tilgang til denne tjenesten (i vårt tilfelle en database).

Tuchanka1 (krets med komprimering)

Struktur

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Tanken var at vi har mange små databaser med lav belastning, som det er ulønnsomt å opprettholde en dedikert slaveserver i hot standby-modus for skrivebeskyttede transaksjoner (det er ikke behov for slikt sløsing med ressurser).

Hvert datasenter har én server. Hver server har to PostgreSQL-instanser (i PostgreSQL-terminologi kalles de clusters, men for å unngå forvirring vil jeg kalle dem instanser (i analogi med andre databaser), og jeg vil kun kalle Pacemaker clusters clusters). En forekomst opererer i mastermodus, og bare den leverer tjenester (kun flytende IP fører til den). Den andre forekomsten fungerer som en slave for det andre datasenteret, og vil kun tilby tjenester hvis masteren mislykkes. Siden det meste av tiden bare én av to forekomster (masteren) vil levere tjenester (utføre forespørsler), er alle serverressurser optimert for masteren (minne er allokert for shared_buffers cachen, etc.), men slik at den andre forekomsten har også nok ressurser (om enn for suboptimal drift gjennom filsystembufferen) i tilfelle feil i et av datasentrene. Slaven leverer ikke tjenester (utfører ikke skrivebeskyttede forespørsler) under normal drift av klyngen, slik at det ikke er krig om ressurser med masteren på samme maskin.

Når det gjelder to noder, er feiltoleranse bare mulig med asynkron replikering, siden med synkron replikering vil feilen til en slave føre til stopp av masteren.

Unnlatelse av å vitne

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Unnlatelse av å vitne (quorumsenhet) Jeg vil kun vurdere Tuchanka1-klyngen, med alle de andre vil det være den samme historien. Hvis vitne mislykkes, vil ingenting endre seg i klyngestrukturen, alt vil fortsette å fungere på samme måte som det gjorde. Men quorumet vil bli 2 av 3, og derfor vil enhver påfølgende fiasko være fatal for klyngen. Det vil fortsatt måtte fikses snarest.

Tuchanka1 avslag

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Feil i et av datasentrene for Tuchanka1. I dette tilfellet Vitne avgir sin stemme til en andre node i et andre datasenter. Der blir den tidligere slaven til en master, som et resultat av at begge masterne jobber på samme server og begge deres flytende IP-er peker til dem.

Tuchanka2 (klassisk)

Struktur

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Klassisk skjema med to noder. Mesteren jobber på den ene, slaven på den andre. Begge kan utføre forespørsler (slaven er skrivebeskyttet), så begge er pekt på med flytende IP: krogan2 er masteren, krogan2s1 er slaven. Både master og slave vil ha feiltoleranse.

I tilfelle av to noder er feiltoleranse bare mulig med asynkron replikering, fordi med synkron replikering vil feilen til slaven føre til stopp av masteren.

Tuchanka2 avslag

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Hvis et av datasentrene svikter Vitne stemmer på den andre. På det eneste fungerende datasenteret vil masteren bli hevet, og begge flytende IP-er vil peke på den: masteren og slaven. Forekomsten må selvfølgelig konfigureres på en slik måte at den har nok ressurser (tilkoblingsgrenser osv.) til å samtidig akseptere alle tilkoblinger og forespørsler fra master og slave float IP. Det vil si at den under normal drift skal ha tilstrekkelig tilførsel av grenser.

Tuchanka4 (mange slaver)

Struktur

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Allerede en annen ytterlighet. Det er databaser som mottar mange skrivebeskyttede forespørsler (et typisk tilfelle av et nettsted med høy belastning). Tuchanka4 er en situasjon der det kan være tre eller flere slaver til å håndtere slike forespørsler, men fortsatt ikke for mange. Med et veldig stort antall slaver vil det være nødvendig å finne opp et hierarkisk replikeringssystem. I minimumstilfellet (på bildet) har hvert av de to datasentrene to servere, hver med en PostgreSQL-instans.

Et annet trekk ved denne ordningen er at det allerede er mulig å organisere en synkron replikering. Den er konfigurert til å replikere, hvis mulig, til et annet datasenter, i stedet for til en replika i samme datasenter som masteren. Masteren og hver slave blir pekt på av en flytende IP. Heldigvis, mellom slaver vil det være nødvendig å balansere forespørsler på en eller annen måte sql proxyfor eksempel på klientsiden. Ulike typer klienter kan kreve forskjellige typer sql proxy, og bare klientutviklere vet hvem som trenger hvilke. Denne funksjonaliteten kan implementeres enten av en ekstern demon eller av et klientbibliotek (tilkoblingspool), etc. Alt dette går utover emnet for en failover-databaseklynge (failover SQL proxy kan implementeres uavhengig, sammen med klientens feiltoleranse).

Tuchanka4 avslag

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Hvis ett datasenter (dvs. to servere) svikter, stemmer vitne for det andre. Som et resultat er det to servere som kjører i det andre datasenteret: den ene kjører en master, og master-float-IP-en peker til den (for å motta lese-skrive-forespørsler); og på den andre serveren er det en slave som kjører med synkron replikering, og en av slave-float-IP-ene peker på den (for skrivebeskyttede forespørsler).

Det første å merke seg er at ikke alle slave-float-IP-er vil være arbeidere, men bare én. Og for å jobbe med det riktig vil det være nødvendig sql proxy omdirigert alle forespørsler til den eneste gjenværende flytende IP-en; og hvis sql proxy nei, da kan du liste alle flytende IP-slaver atskilt med kommaer i tilkoblings-URLen. I dette tilfellet med libpq tilkoblingen vil være til den første fungerende IP-en, dette gjøres i det automatiske testsystemet. Kanskje i andre biblioteker, for eksempel JDBC, vil dette ikke fungere og er nødvendig sql proxy. Dette gjøres fordi flytende IP-er for slaver er forbudt å heves samtidig på én server, slik at de er jevnt fordelt mellom slaveservere hvis det er flere av dem som kjører.

For det andre: selv i tilfelle datasenterfeil vil synkron replikering opprettholdes. Og selv om en sekundær feil oppstår, det vil si at en av de to serverne i det gjenværende datasenteret svikter, vil klyngen, selv om den vil slutte å levere tjenester, fortsatt beholde informasjon om alle forpliktede transaksjoner som den har gitt bekreftelse på forpliktelsen for. (det vil ikke være noen tapsinformasjon i tilfelle sekundær feil).

Tuchanka3 (3 datasentre)

Struktur

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Dette er en klynge for en situasjon der det er tre fullt fungerende datasentre, som hver har en fullt fungerende databaseserver. I dette tilfellet quorumsenhet ikke nødvendig. Ett datasenter er bemannet av en master, de to andre er bemannet av slaver. Replikering er synkron, skriv ANY (slave1, slave2), det vil si at klienten vil motta en commit-bekreftelse når noen av slavene er den første som svarer at han har akseptert commit. Ressurser indikeres med én flytende IP for masteren og to for slaver. I motsetning til Tuchanka4, er alle tre flytende IP-er feiltolerante. For å balansere skrivebeskyttede SQL-spørringer kan du bruke sql proxy (med separat feiltoleranse), eller tilordne en slave flytende IP til halvparten av klientene, og den andre halvparten til den andre.

Tuchanka3 avslag

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Hvis ett av datasentrene svikter, gjenstår to. I den ene heves master- og float-IP-en fra masteren, i den andre - slave- og begge slave-float-IP-ene (forekomsten må ha en dobbel reserve av ressurser for å akseptere alle tilkoblinger fra begge slave-float-IP-ene). Synkron replikering mellom mastere og slaver. Klyngen vil også lagre informasjon om begåtte og bekreftede transaksjoner (det vil ikke være tap av informasjon) i tilfelle ødeleggelse av to datasentre (hvis de ikke blir ødelagt samtidig).

Jeg bestemte meg for ikke å inkludere en detaljert beskrivelse av filstrukturen og distribusjonen. Alle som vil leke kan lese alt i README. Jeg gir kun en beskrivelse av automatisert testing.

Automatisk testsystem

For å teste feiltoleransen til klynger ved å simulere ulike feil, er det laget et automatisk testsystem. Lansert med manus test/failure. Skriptet kan ta som parametere antall klynger du vil teste. For eksempel denne kommandoen:

test/failure 2 3

vil bare teste den andre og tredje klyngen. Hvis parametere ikke er spesifisert, vil alle klynger bli testet. Alle klynger testes parallelt, og resultatet vises i tmux-panelet. Tmux bruker en dedikert tmux-server, så skriptet kan kjøres fra under standard tmux, noe som resulterer i en nestet tmux. Jeg anbefaler å bruke terminalen i et stort vindu og med en liten skrift. Før testingen begynner, rulles alle virtuelle maskiner tilbake til et øyeblikksbilde når skriptet fullføres setup.

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Terminalen er delt inn i kolonner i henhold til antall klynger som testes; som standard (i skjermbildet) er det fire. Jeg vil beskrive innholdet i kolonnene ved å bruke eksemplet med Tuchanka2. Panelene i skjermbildet er nummerert:

  1. Teststatistikk vises her. Kolonner:
    • svikt — navnet på testen (funksjon i skriptet) som emulerer feilen.
    • reaksjon — aritmetisk gjennomsnittstid i sekunder hvor klyngen gjenopprettet funksjonaliteten. Det måles fra starten av skriptet som emulerer en feil til øyeblikket når klyngen gjenoppretter funksjonaliteten og kan fortsette å tilby tjenester. Hvis tiden er veldig kort, for eksempel seks sekunder (dette skjer i klynger med flere slaver (Tuchanka3 og Tuchanka4)), betyr dette at feilen var på den asynkrone slaven og ikke påvirket ytelsen på noen måte; det var ingen klyngetilstandsbrytere.
    • avvik — viser spredningen (nøyaktigheten) av verdien reaksjon ved bruk av standardavviksmetoden.
    • telle – hvor mange ganger denne testen ble utført.
  2. En kort logg lar deg evaluere hva klyngen gjør for øyeblikket. Iterasjonsnummeret (testnummeret), tidsstempelet og navnet på operasjonen vises. Å kjøre for lenge (> 5 minutter) indikerer et problem.
  3. hjerte (hjerte) - gjeldende tid. For visuell vurdering av ytelse herre Den gjeldende tiden skrives konstant til tabellen ved hjelp av float IP-masteren. Hvis vellykket, vises resultatet i dette panelet.
  4. slå (puls) - "nåværende tid", som tidligere ble spilt inn av manuset hjerte å mestre, nå les fra slave via sin flytende IP. Lar deg vurdere ytelsen til slaven og replikeringen visuelt. I Tuchanka1 er det ingen slaver med flytende IP (ingen slaver som leverer tjenester), men det er to forekomster (DB), så det vil ikke bli vist her slåOg hjerte andre instans.
  5. Overvåking av klyngens helse ved hjelp av verktøyet pcs mon. Viser struktur, fordeling av ressurser på tvers av noder og annen nyttig informasjon.
  6. Systemovervåking fra hver virtuell maskin i klyngen vises her. Det kan være flere slike paneler avhengig av hvor mange virtuelle maskiner klyngen har. To grafer CPU-belastning (virtuelle maskiner har to prosessorer), virtuell maskinnavn, Systembelastning (kalt Load Average fordi det er gjennomsnittlig over 5, 10 og 15 minutter), prosessdata og minneallokering.
  7. Spor av skriptet som utfører testing. I tilfelle en funksjonsfeil - et plutselig driftsavbrudd eller en endeløs ventesyklus - her kan du se årsaken til denne oppførselen.

Testing utføres i to trinn. Først går skriptet gjennom alle typer tester, og velger tilfeldig en virtuell maskin som denne testen skal brukes på. Deretter utføres en endeløs syklus med testing, de virtuelle maskinene og feilen velges tilfeldig hver gang. Plutselig avslutning av testskriptet (nederst panel) eller en endeløs løkke med å vente på noe (> 5 minutter utførelsestid for én operasjon, dette kan sees i sporet) indikerer at noen av testene på denne klyngen har mislyktes.

Hver test består av følgende operasjoner:

  1. Start en funksjon som emulerer en feil.
  2. Klar? — venter på at klyngen skal gjenopprettes (når alle tjenester er levert).
  3. Viser klyngegjenopprettingstidsavbrudd (reaksjon).
  4. Fix - klyngen blir "reparert." Deretter skal den gå tilbake til fullt operativ tilstand og være klar for neste feil.

Her er en liste over tester med en beskrivelse av hva de gjør:

  • ForkBomb: Skaper "tom minne" ved hjelp av en gaffelbombe.
  • Tom for rom: Harddisken er full. Men testen er ganske symbolsk; med den ubetydelige belastningen som skapes under testing, mislykkes vanligvis ikke PostgreSQL når harddisken er full.
  • Postgres-KILL: dreper PostgreSQL med kommandoen killall -KILL postgres.
  • Postgres-STOPP: henger PostgreSQL-kommandoen killall -STOP postgres.
  • Slå av: "de-energizes" den virtuelle maskinen med kommandoen VBoxManage controlvm "виртуалка" poweroff.
  • Tilbakestill: overbelaster den virtuelle maskinen med kommandoen VBoxManage controlvm "виртуалка" reset.
  • SBD-STOPP: suspenderer SBD-demonen med kommandoen killall -STOP sbd.
  • Skru av: sender en kommando til den virtuelle maskinen via SSH systemctl poweroff, slår systemet seg elegant av.
  • Fjern koblingen: nettverksisolasjon, kommando VBoxManage controlvm "виртуалка" setlinkstate1 off.

Fullfører testing enten ved å bruke standard tmux-kommandoen "kill-window" Ctrl-b &, eller kommandoen "detach-client". Ctrl-b d: På dette tidspunktet avsluttes testingen, tmux lukkes, virtuelle maskiner er slått av.

Problemer identifisert under testing

  • Akkurat nå vakthund demon sbd jobber med å stoppe observerte demoner, men ikke fryse dem. Og som et resultat, feil som kun fører til frysing Corosync и Pacemaker, men ikke hengende sbd... For sjekk Corosync allerede har PR # 83 (på GitHub kl sbd), godtatt i tråden Master. De lovet (i PR#83) at det ville være noe lignende for Pacemaker, jeg håper det innen Redhat xnumx Vil gjøre. Men slike "feil" er spekulative og kan lett simuleres kunstig ved å f.eks. killall -STOP corosync, men møtes aldri i det virkelige liv.

  • У Pacemaker i versjonen for 7 CentOS feil innstilt sync_timeout у quorumsenhet, som et resultat hvis en node mislyktes, med en viss sannsynlighet startet også den andre noden på nytt, som mesteren skulle flytte til. Herdet ved utvidelse sync_timeout у quorumsenhet under distribusjon (i script setup/setup1). Denne endringen ble ikke akseptert av utviklerne Pacemaker, i stedet lovet de å redesigne infrastrukturen på en slik måte (på en uspesifisert fremtid) at denne tidsavbruddet ville bli beregnet automatisk.

  • Hvis databasekonfigurasjonen spesifiserer det LC_MESSAGES (tekstmeldinger) Unicode kan brukes, f.eks. ru_RU.UTF-8, deretter ved oppstart postgres i et miljø der lokaliteten ikke er UTF-8, si i et tomt miljø (her pacemaker+pgsqlms(paf) løper postgres), deretter loggen vil inneholde spørsmålstegn i stedet for UTF-8 bokstaver. PostgreSQL-utviklerne har ikke blitt enige om hva de skal gjøre i dette tilfellet. Det koster, du må installere LC_MESSAGES=en_US.UTF-8 når du konfigurerer (oppretter) en databaseforekomst.

  • Hvis wal_receiver_timeout er satt (som standard er det 60s), så under PostgreSQL-STOP-testen på masteren i tuchanka3- og tuchanka4-klyngene replikering kobler ikke til den nye masteren på nytt. Replikering der er synkron, så ikke bare slaven stopper, men også den nye masteren. Omgås ved å sette wal_receiver_timeout=0 når du konfigurerer PostgreSQL.

  • Noen ganger observerte jeg at replikering fryser i PostgreSQL i ForkBomb-testen (minneoverflyt). Etter ForkBomb kan det hende at slaver ikke kobler til den nye masteren igjen. Jeg har bare møtt dette i tuchanka3- og tuchanka4-klyngene, hvor masteren frøs på grunn av synkron replikering. Problemet gikk over av seg selv etter lang tid (ca. to timer). Mer forskning er nødvendig for å rette opp dette. Symptomene ligner på den forrige feilen, som er forårsaket av en annen årsak, men med de samme konsekvensene.

Krogan-bilde tatt fra avvikende kunst med tillatelse fra forfatteren:

Modellering av failover-klynger basert på PostgreSQL og Pacemaker

Kilde: www.habr.com

Legg til en kommentar