Architetture per l'alta disponibilità dei cluster PostgreSQL su Compute Engine

Last reviewed 2024-12-03 UTC

Questo documento descrive diverse architetture che forniscono alta disponibilità (HA) per i deployment di PostgreSQL su Google Cloud. L'HA è la misura della resilienza del sistema in risposta al guasto dell'infrastruttura di base. In questo documento, per HA si intende la disponibilità dei cluster PostgreSQL all'interno di un'unica regione cloud o tra più regioni, a seconda dell'architettura HA.

Questo documento è rivolto ad amministratori di database, architetti cloud e sviluppatori DevOps che vogliono scoprire come aumentare l'affidabilità del livello dati PostgreSQL migliorando il tempo di attività complessivo del sistema. Questo documento illustra i concetti pertinenti all'esecuzione di PostgreSQL su Compute Engine. Il documento non discute l'utilizzo di database gestiti come Cloud SQL per PostgreSQL e AlloyDB per PostgreSQL.

Se un sistema o un'applicazione richiede uno stato permanente per gestire richieste o transazioni, il livello di persistenza dei dati (livello dati) deve essere disponibile per gestire correttamente le richieste di query o mutazioni dei dati. Il tempo di riposo nel livello di dati impedisce al sistema o all'applicazione di eseguire le attività necessarie.

A seconda degli obiettivi del livello di servizio (SLO) del sistema, potresti necessitare di un'architettura che offra un livello di disponibilità più elevato. Esistono più modi per ottenere l'alta disponibilità, ma in genere esegui il provisioning di un'infrastruttura ridondante che puoi rendere rapidamente accessibile alla tua applicazione.

Questo documento illustra i seguenti argomenti:

  • Definizione dei termini relativi ai concetti di database ad alta disponibilità.
  • Opzioni per le topologie PostgreSQL ad alta disponibilità.
  • Informazioni contestuali per la valutazione di ogni opzione di architettura.

Terminologia

I seguenti termini e concetti sono standard di settore e sono utili da comprendere per scopi che esulano dall'ambito di questo documento.

replica
La procedura mediante la quale le transazioni di scrittura (INSERT, UPDATE o DELETE) e le modifiche dello schema (linguaggio di definizione dei dati (DDL)) vengono acquisite, registrate e poi applicate in sequenza a tutti i nodi di replica del database in downstream nell'architettura.
Nodo principale
Il nodo che fornisce una lettura con lo stato più aggiornato dei dati memorizzati. Tutte le scritture del database devono essere indirizzate a un nodo principale.
Nodo replica (secondario)
Una copia online del nodo del database principale. Le modifiche vengono replicate ai nodi replica dal nodo principale in modo sincrono o asincrono. Puoi leggere dai nodi replica tenendo presente che i dati potrebbero essere leggermente in ritardo a causa del ritardo della replica.
Ritardo della replica
Una misurazione, in numero di sequenza di log (LSN), ID transazione o ora. Il ritardo della replica esprime la differenza tra il momento in cui le operazioni di modifica vengono applicate alla replica e il momento in cui vengono applicate al nodo principale.
archiviazione continua
Un backup incrementale in cui il database salva continuamente le transazioni sequenziali in un file.
log write-ahead (WAL)
Un log write-ahead (WAL) è un file di log che registra le modifiche ai file di dati prima che vengano apportate modifiche effettive ai file. In caso di arresto anomalo del server, il WAL è un modo standard per contribuire a garantire l'integrità e la durabilità dei dati delle tue scritture.
Record WAL
Un record di una transazione applicata al database. Un record WAL viene formato e archiviato come una serie di record che descrivono le modifiche a livello di pagina del file di dati.
Numero di sequenza di log (LSN)
Le transazioni creano record WAL che vengono aggiunti al file WAL. La posizione in cui avviene l'inserimento è chiamata numero di sequenza di log (LSN). Si tratta di un numero intero a 64 bit, rappresentato da due numeri esadecimali separati da una barra (XXXXXXXX/YYZZZZZZ). "Z" rappresenta la posizione dell'offset nel file WAL.
file di segmenti
File contenenti il maggior numero possibile di record WAL, a seconda della dimensione del file configurata. I file di segmento hanno nomi in aumento monotonico e una dimensione predefinita di 16 MB.
replica sincrona
Una forma di replica in cui il server principale attende che la replica confermi che i dati sono stati scritti nel log delle transazioni della replica prima di confermare un commit al client. Quando esegui la replica in streaming, puoi utilizzare l'opzione PostgreSQL synchronous_commit, che consente di garantire la coerenza tra il server principale e la replica.
Replica asincrona
Una forma di replica in cui il server principale non attende che la replica confermi che la transazione è stata ricevuta correttamente prima di confermare un commit al client. La replica asincrona ha una latenza inferiore rispetto alla replica sincrona. Tuttavia, se l'istanza principale si arresta in modo anomalo e le relative transazioni committate non vengono trasferite alla replica, esiste la possibilità di perdere dati. La replica asincrona è la modalità di replica predefinita su PostgreSQL, che utilizza il trasferimento dei log basato su file o la replica in streaming.
spedizione dei log basata su file
Un metodo di replica in PostgreSQL che trasferisce i file di segmento WAL dal server del database principale alla replica. Il servizio principale funziona in modalità di archiviazione continua, mentre ogni servizio di standby funziona in modalità di recupero continuo per leggere i file WAL. Questo tipo di replica è asincrona.
replica in streaming
Un metodo di replica in cui la replica si connette all'istanza principale e riceve continuamente una sequenza continua di modifiche. Poiché gli aggiornamenti arrivano tramite uno stream, questo metodo mantiene la replica più aggiornata rispetto alla replica di log shipping. Anche se la replica è asincrona per impostazione predefinita, in alternativa puoi configurare la replica sincrona.
Replica di streaming fisico
Un metodo di replica che trasporta le modifiche alla replica. Questo metodo utilizza i record WAL che contengono le modifiche dei dati fisici sotto forma di indirizzi dei blocchi del disco e modifiche byte per byte.
replica di streaming logica
Un metodo di replica che acquisisce le modifiche in base alla loro identità di replica (chiave primaria), il che consente un maggiore controllo sul modo in cui i dati vengono replicati rispetto alla replica fisica. A causa delle limitazioni della replica logica di PostgreSQL, la replica logica in streaming richiede una configurazione speciale per una configurazione HA. Questa guida illustra la replica fisica standard e non la replica logica.
uptime
La percentuale di tempo in cui una risorsa è in funzione e in grado di fornire una risposta a una richiesta.
Rilevamento di errori
Il processo di identificazione di un errore dell'infrastruttura.
failover
La procedura di promozione dell'infrastruttura di backup o di standby (in questo caso, il nodo replica) in modo che diventi l'infrastruttura principale. Durante il failover, il nodo replica diventa il nodo principale.
passaggio
La procedura di esecuzione di un failover manuale su un sistema di produzione. Un switchover verifica il corretto funzionamento del sistema o estrae il nodo principale corrente dal cluster per la manutenzione.
Recovery Time Objective (RTO)
La durata trascorsa in tempo reale per il completamento della procedura di failover del livello di dati. Il RTO dipende dal periodo di tempo accettabile dal punto di vista aziendale.
Recovery Point Objective (RPO)
La quantità di perdita di dati (in tempo reale trascorso) che il livello di dati deve sostenere come risultato del failover. L'RPO dipende dalla quantità di perdita di dati accettabile dal punto di vista aziendale.
di riserva
La procedura di reintegro del nodo principale precedente dopo la correzione della condizione che ha causato un failover.
autoriparazione
La capacità di un sistema di risolvere i problemi senza azioni esterne da parte di un operatore umano.
partizione di rete
Una condizione in cui due nodi di un'architettura, ad esempio i nodi principali e di replica, non possono comunicare tra loro tramite la rete.
cervello diviso
Una condizione che si verifica quando due nodi ritengono contemporaneamente di essere il nodo principale.
gruppo di nodi
Un insieme di risorse di calcolo che forniscono un servizio. In questo documento, questo servizio è il livello di persistenza dei dati.
Nodo di quorum o di testimone
Una risorsa di calcolo separata che aiuta un gruppo di nodi a determinare cosa fare quando si verifica una condizione di split-brain.
elezioni primarie o per il leader
La procedura mediante la quale un gruppo di nodi peer-aware, inclusi i nodi di attestazione, determina quale nodo deve essere il nodo principale.

Quando prendere in considerazione un'architettura HA

Le architetture ad alta disponibilità offrono una maggiore protezione contro i tempi di riposo del livello dati rispetto alle configurazioni di database a un solo nodo. Per selezionare l'opzione migliore per il tuo caso d'uso aziendale, devi conoscere la tua tolleranza al tempo di riposo e i rispettivi compromessi delle varie architetture.

Utilizza un'architettura HA quando vuoi aumentare il tempo di attività del livello di dati per soddisfare i requisiti di affidabilità per i tuoi carichi di lavoro e servizi. Se il tuo ambiente tollera un certo tempo di inattività, un'architettura ad alta disponibilità potrebbe introdurre costi e complessità non necessari. Ad esempio, gli ambienti di sviluppo o di test raramente richiedono un'alta disponibilità del livello del database.

Considera i tuoi requisiti per l'HA

Di seguito sono riportate alcune domande che ti aiuteranno a decidere quale opzione PostgreSQL HA è migliore per la tua attività:

  • Quale livello di disponibilità speri di raggiungere? Hai bisogno di un'opzione che consenta al tuo servizio di continuare a funzionare solo in una singola zona o in caso di guasto regionale completo? Alcune opzioni di HA sono limitate a una regione, mentre altre possono essere multiregione.
  • Quali servizi o clienti si basano sul tuo livello di dati e qual è il costo per la tua attività in caso di tempi di riposo nel livello di persistenza dei dati? Se un servizio si rivolge solo a clienti interni che richiedono un utilizzo occasionale del sistema, probabilmente ha requisiti di disponibilità inferiori a quelli di un servizio rivolto ai clienti finali che li serve continuamente.
  • Qual è il tuo budget operativo? Il costo è un aspetto importante da considerare: per fornire l'HA, i costi di infrastruttura e archiviazione potrebbero aumentare.
  • Quanto deve essere automatizzato il processo e quanto velocemente deve essere eseguito il failover? (What is your RTO?) Le opzioni di HA variano in base alla rapidità con cui il sistema può eseguire il failover ed essere disponibile per i clienti.
  • Puoi permetterti di perdere dati a causa del failover? (Che cos'è il tuo RPD?) A causa della natura distribuita delle topologia ad alta disponibilità, esiste un compromesso tra la latenza del commit e il rischio di perdita di dati a causa di un errore.

Come funziona l'HA

Questa sezione descrive la replica in streaming e la replica in streaming sincrona alla base delle architetture HA di PostgreSQL.

Replica in streaming

La replica in streaming è un approccio di replica in cui la replica si connette all'istanza principale e riceve continuamente uno stream di record WAL. Rispetto alla replica con invio dei log, la replica in streaming consente alla replica di rimanere più aggiornata rispetto all'istanza principale. PostgreSQL offre la replica in streaming integrata a partire dalla versione 9. Molte soluzioni di disponibilità elevata PostgreSQL utilizzano la replica dinamica integrata per fornire il meccanismo per mantenere sincronizzati più nodi replica PostgreSQL con quello principale. Molte di queste opzioni sono descritte nella sezione Architetture HA PostgreSQL più avanti in questo documento.

Ogni nodo replica richiede risorse di calcolo e archiviazione dedicate. L'infrastruttura dei nodi di replica è indipendente da quella principale. Puoi utilizzare i nodi replica come hot standby per gestire le query dei client in sola lettura. Questo approccio consente il bilanciamento del carico delle query di sola lettura tra la principale e una o più repliche.

Per impostazione predefinita, la replica in streaming è asincrona; la replica principale non attende conferma da una replica prima di confermare l'commit di una transazione al client. Se un'istanza principale si arresta in modo anomalo dopo aver confermato la transazione, ma prima che una replica la riceva, la replica asincrona può comportare una perdita di dati. Se la replica viene promossa a diventare una nuova principale, questa transazione non sarà presente.

Replica sincrona in streaming

Puoi configurare la replica in streaming come sincrona scegliendo una o più repliche come standby sincrono. Se configuri l'architettura per la replica sincrona, il principale non conferma l'commit di una transazione fino a quando la replica non conferma la persistenza della transazione. La replica dinamica sincrona offre una maggiore durabilità in cambio di una maggiore latenza delle transazioni.

L'opzione di configurazione synchronous_commit consente inoltre di configurare i seguenti livelli di durabilità delle repliche progressive per la transazione:

  • local: le repliche di standby sincrone non sono coinvolte nell'acknowledgment del commit. Il principale conferma i commit delle transazioni dopo che i record WAL sono stati scritti e sottoposti a flush sul disco locale. I commit delle transazioni sull'istanza principale non coinvolgono le repliche di standby. Le transazioni possono andare perse se si verifica un errore sul database principale.
  • on [valore predefinito]: le repliche di standby sincrone scrivono le transazioni confermate nel proprio WAL prima di inviare l'acknowledgment al principale. L'utilizzo della configurazione on garantisce che la transazione possa andare persa solo se la replica principale e tutte le repliche di standby sincrone subiscono guasti di archiviazione simultanei. Poiché le repliche inviano un ack solo dopo aver scritto i record WAL, i client che eseguono query sulla replica non vedranno le modifiche finché i rispettivi record WAL non vengono applicati al database della replica.
  • remote_write: le repliche di standby sincrone confermano la ricezione del record WAL a livello di sistema operativo, ma non garantiscono che il record WAL sia stato scritto sul disco. Poiché remote_write non garantisce che il WAL sia stato scritto, la transazione può andare persa in caso di errori sia nel database principale che in quello secondario prima della scrittura dei record. remote_write ha una durata inferiore rispetto all'opzione on.
  • remote_apply: le repliche di standby sincrone confermano la ricezione della transazione e la sua applicazione riuscita al database prima di confermare l'commit della transazione al client. L'utilizzo della configurazione remote_apply assicura che la transazione venga mantenuta nella replica e che i risultati delle query del client includano immediatamente gli effetti della transazione. remote_apply offre maggiore durabilità e coerenza rispetto a on e remote_write.

L'opzione di configurazione synchronous_commit funziona con l'opzione di configurazione synchronous_standby_names che specifica l'elenco dei server di riserva che partecipano al processo di replica sincrona. Se non vengono specificati nomi di standby sincroni, i commit delle transazioni non aspettano la replica.

Architetture HA PostgreSQL

A livello più elementare, l'HA del livello di dati è costituito da:

  • Un meccanismo per identificare se si verifica un errore del nodo principale.
  • Una procedura per eseguire un failover in cui il nodo replica viene promosso a nodo principale.
  • Una procedura per modificare il routing delle query in modo che le richieste dell'applicazione raggiungano il nuovo nodo principale.
  • Facoltativamente, un metodo per eseguire il fallback all'architettura originale utilizzando i nodi principali e di replica pre-failover nelle loro capacità originali.

Le seguenti sezioni forniscono una panoramica delle seguenti architetture HA:

  • Il modello Patroni
  • Estensione e servizio pg_auto_failover
  • Gruppi di istanze gestite stateful e disco permanente a livello di regione

Queste soluzioni di HA riducono al minimo i tempi di inattività in caso di interruzione di servizio dell'infrastruttura o di una zona. Quando scegli tra queste opzioni, bilancia la latenza del commit e la durata in base alle esigenze della tua attività.

Un aspetto fondamentale di un'architettura HA è il tempo e lo sforzo manuale necessari per preparare un nuovo ambiente di standby per il successivo failover o il fallback. In caso contrario, il sistema può resistere a un solo errore e il servizio non è protetto da una violazione dello SLA. Ti consigliamo di selezionare un'architettura HA in grado di eseguire failover o switchover manuali con l'infrastruttura di produzione.

HA che utilizza il modello Patroni

Patroni è un modello di software open source (con licenza MIT) maturo e mantenuto attivamente che fornisce gli strumenti per configurare, eseguire il deployment e gestire un'architettura PostgreSQL HA. Patroni fornisce uno stato del cluster condiviso e una configurazione dell'architettura che viene mantenuta in un archivio di configurazione distribuito (DCS). Le opzioni per l'implementazione di un DCS includono: etcd, Consul, Apache ZooKeeper, o Kubernetes. Il seguente diagramma mostra i componenti principali di un cluster Patroni.

Un cluster Patroni prevede l'interazione tra i nodi PostgreSQL, il DCS e gli agenti Patroni.

Figura 1. Diagramma dei componenti principali di un cluster Patroni.

Nella figura 1, i bilanciatori del carico si trovano davanti ai nodi PostgreSQL, mentre gli agenti DCS e Patroni operano sui nodi PostgreSQL.

Patroni esegue un processo dell'agente su ogni nodo PostgreSQL. Il processo dell'agente gestisce il processo PostgreSQL e la configurazione del nodo dati. L'agente Patroni si coordina con gli altri nodi tramite il DCS. Il processo dell'agente Patroni inoltre espone un'API REST a cui puoi eseguire query per determinare l'integrità e la configurazione del servizio PostgreSQL per ogni nodo.

Per affermare il proprio ruolo di appartenenza al cluster, il nodo principale aggiorna regolarmente la chiave leader nel DCS. La chiave leader include un durata (TTL). Se il TTL scade senza un aggiornamento, la chiave leader viene espulsa dal DCS e inizia l'elezione del leader per selezionare un nuovo principale dal pool di candidati.

Il seguente diagramma mostra un cluster in buono stato in cui il nodo A aggiorna correttamente il blocco del leader.

Un leader di cluster in buono stato aggiorna il blocco del leader mentre i candidati leader guardano.

Figura 2. Diagramma di un cluster integro.

La Figura 2 mostra un cluster in buono stato: i nodi B e C osservano mentre il nodo A aggiorna correttamente la chiave leader.

Rilevamento di guasti

L'agente Patroni comunica continuamente il proprio stato aggiornando la propria chiave nel DCS. Allo stesso tempo, l'agente convalida l'integrità di PostgreSQL. Se l'agente rileva un problema, esegue l'isolamento autonomo del nodo spegnendosi o lo riduce a una replica. Come mostrato nel seguente diagramma, se il nodo con problemi è quello principale, la sua chiave leader nel DCS scade e viene eseguita una nuova elezione del leader.

Un cluster con problemi elegge un nuovo leader dopo la scadenza della chiave leader esistente.

Figura 3. Diagramma di un cluster con problemi.

La Figura 3 mostra un cluster con problemi: un nodo principale non attivo non ha aggiornato di recente la sua chiave leader nel DCS e le repliche non leader ricevono una notifica che indica che la chiave leader è scaduta.

Sugli host Linux, Patroni esegue anche un watchdog a livello di sistema operativo sui nodi principali. Questo watchdog è in ascolto per i messaggi keep-alive del processo dell'agente Patroni. Se il processo non risponde e il messaggio keep alive non viene inviato, il watchdog riavvia l'host. Il watchdog contribuisce a evitare una condizione di split brain in cui il nodo PostgreSQL continua a funzionare come principale, ma la chiave leader nel DCS è scaduta a causa del guasto dell'agente ed è stato eletto un altro principale (leader).

Procedura di failover

Se il blocco del leader scade nel DCS, i nodi replica candidati avviano un'elezione del leader. Quando una replica rileva un blocco del leader mancante, controlla la sua posizione di replica rispetto alle altre repliche. Ogni replica utilizza l'API REST per recuperare le posizioni dei log WAL degli altri nodi replica, come mostrato nel seguente diagramma.

Durante il processo di failover di Patroni, le repliche controllano la propria posizione nel log WAL.

Figura 4. Diagramma del processo di failover di Patroni.

La figura 4 mostra le query sulla posizione del log WAL e i rispettivi risultati dei nodi di replica attivi. Il nodo A non è disponibile e i nodi integri B e C restituiscono tra loro la stessa posizione WAL.

Il nodo più aggiornato (o i nodi se si trovano nella stessa posizione) tenta contemporaneamente di acquisire il blocco del leader nel DCS. Tuttavia, solo un node può creare la chiave leader nel DCS. Il primo nodo che crea correttamente la chiave leader è il vincitore della gara di leader, come mostrato nel seguente diagramma. In alternativa, puoi designare i candidati preferiti per il failover impostando il tag failover_priority nei file di configurazione.

Un nodo crea una chiave leader nel DCS e diventa il nuovo principale.

Figura 5. Diagramma della corsa del leader.

La figura 5 mostra una gara di leader: due leader candidati tentano di ottenere il blocco del leader, ma solo uno dei due nodi, il nodo C, imposta correttamente la chiave del leader e vince la gara.

Dopo aver vinto l'elezione del leader, la replica si autopromuove come nuova istanza principale. A partire dal momento in cui la replica si promuove, il nuovo principale aggiorna la chiave leader nel DCS per mantenere il blocco del leader e gli altri nodi fungono da repliche.

Patroni fornisce anche lo strumento di controllo patronictl che ti consente di eseguire switchover per testare la procedura di failover dei nodi. Questo strumento aiuta gli operatori a testare le configurazioni HA in produzione.

Routing delle query

Il processo dell'agente Patroni in esecuzione su ogni nodo espone endpoint API REST che rivelano il ruolo corrente del nodo: principale o replica.

Endpoint REST Codice di ritorno HTTP se principale Codice di ritorno HTTP se replica
/primary 200 503
/replica 503 200

Poiché i controlli di integrità pertinenti modificano le loro risposte se un determinato nodo cambia il proprio ruolo, un controllo di integrità del bilanciatore del carico può utilizzare questi endpoint per informare il routing del traffico dei nodi principali e delle repliche. Il progetto Patroni fornisce configurazioni di modelli per un bilanciatore del carico come HAProxy. Il bilanciatore del carico di rete passthrough interno può utilizzare gli stessi controlli di integrità per fornire funzionalità simili.

Procedura di riserva

In caso di errore del nodo, un cluster viene lasciato in uno stato di funzionamento ridotto. La procedura di fallback di Patroni consente di ripristinare lo stato di un cluster ad alta disponibilità dopo un failover. La procedura di fallback gestisce il ritorno del cluster allo stato originale inizializzando automaticamente il nodo interessato come replica del cluster.

Ad esempio, un nodo potrebbe riavviarsi a causa di un errore nel sistema operativo o nell'infrastruttura di base. Se il nodo è principale e il riavvio richiede più tempo del TTL della chiave del leader, viene attivata un'elezione del leader e viene selezionato e promosso un nuovo nodo principale. Quando viene avviato il processo Patroni principale inutilizzato, rileva che non ha il blocco del leader, si riduce automaticamente a una replica e si unisce al cluster in questa capacità.

Se si verifica un errore del nodo non recuperabile, ad esempio un'improbabile interruzione zonale, devi avviare un nuovo nodo. Un operatore di database può avviare manualmente un nuovo nodo oppure puoi utilizzare un gruppo di istanze gestite regionali con stato (MIG) con un numero minimo di nodi per automatizzare il processo. Dopo aver creato il nuovo nodo, Patroni rileva che fa parte di un cluster esistente e lo inizializza automaticamente come replica.

HA utilizzando l'estensione e il servizio pg_auto_failover

pg_auto_failover è un'estensione PostgreSQL open source (licenza PostgreSQL) in fase di sviluppo attivo. pg_auto_failover configura un'architettura HA estendendo le funzionalità PostgreSQL esistenti. pg_auto_failover non ha dipendenze diverse da PostgreSQL.

Per utilizzare l'estensione pg_auto_failover con un'architettura HA, sono necessari almeno tre nodi, ciascuno con PostgreSQL in esecuzione con l'estensione abilitata. Qualsiasi nodo può non riuscire senza influire sul tempo di attività del gruppo di database. Un insieme di nodi gestiti da pg_auto_failover è chiamato formazione. Il seguente diagramma mostra un'architettura pg_auto_failover.

Un'architettura pg_auto_failover contiene una formazione di nodi.

Figura 6. Diagramma di un'architettura pg_auto_failover.

La Figura 6 mostra un'architettura pg_auto_failover composta da due componenti principali: il servizio Monitor e l'agente Keeper. Sia Keeper che Monitor sono contenuti nell'estensione pg_auto_failover.

Monitorare il servizio

Il servizio di monitoraggio pg_auto_failover è implementato come estensione PostgreSQL. Quando il servizio crea un nodo di monitoraggio, avvia un'istanza PostgreSQL con l'estensione pg_auto_failover abilitata. Il Monitor gestisce lo stato globale per la formazione, ottiene lo stato del controllo dell'integrità dai nodi di dati PostgreSQL dei membri e orchestra il gruppo utilizzando le regole stabilite da una macchina a stati finiti (FSM). In base alle regole FSM per le transizioni di stato, il Monitor comunica istruzioni ai nodi di gruppo per azioni come promozione, retrocessione e modifiche alla configurazione.

Agente Keeper

Su ogni nodo di dati pg_auto_failover, l'estensione avvia un processo dell'agente Keeper. Questo processo Keeper osserva e gestisce il servizio PostgreSQL. Il guardiano invia aggiornamenti dello stato al nodo di monitoraggio e riceve ed esegue le azioni inviate dal monitoraggio in risposta.

Per impostazione predefinita, pg_auto_failover configura tutti i nodi di dati secondari del gruppo come repliche sincrone. Il numero di repliche sincrone richieste per un commit si basa sulla configurazione di number_sync_standby impostata sul monitoraggio.

Rilevamento di guasti

Gli agenti Keeper sui nodi di dati principali e secondari si connettono periodicamente al nodo Monitor per comunicare il loro stato corrente e verificare se sono presenti azioni da eseguire. Il nodo di monitoraggio si connette anche ai nodi di dati per eseguire un controllo di integrità mediante l'esecuzione di chiamate API del protocollo PostgreSQL (libpq), imitando l'applicazione client PostgreSQL pg_isready(). Se nessuna di queste azioni va a buon fine dopo un determinato periodo di tempo (30 secondi per impostazione predefinita), il nodo di monitoraggio determina che si è verificato un errore del nodo di dati. Puoi modificare le impostazioni di configurazione di PostgreSQL per personalizzare la temporizzazione del monitoraggio e il numero di nuovi tentativi. Per ulteriori informazioni, consulta Failover e tolleranza ai guasti.

Se si verifica un errore di un singolo nodo, una delle seguenti condizioni è vera:

  • Se il nodo di dati non in stato di salute è principale, il monitoraggio avvia un failover.
  • Se il nodo di dati non integro è secondario, il monitoraggio disattiva la replica sincrona per il nodo non integro.
  • Se il nodo con errore è il nodo di monitoraggio, il failover automatico non è possibile. Per evitare questo single point of failure, devi assicurarti che siano presenti il monitoraggio e il piano di risposta agli incidenti adeguati.

Il seguente diagramma mostra gli scenari di errore e gli stati del risultato della formazione descritti nell'elenco precedente.

Gli scenari di errore di pg_auto_failover per errori dei nodi principali, secondari e di monitoraggio.

Figura 7. Diagramma degli scenari di errore di pg_auto_failover.

Procedura di failover

Ogni nodo del database nel gruppo dispone delle seguenti opzioni di configurazione che determinano il processo di failover:

  • replication_quorum: un'opzione booleana. Se replication_quorum è impostato su true, il nodo è considerato un potenziale candidato per il failover
  • candidate_priority: un valore intero compreso tra 0 e 100. candidate_priority ha un valore predefinito di 50 che puoi modificare per influire sulla priorità del failover. I nodi vengono assegnati come potenziali candidati per il failover in base al valore candidate_priority. I nodi con un valore candidate_priority più elevato hanno una priorità maggiore. Il processo di failover richiede che almeno due nodi abbiano una priorità candidata non pari a zero in qualsiasi formazione pg_auto_failover.

In caso di guasto del nodo principale, i nodi secondari vengono presi in considerazione per la promozione a nodi principali se hanno la replica sincrona attiva e se sono membri del gruppo replication_quorum.

I nodi secondari vengono presi in considerazione per la promozione in base ai seguenti criteri progressivi:

  • Nodi con la priorità candidata più alta
  • In modalità standby con la posizione del log WAL più avanzata pubblicata nel Monitor
  • Selezione casuale come spareggio finale

Un candidato per il failover è un candidato in ritardo quando non ha pubblicato la posizione LSN più avanzata nel WAL. In questo scenario, pg_auto_failover orchestri un passaggio intermedio nel meccanismo di failover: il candidato in ritardo recupera i byte WAL mancanti da un nodo in standby con la posizione LSN più avanzata. Il nodo in standby viene quindi promosso. Postgres consente questa operazione perché la replica a cascata consente a qualsiasi standby di fungere da node upstream per un altro standby.

Routing delle query

pg_auto_failure non fornisce funzionalità di instradamento delle query lato server. Al contrario, pg_auto_failure si basa sull'instradamento delle query lato client che utilizza il driver client PostgreSQL ufficiale libpq. Quando definisci l'URI di connessione, il driver può accettare più host nella sua parola chiave host.

La libreria client utilizzata dall'applicazione deve eseguire il wrapping di libpq o implementare la possibilità di fornire più host affinché l'architettura supporti un failover completamente automatico.

Procedure di riserva e passaggio

Quando il processo Keeper riavvia un nodo non riuscito o avvia un nuovo nodo di sostituzione, controlla il nodo Monitor per determinare l'azione successiva da eseguire. Se un nodo riavviato e non riuscito era precedentemente principale e il Monitor ha già scelto un nuovo principale in base alla procedura di failover, il Keeper reinizializza questo principale inutilizzato come replica secondaria.

pg_auto_failure fornisce lo strumento pg_autoctl, che consente di eseguire passaggi per testare il processo di failover del nodo. Oltre a consentire agli operatori di testare le configurazioni HA in produzione, lo strumento consente di ripristinare un cluster HA in uno stato corretto dopo un failover.

HA utilizzando MIG stateful e disco permanente a livello di area geografica

Questa sezione descrive un approccio HA che utilizza i seguenti Google Cloud componenti:

  • disco permanente a livello di area geografica. Quando utilizzi i dischi permanenti a livello di area geografica, i dati vengono replicati in modo sincrono tra due zone di una regione, quindi non è necessario utilizzare la replica dinamica. Tuttavia, l'HA è limitato a esattamente due zone in una regione.
  • Gruppi di istanze gestite stateful. Una coppia di MIG con stato viene utilizzata all'interno di un piano di controllo per mantenere in esecuzione un nodo PostgreSQL principale. Quando il gruppo di istanze gestite stateful avvia una nuova istanza, può collegare il disco permanente regionale esistente. In un determinato momento, solo uno dei due MIG avrà un'istanza in esecuzione.
  • Cloud Storage. Un oggetto in un bucket Cloud Storage contiene una configurazione che indica su quale dei due MIG è in esecuzione il nodo del database principale e in quale MIG deve essere creata un'istanza di failover.
  • Controlli di integrità e riparazione automatica dei gruppi di istanze gestite. Il controllo di integrità monitora l'integrità dell'istanza. Se il nodo in esecuzione diventa non in stato di salute, il controllo di integrità avvia il processo di riparazione automatica.
  • Logging. Quando la riparazione automatica arresta il nodo principale, viene registrata una voce nel logging. Le voci di log pertinenti vengono esportate in un argomento sink Pub/Sub utilizzando un filtro.
  • Funzioni Cloud Run basate su eventi. Il messaggio Pub/Sub attiva le funzioni Cloud Run. Le funzioni Cloud Run utilizzano la configurazione in Cloud Storage per determinare quali azioni intraprendere per ogni MIG stateful.
  • Bilanciatore del carico di rete passthrough interno. Il bilanciatore del carico fornisce il routing all'istanza in esecuzione nel gruppo. In questo modo, la modifica dell'indirizzo IP di un'istanza causata dalla sua nuova creazione viene astratta dal client.

Il seguente diagramma mostra un esempio di HA che utilizza gruppi di istanze gestite stateful e dischi permanenti regionali:

Un'HA utilizza gruppi di istanze gestite stateful e dischi permanenti a livello di regione.

Figura 8. Diagramma di un HA che utilizza MIG stateful e dischi permanenti regionali.

La Figura 8 mostra un Nodo principale integro che gestisce il traffico dei client. I client si connettono all'indirizzo IP statico del bilanciatore del carico di rete passthrough interno. Il bilanciatore del carico instrada le richieste del client alla VM in esecuzione nell'ambito del gruppo MIG. I volumi di dati vengono memorizzati su dischi permanenti a livello di regione montati.

Per implementare questo approccio, crea un'immagine VM con PostgreSQL che si avvia all'inizializzazione da utilizzare come modello di istanza del gruppo di istanze gestite. Devi anche configurare un controllo di integrità basato su HTTP (ad esempio HAProxy o pgDoctor) sul nodo. Un controllo di integrità basato su HTTP contribuisce ad assicurare che sia il bilanciatore del carico sia il gruppo di istanze possano determinare l'integrità del nodo PostgreSQL.

Disco permanente regionale

Per eseguire il provisioning di un dispositivo di archiviazione a blocchi che fornisca la replica sincrona dei dati tra due zone in una regione, puoi utilizzare l'opzione di archiviazione disco permanente regionale di Compute Engine. Un disco permanente regionale può fornire un elemento di base per implementare un'opzione di disponibilità elevata PostgreSQL che non si basa sulla replica in streaming integrata di PostgreSQL.

Se l'istanza VM del nodo principale non è disponibile a causa di un errore dell'infrastruttura o di un'interruzione di servizio a livello di zona, puoi forzare il disco permanente regionale ad associarsi a un'istanza VM nella zona di backup nella stessa regione.

Per collegare il disco permanente regionale a un'istanza VM nella tua zona di backup, puoi eseguire una delle seguenti operazioni:

  • Mantieni un'istanza VM cold standby nella zona di backup. Un'istanza VM in standby a freddo è un'istanza VM arrestata a cui non è montato un disco permanente regionale, ma è un'istanza VM identica all'istanza VM del nodo principale. In caso di errore, viene avviata la VM in standby a freddo e viene montato il disco permanente regionale. L'istanza di standby freddo e l'istanza del nodo principale hanno gli stessi dati.
  • Crea una coppia di gruppi di istanze gestite stateful utilizzando lo stesso modello di istanza. I gruppi MIG forniscono controlli di integrità e fanno parte del piano di controllo. Se il nodo principale non funziona, viene creata un'istanza di failover nel MIG di destinazione in modo dichiarativo. L'MIG di destinazione è definito nell'oggetto Cloud Storage. Per associare il disco permanente regionale viene utilizzata una configurazione per istanza.

Se l'interruzione del servizio dati viene identificata tempestivamente, l'operazione di attacco forzato solitamente si completa in meno di un minuto, pertanto è possibile ottenere un RTO misurato in minuti.

Se la tua attività può tollerare il tempo di riposo aggiuntivo necessario per rilevare e comunicare un'interruzione e per eseguire il failover manualmente, non è necessario automatizzare la procedura di attacco forzato. Se la tolleranza RTO è inferiore, puoi automatizzare il processo di rilevamento e failover. In alternativa, Cloud SQL per PostgreSQL fornisce anche un'implementazione completamente gestita di questo approccio HA.

Rilevamento degli errori e processo di failover

L'approccio HA utilizza le funzionalità di riparazione automatica dei gruppi di istanze per monitorare l'integrità dei nodi utilizzando un controllo di integrità. Se un controllo di integrità non riesce, l'istanza esistente viene considerata non integra e viene interrotta. Questa interruzione avvia il processo di failover utilizzando logging, Pub/Sub e la funzione Cloud Run Functions attivata.

Per soddisfare il requisito che questa VM abbia sempre il disco regionale montato, uno dei due MIG verrà configurato dalle funzioni Cloud Run per creare un'istanza in una delle due zone in cui è disponibile il disco permanente regionale. In caso di guasto di un nodo, l'istanza sostitutiva viene avviata in base allo stato mantenuto in Cloud Storage nella zona alternativa.

Durante un errore a livello di zona, viene avviata un'istanza sostitutiva.

Figura 9. Diagramma di un errore zonale in un gruppo di istanze gestite.

Nella figura 9, l'ex nodo principale nella zona A ha riscontrato un errore e le funzioni Cloud Run hanno configurato il gruppo di istanze gestite B per lanciare una nuova istanza principale nella zona B. Il meccanismo di rilevamento degli errori viene configurato automaticamente per monitorare la salute del nuovo nodo principale.

Routing delle query

Il bilanciatore del carico di rete passthrough interno instrada i client all'istanza su cui è in esecuzione il servizio PostgreSQL. Il bilanciatore del carico utilizza lo stesso controllo di integrità del gruppo di istanze per determinare se l'istanza è disponibile per l'elaborazione delle query. Se il nodo non è disponibile perché è in fase di ricreazione, le connessioni non riescono. Una volta ripristinata l'istanza, i controlli di integrità iniziano a essere superati e le nuove connessioni vengono instradate al nodo disponibile. In questa configurazione non sono presenti nodi di sola lettura perché è presente un solo nodo in esecuzione.

Procedura di riserva

Se il nodo del database non supera un controllo di integrità a causa di un problema hardware di base, il nodo viene ricreato in un'istanza di base diversa. A questo punto, l'architettura torna allo stato originale senza ulteriori passaggi. Tuttavia, in caso di errore zonale, la configurazione continua a funzionare in uno stato di degradamento fino al recupero della prima zona. Anche se altamente improbabile, se si verificano errori simultanei in entrambe le zone configurate per la replica dei Persistent Disk a livello di regione e per gli MIG stateful, l'istanza PostgreSQL non può recuperare e il database non è disponibile per l'elaborazione delle richieste durante l'interruzione.

Confronto tra le opzioni di HA

Le seguenti tabelle forniscono un confronto delle opzioni di HA disponibili da Patroni, pg_auto_failover e MIG stateful con dischi permanenti regionali.

Configurazione e architettura

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione

Richiede un'architettura HA, la configurazione del DCS, il monitoraggio e gli avvisi. La configurazione dell'agente sui nodi di dati è relativamente semplice.

Non richiede dipendenze esterne diverse da PostgreSQL. Richiede un nodo dedicato come monitor. Il nodo di monitoraggio richiede HA e RE per garantire che non sia un singolo punto di défaillance (SPOF). Architettura costituita esclusivamente da Google Cloud servizi. Esegui un solo nodo del database attivo alla volta.

Configurabilità dell'alta disponibilità

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione
Estremamente configurabile: supporta sia la replica sincrona sia quella asincrona e consente di specificare quali nodi devono essere sincroni e asincroni. Include la gestione automatica dei nodi sincroni. Consente configurazioni HA multi-zona e multi-regione. Il DCS deve essere accessibile. Simile a Patroni: molto configurabile. Tuttavia, poiché il monitor è disponibile solo come singola istanza, qualsiasi tipo di configurazione deve considerare l'accesso a questo nodo. Limitato a due zone in una singola regione con replica sincrona.

Possibilità di gestire la partizione della rete

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione
La recinzione virtuale e un monitoraggio a livello di sistema operativo forniscono protezione contro la situazione di split brain. Qualsiasi mancata connessione al DCS comporta la disinstallazione della versione principale come replica e l'attivazione di un failover per garantire la durabilità rispetto alla disponibilità. Utilizza una combinazione di controlli di integrità dal principale al monitor e alla replica per rilevare una partizione di rete e si esegue la retrocessione se necessario. Non applicabile: è attivo un solo nodo PostgreSQL alla volta, quindi non esiste una partizione di rete.

Costo

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione
Costo elevato perché dipende dal DCS scelto e dal numero di repliche PostgreSQL. L'architettura di Patroni non comporta costi significativi. Tuttavia, la spesa complessiva è influenzata dall'infrastruttura di base, che utilizza più istanze di calcolo per PostgreSQL e il DCS. Poiché utilizza più repliche e un cluster DCS separato, questa opzione può essere la più costosa. Costo medio perché prevede l'esecuzione di un nodo di monitoraggio e di almeno tre nodi PostgreSQL (uno principale e due repliche). Basso costo perché in un determinato momento è in esecuzione solo un nodo PostgreSQL. Paghi solo per una singola istanza di calcolo.

Configurazione client

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione
Trasparente per il client perché si connette a un bilanciatore del carico. Richiede che la libreria client supporti la definizione di più host nella configurazione perché non è facilmente supportata da un bilanciatore del carico. Trasparente per il client perché si connette a un bilanciatore del carico.

Scalabilità

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione
Elevata flessibilità nella configurazione per i compromessi tra scalabilità e disponibilità. La scalabilità in lettura è possibile aggiungendo altre repliche. Come Patroni: la scalabilità delle letture è possibile aggiungendo altre repliche. Scalabilità limitata a causa della presenza di un solo nodo PostgreSQL attivo alla volta.

Automatizzazione dell'inizializzazione e della gestione della configurazione dei nodi PostgreSQL

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione
Fornisce strumenti per gestire la configurazione di PostgreSQL (patronictl edit-config) e inizializza automaticamente i nuovi nodi o quelli riavviati nel cluster. Puoi inizializzare i nodi utilizzando pg_basebackup o altri strumenti come barman. Inizializza automaticamente i nodi, ma è limitato all'utilizzo di pg_basebackup solo durante l'inizializzazione di un nuovo nodo replica. La gestione della configurazione è limitata alle configurazioni correlate a pg_auto_failover. Il gruppo di istanze con stato e disco condiviso elimina la necessità di inizializzare il nodo PostgreSQL. Poiché è sempre in esecuzione un solo nodo, la gestione delle configurazioni avviene su un singolo nodo.

Personalizzazione e ricchezza di funzionalità

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione

Fornisce un'interfaccia di hook per consentire di chiamare azioni definibili dall'utente in fasi chiave, ad esempio in caso di retrocessione o promozione.

Configurabilità completa, ad esempio il supporto di diversi tipi di DCS, metodi diversi per inizializzare le repliche e modi diversi per fornire la configurazione di PostgreSQL.

Consente di configurare cluster di riserva che consentono di creare cluster con replica a cascata per semplificare la migrazione tra cluster.

Limitato perché è un progetto relativamente nuovo. Non applicabile.

Maturità

Patroni pg_auto_failover Gruppi di istanze gestite stateful con dischi permanenti a livello di regione
Il progetto è disponibile dal 2015 e viene utilizzato in produzione da grandi aziende come Zalando e GitLab. Progetto relativamente nuovo annunciato all'inizio del 2019. Composto interamente da prodotti Google Cloud in disponibilità generale.

Best practice per la manutenzione e il monitoraggio

La manutenzione e il monitoraggio del cluster PostgreSQL HA sono fondamentali per garantire un'alta disponibilità, l'integrità dei dati e prestazioni ottimali. Le seguenti sezioni forniscono alcune best practice per il monitoraggio e la manutenzione di un cluster PostgreSQL HA.

Esegui backup regolari e test di ripristino

Esegui regolarmente il backup dei database PostgreSQL e testa la procedura di recupero. In questo modo, contribuisci a garantire l'integrità dei dati e riduci al minimo i tempi di inattività in caso di interruzione del servizio. Testa la procedura di recupero per convalidare i backup e identificare potenziali problemi prima che si verifichi un'interruzione del servizio.

Monitora i server PostgreSQL e il ritardo nella replica

Monitora i server PostgreSQL per verificare che siano in esecuzione. Monitora il ritardo della replica tra i nodi principali e di replica. Un ritardo eccessivo può portare a incoerenze nei dati e a un aumento della perdita di dati in caso di failover. Configura gli avvisi per aumenti significativi del tempo di latenza e indaga immediatamente sulla causa principale. L'utilizzo di visualizzazioni come pg_stat_replication e pg_replication_slots può aiutarti a monitorare il ritardo della replica.

Implementare il pool di connessioni

Il pool di connessioni può aiutarti a gestire in modo efficiente le connessioni al database. Il pool di connessioni contribuisce a ridurre l'overhead di creazione di nuove connessioni, migliorando le prestazioni dell'applicazione e la stabilità del server di database. Strumenti come PGBouncer e Pgpool-II possono fornire il pooling delle connessioni per PostgreSQL.

Implementa un monitoraggio completo

Per ottenere informazioni sui cluster PostgreSQL HA, crea sistemi di monitoraggio efficaci come segue:

  • Monitora le metriche chiave di PostgreSQL e del sistema, come l'utilizzo della CPU, l'utilizzo della memoria, l'I/O del disco, l'attività di rete e le connessioni attive.
  • Raccogli i log PostgreSQL, inclusi i log del server, i log WAL e i log autovacuum, per analisi approfondite e risoluzione dei problemi.
  • Utilizza gli strumenti di monitoraggio e le dashboard per visualizzare metriche e log al fine di identificare rapidamente i problemi.
  • Integra le metriche e i log con i sistemi di avviso per ricevere notifiche proattive su potenziali problemi.

Per ulteriori informazioni sul monitoraggio di un'istanza Compute Engine, consulta la panoramica di Cloud Monitoring.

Passaggi successivi

Collaboratori

Autore: Alex Cârciu | Solutions Architect