Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Introducció

Fa un temps em van donar l'encàrrec de desenvolupar un clúster de failover per PostgreSQL, que operen en diversos centres de dades connectats per fibra òptica dins d'una ciutat i capaços de suportar una fallada (per exemple, apagada) d'un centre de dades. Com a programari responsable de la tolerància a errors, vaig triar marcapassosperquè aquesta és la solució oficial de RedHat per crear clústers de failover. És bo perquè RedHat ofereix suport i perquè aquesta solució és universal (modular). Amb la seva ajuda, serà possible garantir la tolerància a errors no només de PostgreSQL, sinó també d'altres serveis, ja sigui utilitzant mòduls estàndard o creant-los per a necessitats específiques.

Aquesta decisió va plantejar una pregunta raonable: com serà de tolerant a errors un clúster de failover? Per investigar-ho, vaig desenvolupar un banc de proves que simula diversos errors als nodes del clúster, espera que es restauri el servei, recupera el node fallit i continua provant en un bucle. Aquest projecte es deia originalment hapgsql, però amb el temps em vaig avorrir del nom, que només tenia una vocal. Per tant, vaig començar a cridar bases de dades tolerants a errors (i a IP flotant apuntant-hi) krogan (un personatge d'un joc d'ordinador en el qual es dupliquen tots els òrgans importants), i els nodes, els clústers i el projecte en si són tuchanka (el planeta on viuen els krogans).

Ara la direcció ho ha permès obriu el projecte a la comunitat de codi obert sota la llicència MIT. El README es traduirà aviat a l'anglès (perquè s'espera que els principals consumidors seran desenvolupadors de Pacemaker i PostgreSQL), i vaig decidir presentar l'antiga versió russa del README (parcialment) en forma d'aquest article.

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Els clústers es despleguen a màquines virtuals VirtualBox. Es desplegaran un total de 12 màquines virtuals (36 GiB en total), que formen 4 clústers tolerants a errors (opcions diferents). Els dos primers clústers estan formats per dos servidors PostgreSQL, que es troben en diferents centres de dades, i un servidor comú Testimoni c dispositiu de quòrum (allotjat en una màquina virtual barata en un tercer centre de dades), que resol la incertesa 50% / 50%, donant el seu vot a una de les parts. Tercer clúster en tres centres de dades: un mestre, dos esclaus, no dispositiu de quòrum. El quart clúster consta de quatre servidors PostgreSQL, dos per centre de dades: un mestre, la resta rèpliques i també utilitza Testimoni c dispositiu de quòrum. El quart pot suportar la fallada de dos servidors o un centre de dades. Aquesta solució es pot escalar a un nombre més gran de rèpliques si cal.

Servei de temps precís ntpd també s'ha reconfigurat per a la tolerància a errors, però utilitza el mètode en si ntpd (mode orfe). Servidor compartit Testimoni actua com un servidor NTP central, distribuint el seu temps a tots els clústers, sincronitzant així tots els servidors entre si. Si Testimoni falla o queda aïllat, aleshores un dels servidors del clúster (dins del clúster) començarà a distribuir el seu temps. Emmagatzematge en memòria cau auxiliar Proxy HTTP també elevat a Testimoni, amb la seva ajuda, altres màquines virtuals tenen accés als repositoris Yum. En realitat, els serveis com ara l'hora precisa i els servidors intermediaris probablement s'allotgin en servidors dedicats, però a l'estand estan allotjats en Testimoni només per estalviar el nombre de màquines virtuals i espai.

Versions

v0. Funciona amb CentOS 7 i PostgreSQL 11 a VirtualBox 6.1.

Estructura de clúster

Tots els clústers estan dissenyats per situar-se en diversos centres de dades, combinats en una xarxa plana i han de suportar fallades o aïllament de la xarxa d'un únic centre de dades. Aixo es perqué és impossible utilitzar com a protecció contra cervell dividit anomenada tecnologia de marcapassos estàndard STONITH (Dispara a l'altre node al cap) o esgrima. La seva essència: si els nodes del clúster comencen a sospitar que alguna cosa no funciona amb algun node, no respon o es comporta de manera incorrecta, l'apagaran per força mitjançant dispositius "externs", per exemple, una targeta de control IPMI o UPS. . Però això només funcionarà en els casos en què, en cas d'una sola fallada, el servidor IPMI o UPS segueixi funcionant. Aquí tenim previst protegir-nos d'una fallada molt més catastròfica, quan falla tot el centre de dades (per exemple, perd energia). I amb tal negativa, tot pedra-els dispositius (IPMI, UPS, etc.) tampoc funcionaran.

En canvi, el sistema es basa en la idea de quòrum. Tots els nodes tenen veu i només poden funcionar aquells que poden veure més de la meitat de tots els nodes. Aquesta quantitat de "meitat + 1" s'anomena quòrum. Si no s'arriba al quòrum, aleshores el node decideix que està aïllat a la xarxa i ha de desactivar els seus recursos, és a dir. això és el que és protecció del cervell dividit. Si el programari responsable d'aquest comportament no funciona, haurà de funcionar un gos vigilant, per exemple, basat en IPMI.

Si el nombre de nodes és parell (un clúster en dos centres de dades), pot sorgir l'anomenada incertesa 50% / 50% (cinquanta cinquanta) quan l'aïllament de la xarxa divideix el clúster exactament per la meitat. Per tant, per a un nombre parell de nodes, afegim dispositiu de quòrum és un dimoni poc exigent que es pot llançar a la màquina virtual més barata d'un tercer centre de dades. Dona el seu vot a un dels segments (que veu), i així resol la incertesa del 50%/50%. Vaig anomenar el servidor on s'iniciarà el dispositiu de quòrum Testimoni (terminologia de repmgr, em va agradar).

Els recursos es poden moure d'un lloc a un altre, per exemple, des de servidors defectuosos a altres de bons, o per ordre dels administradors del sistema. Perquè els clients sàpiguen on es troben els recursos que necessiten (on connectar-se?), IP flotant (IP flotant). Aquestes són les IP que Pacemaker pot moure pels nodes (tot està en una xarxa plana). Cadascun d'ells simbolitza un recurs (servei) i s'ubicarà on cal connectar-se per poder accedir a aquest servei (en el nostre cas, una base de dades).

Tuchanka1 (circuit amb compactació)

Estructura

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

La idea era que disposem de moltes bases de dades petites amb poca càrrega, per a les quals no és rendible mantenir un servidor esclau dedicat en mode d'espera en calent per a transaccions de només lectura (no és necessari un malbaratament de recursos).

Cada centre de dades té un servidor. Cada servidor té dues instàncies PostgreSQL (en terminologia PostgreSQL s'anomenen clústers, però per evitar confusions els anomenaré instàncies (per analogia amb altres bases de dades) i només anomenaré clústers de Pacemaker). Una instància funciona en mode mestre i només proporciona serveis (només la IP flotant hi condueix). La segona instància funciona com a esclau per al segon centre de dades i només oferirà serveis si el seu mestre falla. Com que la majoria de vegades només una instància de cada dues (el mestre) proporcionarà serveis (realitzar sol·licituds), tots els recursos del servidor estan optimitzats per al mestre (s'assigna memòria per a la memòria cau shared_buffers, etc.), però de manera que la segona instància també té recursos suficients (encara que per a un funcionament subòptim a través de la memòria cau del sistema de fitxers) en cas de fallada d'un dels centres de dades. L'esclau no proporciona serveis (no realitza sol·licituds de només lectura) durant el funcionament normal del clúster, de manera que no hi ha guerra de recursos amb el mestre a la mateixa màquina.

En el cas de dos nodes, la tolerància a errors només és possible amb la replicació asíncrona, ja que amb la replicació síncrona, la fallada d'un esclau comportarà l'aturada del mestre.

Falta de testimoni

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Falta de testimoni (dispositiu de quòrum) Tindré en compte només per al clúster Tuchanka1, amb tots els altres serà la mateixa història. Si el testimoni falla, res canviarà a l'estructura del clúster, tot continuarà funcionant de la mateixa manera que ho va fer. Però el quòrum serà de 2 sobre 3 i, per tant, qualsevol fallada posterior serà fatal per al clúster. Encara s'haurà de solucionar amb urgència.

Tuchanka1 negativa

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Falla d'un dels centres de dades de Tuchanka1. En aquest cas Testimoni emet el seu vot a un segon node en un segon centre de dades. Allà, l'antic esclau es converteix en un mestre, com a resultat, tots dos mestres treballen al mateix servidor i les seves dues IP flotants apunten a ells.

Tuchanka2 (clàssic)

Estructura

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Esquema clàssic de dos nodes. L'amo treballa en un, l'esclau en el segon. Tots dos poden executar sol·licituds (l'esclau només és de lectura), de manera que tots dos s'apunten amb una IP flotant: krogan2 és el mestre, krogan2s1 és l'esclau. Tant el mestre com l'esclau tindran tolerància a fallades.

En el cas de dos nodes, la tolerància a errors només és possible amb la replicació asíncrona, perquè amb la replicació síncrona, la fallada de l'esclau portarà a l'aturada del mestre.

Tuchanka2 negativa

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Si un dels centres de dades falla Testimoni vots pel segon. A l'únic centre de dades que funcioni, el mestre s'elevarà i les dues IP flotants hi apuntaran: el mestre i l'esclau. Per descomptat, la instància s'ha de configurar de manera que tingui recursos suficients (límits de connexió, etc.) per acceptar simultàniament totes les connexions i peticions de la IP flotant mestre i esclau. És a dir, durant el funcionament normal hauria de tenir un subministrament suficient de límits.

Tuchanka4 (molts esclaus)

Estructura

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Ja és un altre extrem. Hi ha bases de dades que reben moltes sol·licituds de només lectura (un cas típic d'un lloc d'alta càrrega). Tuchanka4 és una situació en què hi pot haver tres o més esclaus per gestionar aquestes peticions, però encara no massa. Amb un nombre molt gran d'esclaus, caldrà inventar un sistema de replicació jeràrquica. En el cas mínim (a la imatge), cadascun dels dos centres de dades té dos servidors, cadascun amb una instància PostgreSQL.

Una altra característica d'aquest esquema és que ja és possible organitzar una replicació síncrona. Està configurat per replicar, si és possible, a un altre centre de dades, en lloc d'una rèplica al mateix centre de dades que el mestre. El mestre i cada esclau són assenyalats per una IP flotant. Afortunadament, entre esclaus caldrà equilibrar les peticions d'alguna manera proxy sql, per exemple, al costat del client. Diferents tipus de clients poden requerir diferents tipus proxy sql, i només els desenvolupadors de clients saben qui necessita quin. Aquesta funcionalitat es pot implementar per un dimoni extern o per una biblioteca de client (agrupació de connexions), etc. Tot això va més enllà del tema d'un clúster de bases de dades de failover (failover Proxy SQL es pot implementar de manera independent, juntament amb la tolerància a errors del client).

Tuchanka4 negativa

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Si un centre de dades (és a dir, dos servidors) falla, els testimonis votaran pel segon. Com a resultat, hi ha dos servidors que s'executen al segon centre de dades: un està executant un mestre i la IP flotant mestra hi apunta (per rebre sol·licituds de lectura i escriptura); i al segon servidor hi ha un esclau que s'executa amb replicació síncrona i una de les IP flotants esclau hi apunta (per a sol·licituds de només lectura).

El primer que cal tenir en compte és que no totes les IP flotants esclaus seran treballadors, sinó només una. I per treballar-hi correctament serà necessari que proxy sql ha redirigit totes les sol·licituds a l'única IP flotant restant; i si proxy sql no, llavors podeu llistar tots els esclaus IP flotants separats per comes a l'URL de connexió. En aquest cas, amb libpq la connexió serà a la primera IP de treball, això es fa en el sistema de proves automàtic. Potser en altres biblioteques, per exemple, JDBC, això no funcionarà i és necessari proxy sql. Això es fa perquè es prohibeix que les IP flotants per als esclaus s'aixequin simultàniament en un servidor, de manera que es distribueixen uniformement entre els servidors esclaus si n'hi ha diversos en execució.

Segon: fins i tot en cas de fallada del centre de dades, es mantindrà la replicació síncrona. I fins i tot si es produeix una fallada secundària, és a dir, un dels dos servidors del centre de dades restant falla, el clúster, tot i que deixarà de proporcionar serveis, encara conservarà la informació sobre totes les transaccions compromeses per a les quals hagi donat confirmació de la confirmació. (no hi haurà informació de pèrdua en cas de fallada secundària).

Tuchanka3 (3 centres de dades)

Estructura

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Aquest és un clúster per a una situació en què hi ha tres centres de dades que funcionen completament, cadascun dels quals té un servidor de bases de dades completament funcional. En aquest cas dispositiu de quòrum no necessari. Un centre de dades compta amb un mestre, els altres dos són esclaus. La replicació és sincrònica, escriviu ANY (slave1, slave2), és a dir, el client rebrà una confirmació de commit quan algun dels esclaus sigui el primer a respondre que ha acceptat la confirmació. Els recursos s'indiquen amb una IP flotant per al mestre i dues per als esclaus. A diferència de Tuchanka4, les tres IP flotants són tolerants a errors. Per equilibrar les consultes SQL de només lectura, podeu utilitzar proxy sql (amb tolerància a errors independent), o assigneu una IP flotant esclau a la meitat dels clients i l'altra meitat al segon.

Tuchanka3 negativa

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Si un dels centres de dades falla, en queden dos. En un, s'eleven l'IP mestre i flotant del mestre, en el segon: l'esclau i els dos IP flotants esclaus (la instància ha de tenir una reserva doble de recursos per acceptar totes les connexions de les dues IP flotants esclaus). Replicació sincrònica entre mestres i esclaus. A més, el clúster desarà informació sobre les transaccions compromeses i confirmades (no hi haurà pèrdua d'informació) en cas de destrucció de dos centres de dades (si no es destrueixen simultàniament).

Vaig decidir no incloure una descripció detallada de l'estructura del fitxer i el desplegament. Qualsevol persona que vulgui jugar pot llegir-ho tot al README. Només proporciono una descripció de les proves automatitzades.

Sistema de prova automàtic

Per provar la tolerància a fallades dels clústers simulant diverses fallades, s'ha creat un sistema de proves automàtic. Llançat per guió test/failure. L'script pot prendre com a paràmetres el nombre de clústers que voleu provar. Per exemple, aquesta comanda:

test/failure 2 3

només provarà el segon i el tercer clúster. Si no s'especifiquen els paràmetres, es provaran tots els clústers. Tots els clústers es posen a prova en paral·lel i el resultat es mostra al panell tmux. Tmux utilitza un servidor tmux dedicat, de manera que l'script es pot executar des de tmux predeterminat, donant lloc a un tmux imbricat. Recomano utilitzar el terminal en una finestra gran i amb un tipus de lletra petit. Abans de començar les proves, totes les màquines virtuals es tornen a una instantània en el moment en què es completa l'script setup.

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

El terminal es divideix en columnes segons el nombre de clústers que s'estan provant; per defecte (a la captura de pantalla) n'hi ha quatre. Descriuré el contingut de les columnes utilitzant l'exemple de Tuchanka2. Els panells de la captura de pantalla estan numerats:

  1. Les estadístiques de prova es mostren aquí. Columnes:
    • fracàs — el nom de la prova (funció a l'script) que emula l'error.
    • reacció — temps mitjà aritmètic en segons durant el qual el clúster va recuperar la seva funcionalitat. Es mesura des de l'inici de l'script emulant un error fins al moment en què el clúster restaura la seva funcionalitat i és capaç de continuar prestant serveis. Si el temps és molt curt, per exemple, sis segons (això passa en clústers amb diversos esclaus (Tuchanka3 i Tuchanka4)), això vol dir que l'error va ser a l'esclau asíncron i no va afectar de cap manera el rendiment; no hi havia commutadors d'estat del clúster.
    • desviació — mostra la dispersió (exactitud) del valor reacció utilitzant el mètode de la desviació estàndard.
    • comptar — Quantes vegades s'ha realitzat aquesta prova.
  2. Un registre breu us permet avaluar què està fent el clúster actualment. Es mostren el número d'iteració (prova), la marca de temps i el nom de l'operació. Executar massa temps (> 5 minuts) indica un problema.
  3. cor (cor) - hora actual. Per a l'avaluació visual del rendiment mestres L'hora actual s'escriu constantment a la seva taula mitjançant el mestre IP flotant. Si té èxit, el resultat es mostra en aquest panell.
  4. batre (pols) - "hora actual", que el guió va registrar prèviament cor dominar, ara llegiu-ne esclau mitjançant la seva IP flotant. Permet avaluar visualment el rendiment de l'esclau i la replicació. A Tuchanka1 no hi ha esclaus amb IP flotant (no hi ha esclaus que proporcionen serveis), però hi ha dues instàncies (DB), per la qual cosa no es mostrarà aquí batreI cor segona instància.
  5. Supervisió de l'estat del clúster mitjançant la utilitat pcs mon. Mostra l'estructura, la distribució dels recursos entre nodes i altra informació útil.
  6. Aquí es mostra la supervisió del sistema des de cada màquina virtual del clúster. Pot ser que hi hagi més panells d'aquest tipus en funció de quantes màquines virtuals tingui el clúster. Dos gràfics Càrrega de la CPU (les màquines virtuals tenen dos processadors), nom de la màquina virtual, Càrrega del sistema (anomenat Load Average perquè es fa una mitjana de 5, 10 i 15 minuts), processa dades i assignació de memòria.
  7. Rastre de l'script realitzant proves. En cas d'un mal funcionament -una interrupció sobtada del funcionament o un cicle d'espera interminable- aquí podeu veure el motiu d'aquest comportament.

La prova es realitza en dues etapes. En primer lloc, l'script passa per tot tipus de proves, seleccionant aleatòriament una màquina virtual a la qual aplicar aquesta prova. A continuació, es realitza un cicle interminable de proves, les màquines virtuals i la falla es seleccionen aleatòriament cada vegada. La finalització sobtada de l'script de prova (tauler inferior) o un bucle interminable d'espera d'alguna cosa (> 5 minuts de temps d'execució per a una operació, això es pot veure a la traça) indica que algunes de les proves d'aquest clúster han fallat.

Cada prova consta de les operacions següents:

  1. Inicieu una funció que emuli una fallada.
  2. Ready? — esperant que es restableixi el clúster (quan es proporcionin tots els serveis).
  3. Mostra el temps d'espera de recuperació del clúster (reacció).
  4. Fixar — el clúster s'està "reparant". Després d'això, hauria de tornar a un estat totalment operatiu i estar preparat per al següent mal funcionament.

Aquí teniu una llista de proves amb una descripció del que fan:

  • ForkBomb: Crea "S'ha quedat sense memòria" amb una bomba de forquilla.
  • Sense espai: El disc dur està ple. Però la prova és més aviat simbòlica; amb la càrrega insignificant que es crea durant la prova, PostgreSQL normalment no falla quan el disc dur està ple.
  • Postgres-KILL: mata PostgreSQL amb l'ordre killall -KILL postgres.
  • Postgres-STOP: penja l'ordre PostgreSQL killall -STOP postgres.
  • poweroff: "desenergitza" la màquina virtual amb l'ordre VBoxManage controlvm "виртуалка" poweroff.
  • reajustar: sobrecarrega la màquina virtual amb l'ordre VBoxManage controlvm "виртуалка" reset.
  • SBD-STOP: suspèn el dimoni SBD amb l'ordre killall -STOP sbd.
  • Tancar: envia una ordre a la màquina virtual mitjançant SSH systemctl poweroff, el sistema s'apaga amb gràcia.
  • Desenllaça: aïllament de xarxa, comandament VBoxManage controlvm "виртуалка" setlinkstate1 off.

Completar les proves utilitzant l'ordre estàndard de tmux "kill-window" Ctrl-b &, o l'ordre "detach-client". Ctrl-b d: en aquest punt s'acaben les proves, tmux es tanca i les màquines virtuals s'apaguen.

Problemes detectats durant les proves

  • En aquest moment gos guardià dimoni sbd treballa per aturar els dimonis observats, però no per congelar-los. I, com a resultat, falles que només condueixen a la congelació Corosync и marcapassos, però no penjant sbd. Per comprovar Corosync Ja ho teniu PR#83 (a GitHub a sbd), acceptat al fil mestre. Van prometre (en PR#83) que hi hauria alguna cosa semblant per a Pacemaker, espero que abans RedHat juliol ho faré. Però aquests "mal funcionaments" són especulatius i es poden simular fàcilment artificialment utilitzant, per exemple, killall -STOP corosync, però mai ens trobem a la vida real.

  • У marcapassos en la versió per CentOS 7 configurat incorrectament sync_timeout у dispositiu de quòrum, com a resultat si un node fallava, amb certa probabilitat el segon node també es reiniciava, a la qual s'havia de traslladar el mestre. Curat per l'ampliació sync_timeout у dispositiu de quòrum durant el desplegament (en script setup/setup1). Aquesta modificació no va ser acceptada pels desenvolupadors marcapassos, en canvi, es van comprometre a redissenyar la infraestructura de tal manera (en un futur no especificat) que aquest temps d'espera es calcularia automàticament.

  • Si la configuració de la base de dades ho especifica LC_MESSAGES (missatges de text) Es pot utilitzar Unicode, p. ru_RU.UTF-8, després a l'inici postgres en un entorn on la configuració regional no és UTF-8, per exemple, en un entorn buit (aquí marcapassos+pgsqlms(paf) corre postgres) doncs el registre contindrà signes d'interrogació en lloc de lletres UTF-8. Els desenvolupadors de PostgreSQL no s'han posat d'acord sobre què fer en aquest cas. Costa, cal instal·lar-lo LC_MESSAGES=en_US.UTF-8 quan es configura (crea) una instància de base de dades.

  • Si s'estableix wal_receiver_timeout (per defecte és de 60 segons), aleshores durant la prova PostgreSQL-STOP al mestre als clústers tuchanka3 i tuchanka4 la replicació no es torna a connectar al nou mestre. La replicació és síncrona, de manera que no només s'atura l'esclau, sinó també el nou mestre. Funciona configurant wal_receiver_timeout=0 quan es configura PostgreSQL.

  • De tant en tant vaig observar congelacions de rèplica a PostgreSQL a la prova ForkBomb (desbordament de memòria). Després de ForkBomb, de vegades és possible que els esclaus no es tornin a connectar al nou mestre. Només he trobat això als clústers tuchanka3 i tuchanka4, on el mestre es va congelar a causa de la replicació síncrona. El problema va desaparèixer tot sol després de molt de temps (unes dues hores). Cal més investigació per corregir-ho. Els símptomes són semblants a l'error anterior, que és causat per un motiu diferent, però amb les mateixes conseqüències.

Imatge de Krogan presa de Deviant Art amb permís de l'autor:

Modelatge de clústers de failover basat en PostgreSQL i Pacemaker

Font: www.habr.com

Afegeix comentari