Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Introduzione

Qualche tempo fa mi è stato affidato il compito di sviluppare un cluster di failover per PostgreSQL, che operano in diversi data center collegati tramite fibra ottica all'interno di una città e in grado di resistere a un guasto (ad esempio, blackout) di un data center. Come software responsabile della tolleranza agli errori, ho scelto Pacemakerperché questa è la soluzione ufficiale di RedHat per la creazione di cluster di failover. È positivo perché RedHat ne fornisce il supporto e perché questa soluzione è universale (modulare). Con il suo aiuto sarà possibile garantire la tolleranza agli errori non solo di PostgreSQL, ma anche di altri servizi, sia utilizzando moduli standard sia creandoli per esigenze specifiche.

Questa decisione ha sollevato una domanda ragionevole: quanto sarà tollerante ai guasti un cluster di failover? Per indagare su questo, ho sviluppato un banco di prova che simula vari guasti sui nodi del cluster, attende il ripristino del servizio, recupera il nodo guasto e continua il test in un ciclo. Questo progetto originariamente si chiamava hapgsql, ma col tempo mi sono stufato del nome, che aveva solo una vocale. Pertanto, ho iniziato a chiamare database tolleranti agli errori (e IP float che punta ad essi) krogan (un personaggio di un gioco per computer in cui tutti gli organi importanti sono duplicati), così come i nodi, i cluster e il progetto stesso tuchanka (il pianeta dove vivono i krogan).

Ora la direzione lo ha permesso aprire il progetto alla comunità open source sotto la licenza MIT. Il README sarà presto tradotto in inglese (perché si prevede che i principali consumatori saranno gli sviluppatori Pacemaker e PostgreSQL), e ho deciso di presentare la vecchia versione russa del README (parzialmente) sotto forma di questo articolo.

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

I cluster vengono distribuiti su macchine virtuali VirtualBox. Verranno implementate un totale di 12 macchine virtuali (36GiB in totale), che formano 4 cluster tolleranti agli errori (diverse opzioni). I primi due cluster sono costituiti da due server PostgreSQL, situati in data center diversi, e da un server comune testimoniare c dispositivo del quorum (ospitato su una macchina virtuale economica in un terzo data center), che risolve l’incertezza 50% / 50%, dando il tuo voto a uno dei partiti. Terzo cluster in tre data center: un master, due slave, n dispositivo del quorum. Il quarto cluster è costituito da quattro server PostgreSQL, due per data center: uno master, il resto repliche e anche usi testimoniare c dispositivo del quorum. Il quarto può resistere al guasto di due server o di un data center. Se necessario, questa soluzione può essere scalata per un numero maggiore di repliche.

Servizio orario accurato ntpd anch'esso riconfigurato per la tolleranza agli errori, ma utilizza il metodo stesso ntpd (modalità orfana). Server condiviso testimoniare agisce come un server NTP centrale, distribuendo il suo tempo a tutti i cluster, sincronizzando così tutti i server tra loro. Se testimoniare fallisce o viene isolato, uno dei server del cluster (all'interno del cluster) inizierà a distribuire il proprio tempo. Caching ausiliario Proxy HTTP anche elevato a testimoniare, con il suo aiuto, altre macchine virtuali hanno accesso ai repository Yum. In realtà, servizi come l'ora esatta e i proxy saranno molto probabilmente ospitati su server dedicati, ma nello stand sono ospitati su testimoniare solo per risparmiare il numero di macchine virtuali e spazio.

versioni

v0. Funziona con CentOS 7 e PostgreSQL 11 su VirtualBox 6.1.

Struttura a grappolo

Tutti i cluster sono progettati per essere ubicati in più data center, combinati in un'unica rete piatta e devono resistere ai guasti o all'isolamento della rete di un singolo data center. Ecco perché impossibile utilizzare per la protezione contro cervello diviso la tecnologia standard Pacemaker chiamata STONITO (Spara all'altro nodo in testa) o scherma. La sua essenza: se i nodi nel cluster iniziano a sospettare che qualcosa non va in qualche nodo, non risponde o si comporta in modo errato, lo spengono forzatamente tramite dispositivi "esterni", ad esempio una scheda di controllo IPMI o UPS . Ma questo funzionerà solo nei casi in cui, in caso di un singolo guasto, il server IPMI o UPS continua a funzionare. In questo caso intendiamo proteggerci da guasti molto più catastrofici, quando l'intero data center fallisce (ad esempio, perde energia). E con un tale rifiuto, tutto stonith-anche i dispositivi (IPMI, UPS, ecc.) non funzioneranno.

Il sistema si basa invece sull’idea del quorum. Tutti i nodi hanno una voce e solo quelli che possono vedere più della metà di tutti i nodi possono funzionare. Questa quantità di “metà + 1” si chiama quorum. Se il quorum non viene raggiunto, il nodo decide di essere in isolamento di rete e deve disattivare le proprie risorse, ad es. questo è quello che è protezione del cervello diviso. Se il software responsabile di questo comportamento non funziona, allora dovrà funzionare un watchdog basato, ad esempio, su IPMI.

Se il numero di nodi è pari (un cluster in due data center), potrebbe verificarsi la cosiddetta incertezza 50% / 50% (Metà e metà) quando l'isolamento della rete divide il cluster esattamente a metà. Pertanto, per un numero pari di nodi, aggiungiamo dispositivo del quorum è un demone poco impegnativo che può essere avviato sulla macchina virtuale più economica in un terzo data center. Dà il suo voto a uno dei segmenti (che vede), risolvendo così l'incertezza del 50%/50%. Ho nominato il server su cui verrà avviato il dispositivo quorum testimoniare (terminologia da repmgr, mi è piaciuta).

Le risorse possono essere spostate da un luogo all'altro, ad esempio da server difettosi a server integri o su comando degli amministratori di sistema. In modo che i clienti sappiano dove si trovano le risorse di cui hanno bisogno (dove connettersi?), IP mobile (IP mobile). Questi sono gli IP che Pacemaker può spostare tra i nodi (tutto è su una rete piatta). Ognuno di essi simboleggia una risorsa (servizio) e si troverà nel punto in cui è necessario connettersi per accedere a questo servizio (nel nostro caso, un database).

Tuchanka1 (circuito con compattazione)

Struttura

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

L'idea era che abbiamo molti piccoli database con carico ridotto, per i quali non è redditizio mantenere un server slave dedicato in modalità hot standby per transazioni di sola lettura (non è necessario un tale spreco di risorse).

Ogni data center ha un server. Ogni server ha due istanze PostgreSQL (nella terminologia PostgreSQL sono chiamate cluster, ma per evitare confusione le chiamerò istanze (per analogia con altri database) e chiamerò solo cluster Pacemaker cluster). Un'istanza funziona in modalità master e solo essa fornisce servizi (solo l'IP float conduce ad essa). La seconda istanza funziona come slave per il secondo data center e fornirà servizi solo in caso di guasto del master. Poiché nella maggior parte dei casi solo un'istanza su due (il master) fornirà servizi (eseguirà richieste), tutte le risorse del server sono ottimizzate per il master (la memoria è allocata per la cache shared_buffers, ecc.), ma in modo che la seconda istanza dispone inoltre di risorse sufficienti (anche se per un funzionamento non ottimale tramite la cache del file system) in caso di guasto di uno dei data center. Lo slave non fornisce servizi (non esegue richieste di sola lettura) durante il normale funzionamento del cluster, in modo che non vi sia guerra per le risorse con il master sulla stessa macchina.

Nel caso di due nodi la tolleranza agli errori è possibile solo con la replica asincrona, poiché nella replica sincrona il guasto di uno slave porterà all'arresto del master.

Mancata testimonianza

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Mancata testimonianza (dispositivo del quorum) Prenderò in considerazione solo il cluster Tuchanka1, con tutti gli altri sarà la stessa storia. Se il testimone fallisce, nulla cambierà nella struttura del cluster, tutto continuerà a funzionare come prima. Ma il quorum diventerà 2 su 3, e quindi ogni successivo fallimento sarà fatale per il cluster. Dovrà ancora essere risolto con urgenza.

Rifiuto di Tuchanka1

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Guasto di uno dei data center per Tuchanka1. In questo caso testimoniare esprime il suo voto a un secondo nodo in un secondo data center. Lì, l'ex schiavo si trasforma in un master, di conseguenza entrambi i master lavorano sullo stesso server ed entrambi i loro IP float puntano a loro.

Tuchanka2 (classico)

Struttura

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Schema classico di due nodi. Su uno lavora il padrone, sul secondo lo schiavo. Entrambi possono eseguire richieste (lo slave è di sola lettura), quindi entrambi sono puntati dall'IP float: krogan2 è il master, krogan2s1 è lo slave. Sia il master che lo slave avranno tolleranza agli errori.

Nel caso di due nodi la tolleranza agli errori è possibile solo con la replica asincrona, perché nella replica sincrona il guasto dello slave porterà all'arresto del master.

Rifiuto di Tuchanka2

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Se uno dei data center fallisce testimoniare voti per la seconda. Nell'unico data center funzionante, verrà attivato il master ed entrambi gli IP float punteranno ad esso: il master e lo slave. Naturalmente l'istanza deve essere configurata in modo tale da disporre di risorse sufficienti (limiti di connessione, ecc.) per accettare contemporaneamente tutte le connessioni e le richieste dall'IP float master e slave. Cioè, durante il normale funzionamento dovrebbe avere una fornitura sufficiente di limiti.

Tuchanka4 (molti schiavi)

Struttura

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Già un altro estremo. Esistono database che ricevono molte richieste di sola lettura (un caso tipico di un sito ad alto carico). Tuchanka4 è una situazione in cui potrebbero esserci tre o più schiavi per gestire tali richieste, ma non troppi. Con un numero molto elevato di schiavi sarà necessario inventare un sistema di replicazione gerarchica. Nel caso minimo (nella foto), ciascuno dei due data center ha due server, ciascuno con un'istanza PostgreSQL.

Un'altra caratteristica di questo schema è che è già possibile organizzare una replica sincrona. È configurato per replicarsi, se possibile, su un altro data center, anziché su una replica nello stesso data center del master. Il master e ogni slave sono puntati da un IP float. Per fortuna tra gli schiavi bisognerà in qualche modo bilanciare le richieste proxy sql, ad esempio, sul lato client. Diversi tipi di client possono richiedere tipi diversi proxy sqle solo gli sviluppatori client sanno chi ha bisogno di quale. Questa funzionalità può essere implementata da un demone esterno o da una libreria client (pool di connessione), ecc. Tutto ciò va oltre l'argomento di un cluster di database di failover (failover Proxy SQL può essere implementato in modo indipendente, insieme alla tolleranza agli errori del client).

Rifiuto di Tuchanka4

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Se un data center (ovvero due server) fallisce, il testimone vota per il secondo. Di conseguenza, nel secondo data center sono in esecuzione due server: su uno è in esecuzione un master e l'IP float del master punta ad esso (per ricevere richieste di lettura-scrittura); e sul secondo server è presente uno slave in esecuzione con replica sincrona e uno degli IP float dello slave punta ad esso (per richieste di sola lettura).

La prima cosa da notare è che non tutti gli IP float slave saranno lavoratori, ma solo uno. E per lavorarci correttamente sarà necessario quello proxy sql reindirizzato tutte le richieste all'unico IP float rimanente; e se proxy sql no, allora puoi elencare tutti gli slave IP float separati da virgole nell'URL di connessione. In questo caso, con libq la connessione avverrà al primo IP funzionante, questo avviene nel sistema di test automatico. Forse in altre librerie, ad esempio JDBC, questo non funzionerà ed è necessario proxy sql. Questo viene fatto perché gli IP float per gli slave non possono essere generati simultaneamente su un server, in modo che siano distribuiti equamente tra i server slave se ce ne sono diversi in esecuzione.

Secondo: anche in caso di guasto del data center, verrà mantenuta la replica sincrona. E anche se si verifica un guasto secondario, ovvero uno dei due server nel restante data center si guasta, il cluster, anche se smetterà di fornire servizi, conserverà comunque le informazioni su tutte le transazioni impegnate per le quali ha dato conferma del commit (non ci saranno informazioni sulla perdita in caso di guasto secondario).

Tuchanka3 (3 data center)

Struttura

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Questo è un cluster per una situazione in cui sono presenti tre data center perfettamente funzionanti, ognuno dei quali dispone di un server database perfettamente funzionante. In questo caso dispositivo del quorum non necessario. Un data center è gestito da un master, gli altri due sono gestiti da slave. La replica è sincrona, tipo ANY (slave1, slave2), ovvero il client riceverà una conferma di commit quando uno qualsiasi degli slave sarà il primo a rispondere di aver accettato il commit. Le risorse sono indicate da un IP float per il master e due per gli slave. A differenza di Tuchanka4, tutti e tre gli IP float sono tolleranti agli errori. Per bilanciare le query SQL di sola lettura è possibile utilizzare proxy sql (con tolleranza agli errori separata), oppure assegnare un IP float slave a metà dei client e l'altra metà al secondo.

Rifiuto di Tuchanka3

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Se uno dei data center fallisce, ne rimangono due. In uno, vengono generati l'IP master e float dal master, nel secondo - lo slave e entrambi gli IP float dello slave (l'istanza deve avere una doppia riserva di risorse per accettare tutte le connessioni da entrambi gli IP float dello slave). Replica sincrona tra master e slave. Inoltre, il cluster salverà le informazioni sulle transazioni confermate e confermate (non ci sarà perdita di informazioni) in caso di distruzione di due data center (se non vengono distrutti contemporaneamente).

Ho deciso di non includere una descrizione dettagliata della struttura e della distribuzione dei file. Chiunque voglia giocare può leggere tutto nel README. Sto solo fornendo una descrizione dei test automatizzati.

Sistema di test automatico

Per testare la tolleranza agli errori dei cluster simulando vari errori, è stato creato un sistema di test automatico. Lanciato tramite script test/failure. Lo script può prendere come parametri il numero di cluster che vuoi testare. Ad esempio questo comando:

test/failure 2 3

testerà solo il secondo e il terzo cluster. Se i parametri non vengono specificati, verranno testati tutti i cluster. Tutti i cluster vengono testati in parallelo e il risultato viene visualizzato nel pannello tmux. Tmux utilizza un server tmux dedicato, quindi lo script può essere eseguito da tmux predefinito, risultando in un tmux nidificato. Consiglio di utilizzare il terminale in una finestra grande e con un carattere piccolo. Prima dell'inizio del test, viene eseguito il rollback di tutte le macchine virtuali a uno snapshot al momento del completamento dello script setup.

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Il terminale è diviso in colonne in base al numero di cluster in fase di test; di default (nello screenshot) ce ne sono quattro. Descriverò il contenuto delle colonne usando l'esempio di Tuchanka2. I pannelli nello screenshot sono numerati:

  1. Le statistiche del test vengono visualizzate qui. Colonne:
    • fallimento — il nome del test (funzione nello script) che emula l'errore.
    • reazione — tempo medio aritmetico in secondi durante il quale il cluster ha recuperato la sua funzionalità. Viene misurato dall'inizio dello script che emula un guasto fino al momento in cui il cluster ripristina la sua funzionalità ed è in grado di continuare a fornire servizi. Se il tempo è molto breve, ad esempio sei secondi (questo accade nei cluster con più slave (Tuchanka3 e Tuchanka4)), significa che il guasto era sullo slave asincrono e non ha influito in alcun modo sulle prestazioni; non c'erano interruttori di stato del cluster.
    • deviazione — mostra lo spread (precisione) del valore reazione utilizzando il metodo della deviazione standard.
    • contare — quante volte è stato eseguito questo test.
  2. Un breve registro consente di valutare cosa sta attualmente facendo il cluster. Vengono visualizzati il ​​numero dell'iterazione (test), il timestamp e il nome dell'operazione. Un'esecuzione troppo lunga (> 5 minuti) indica un problema.
  3. cuore (cuore) - ora corrente. Per la valutazione visiva delle prestazioni maestro L'ora corrente viene costantemente scritta nella sua tabella utilizzando il master IP float. In caso di successo, il risultato viene visualizzato in questo pannello.
  4. battere (impulso) - "ora corrente", precedentemente registrata dallo script cuore per padroneggiare, ora leggi da schiavo tramite il suo IP float. Consente di valutare visivamente le prestazioni dello slave e della replica. In Tuchanka1 non ci sono slave con IP float (nessuno slave che fornisce servizi), ma ci sono due istanze (DB), quindi non verrà mostrato qui battereE cuore seconda istanza.
  5. Monitoraggio dell'integrità del cluster utilizzando l'utilità pcs mon. Mostra la struttura, la distribuzione delle risorse tra i nodi e altre informazioni utili.
  6. Il monitoraggio del sistema da ogni macchina virtuale nel cluster viene visualizzato qui. Potrebbero esserci più pannelli di questo tipo a seconda del numero di macchine virtuali di cui dispone il cluster. Due grafici Carico della CPU (le macchine virtuali hanno due processori), nome della macchina virtuale, Carico di sistema (denominato Load Average perché viene calcolata la media su 5, 10 e 15 minuti), elabora i dati e l'allocazione della memoria.
  7. Traccia dello script che esegue il test. In caso di malfunzionamento - un'improvvisa interruzione del funzionamento o un ciclo di attesa infinito - qui puoi vedere il motivo di questo comportamento.

Il test viene effettuato in due fasi. Innanzitutto, lo script esegue tutti i tipi di test, selezionando in modo casuale una macchina virtuale a cui applicare questo test. Quindi viene eseguito un ciclo infinito di test, le macchine virtuali e l'errore vengono selezionati ogni volta in modo casuale. L'interruzione improvvisa dello script di test (pannello inferiore) o un ciclo infinito di attesa di qualcosa (> 5 minuti di tempo di esecuzione per un'operazione, questo può essere visualizzato nella traccia) indica che alcuni dei test su questo cluster non sono riusciti.

Ogni prova consiste nelle seguenti operazioni:

  1. Avvia una funzione che emula un errore.
  2. Pronti? — in attesa del ripristino del cluster (quando tutti i servizi saranno forniti).
  3. Mostra il timeout di ripristino del cluster (reazione).
  4. Fissare - il cluster è in fase di "riparazione". Dopodiché dovrebbe tornare allo stato pienamente operativo ed essere pronto per il prossimo malfunzionamento.

Ecco un elenco dei test con una descrizione di ciò che fanno:

  • ForkBomb: Crea "Memoria esaurita" utilizzando una bomba fork.
  • Pieno: Il disco rigido è pieno. Ma il test è piuttosto simbolico; con il carico insignificante che viene creato durante il test, PostgreSQL di solito non fallisce quando il disco rigido è pieno.
  • Postgres-KILL: uccide PostgreSQL con il comando killall -KILL postgres.
  • Postgres-STOP: blocca il comando PostgreSQL killall -STOP postgres.
  • Spegni: “diseccita” la macchina virtuale con il comando VBoxManage controlvm "виртуалка" poweroff.
  • Reset: sovraccarica la macchina virtuale con il comando VBoxManage controlvm "виртуалка" reset.
  • SBD-STOP: sospende il demone SBD con il comando killall -STOP sbd.
  • Spegnimento: invia un comando alla macchina virtuale tramite SSH systemctl poweroff, il sistema si spegne normalmente.
  • Scollega: isolamento della rete, comando VBoxManage controlvm "виртуалка" setlinkstate1 off.

Completamento del test utilizzando il comando tmux standard "kill-window" Ctrl-b &o il comando "detach-client". Ctrl-bd: a questo punto il testing termina, tmux si chiude, le macchine virtuali vengono spente.

Problemi identificati durante i test

  • Al momento, demone cane da guardia sbd funziona per fermare i demoni osservati, ma non per congelarli. E, di conseguenza, difetti che portano solo al congelamento Corosinc и Pacemaker, ma non impiccato sbd... Per il controllo Corosinc già PR#83 (su GitHub all'indirizzo sbd), accettato nel thread Mastercard. Hanno promesso (nel PR#83) che ci sarebbe stato qualcosa di simile per Pacemaker, lo spero Red Hat 8 andrà bene. Ma tali “malfunzionamenti” sono speculativi e possono essere facilmente simulati artificialmente utilizzando, ad esempio, killall -STOP corosync, ma non si incontrano mai nella vita reale.

  • У Pacemaker nella versione per 7 CentOS impostato in modo errato sync_timeout у dispositivo del quorum, di conseguenza se un nodo fallisce, con una certa probabilità anche il secondo nodo si riavvia, a cui avrebbe dovuto trasferirsi il maestro. Curato dall'allargamento sync_timeout у dispositivo del quorum durante la distribuzione (in script setup/setup1). Questo emendamento non è stato accettato dagli sviluppatori Pacemaker, hanno invece promesso di riprogettare l'infrastruttura in modo tale (in un futuro non specificato) che questo timeout sarebbe stato calcolato automaticamente.

  • Se la configurazione del database lo specifica LC_MESSAGES (messaggi di testo) È possibile utilizzare Unicode, ad es. ru_RU.UTF-8, quindi all'avvio Postgres in un ambiente in cui la locale non è UTF-8, ad esempio in un ambiente vuoto (qui pacemaker+pgsqlms(paf) corre Postgres) poi il registro conterrà punti interrogativi anziché lettere UTF-8. Gli sviluppatori PostgreSQL non sono d'accordo su cosa fare in questo caso. Costa, devi installarlo LC_MESSAGES=en_US.UTF-8 durante la configurazione (creazione) di un'istanza del database.

  • Se wal_receiver_timeout è impostato (per impostazione predefinita è 60s), durante il test PostgreSQL-STOP sul master nei cluster tuchanka3 e tuchanka4 la replica non si riconnette al nuovo master. La replica è sincrona, quindi non si ferma solo lo slave, ma anche il nuovo master. Funziona impostando wal_receiver_timeout=0 durante la configurazione di PostgreSQL.

  • Occasionalmente ho osservato blocchi della replica in PostgreSQL nel test ForkBomb (overflow della memoria). Dopo ForkBomb, a volte gli slave potrebbero non riconnettersi al nuovo master. L'ho riscontrato solo nei cluster tuchanka3 e tuchanka4, dove il master si è bloccato a causa della replica sincrona. Il problema si è risolto da solo dopo molto tempo (circa due ore). Sono necessarie ulteriori ricerche per correggere questo problema. I sintomi sono simili al bug precedente, causato da un motivo diverso, ma con le stesse conseguenze.

Foto di Krogan tratta da Deviant Art con il permesso dell'autore:

Modellazione di cluster di failover basati su PostgreSQL e Pacemaker

Fonte: habr.com

Aggiungi un commento