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 affidabilità (HA) per i deployment PostgreSQL su Google Cloud. L'alta affidabilità è la misura della resilienza del sistema in risposta a un errore dell'infrastruttura sottostante. In questo documento, HA si riferisce alla disponibilità dei cluster PostgreSQL all'interno di una singola regione cloud o tra più regioni, a seconda dell'architettura HA.

Questo documento è rivolto ad amministratori di database, cloud architect e DevOps engineer che vogliono scoprire come aumentare l'affidabilità del livello dati di PostgreSQL migliorando l'uptime complessivo del sistema. Questo documento illustra i concetti relativi all'esecuzione di PostgreSQL su Compute Engine. Il documento non tratta 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 (il livello dati) deve essere disponibile per gestire correttamente le richieste di query o mutazioni dei dati. I tempi di inattività nel livello dati impediscono al sistema o all'applicazione di eseguire le attività necessarie.

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

Questo documento tratta i seguenti argomenti:

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

Terminologia

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

replica
Il processo mediante il quale le transazioni di scrittura (INSERT, UPDATE o DELETE) e le modifiche allo schema (linguaggio di definizione dei dati (DDL)) vengono acquisite, registrate e applicate in serie in modo affidabile a tutti i nodi di replica del database downstream nell'architettura.
nodo principale
Il nodo che fornisce una lettura con lo stato più aggiornato dei dati permanenti. Tutte le scritture nel database devono essere indirizzate a un nodo principale.
nodo di replica (secondario)
Una copia online del nodo del database primario. Le modifiche vengono replicate in modo sincrono o asincrono nei nodi di replica dal nodo primario. Puoi leggere dai nodi di replica, tenendo presente che i dati potrebbero essere leggermente ritardati 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 write-ahead log (WAL) è un file di log che registra le modifiche ai file di dati prima che vengano effettivamente apportate. In caso di arresto anomalo del server, il WAL è un modo standard per garantire l'integrità dei dati e la durabilità delle scritture.
Record WAL
Un record di una transazione applicata al database. Un record WAL viene formattato e archiviato come una serie di record che descrivono le modifiche a livello di pagina dei 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). La "Z" rappresenta la posizione di offset nel file WAL.
file di segmento
File che contengono il maggior numero possibile di record WAL, a seconda delle dimensioni del file configurate. I file di segmento hanno nomi file che aumentano monotonicamente e una dimensione file 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 modalità flusso, puoi utilizzare l'opzione synchronous_commit di PostgreSQL, che contribuisce a 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 transazioni di cui è stato eseguito il commit non vengono trasferite alla replica, esiste la possibilità di perdita di dati. La replica asincrona è la modalità di replica predefinita su PostgreSQL, che utilizza la spedizione dei log basata 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 di database primario alla replica. Il server principale opera in modalità di archiviazione continua, mentre ogni servizio in standby opera in modalità Recovery [Recovery mode] continua per leggere i file WAL. Questo tipo di replica è asincrono.
replica di flussi di dati
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 con invio dei log. Sebbene la replica sia asincrona per impostazione predefinita, in alternativa puoi configurare la replica sincrona.
replica di flussi di dati fisici
Un metodo di replica che trasferisce le modifiche alla replica. Questo metodo utilizza i record WAL che contengono le modifiche ai dati fisici sotto forma di indirizzi dei blocchi del disco e modifiche byte per byte.
replica di flussi logici
Un metodo di replica che acquisisce le modifiche in base alla loro identità di replica (chiave primaria), che consente un maggiore controllo sulla modalità di replica dei dati 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 ad alta affidabilità. Questa guida illustra la replica fisica standard e non la replica logica.
uptime
La percentuale di tempo in cui una risorsa è in esecuzione ed è in grado di fornire una risposta a una richiesta.
rilevamento errori
Il processo di identificazione di un errore dell'infrastruttura.
failover
Il processo di promozione dell'infrastruttura di backup o di standby (in questo caso, il nodo di replica) per diventare l'infrastruttura principale. Durante il failover, il nodo di replica diventa il nodo principale.
switchover
La procedura per eseguire un failover manuale su un sistema di produzione. Uno switchover verifica che il sistema funzioni correttamente o rimuove il nodo principale corrente dal cluster per la manutenzione.
Recovery Time Objective (RTO)
La durata in tempo reale trascorsa per il completamento del processo di failover del livello dati. L'RTO dipende dalla quantità 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 dati deve sostenere in seguito al failover. L'RPO dipende dalla quantità di perdita di dati accettabile dal punto di vista aziendale.
fallback
Il processo di reintegrazione del nodo principale precedente dopo che è stata risolta la condizione che ha causato un failover.
riparazione automatica
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 principale e di replica, non possono comunicare tra loro tramite la rete.
split brain
Una condizione che si verifica quando due nodi ritengono contemporaneamente di essere il nodo principale.
gruppo di nodi
Un insieme di risorse di computing che forniscono un servizio. In questo documento, il servizio è il livello di persistenza dei dati.
nodo witness o quorum
Una risorsa di computing separata che aiuta un gruppo di nodi a determinare cosa fare quando si verifica una condizione di split-brain.
elezione del nodo primario o leader
Il processo mediante il quale un gruppo di nodi peer-aware, inclusi i nodi witness, determina quale nodo deve essere il nodo principale.

Quando prendere in considerazione un'architettura ad alta affidabilità

Le architetture ad alta affidabilità offrono una maggiore protezione contro i tempi di inattività del livello dati rispetto alle configurazioni di database a nodo singolo. Per selezionare l'opzione migliore per il tuo caso d'uso aziendale, devi comprendere la tua tolleranza ai tempi di inattività e i rispettivi compromessi delle varie architetture.

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

Considera i tuoi requisiti per l'alta affidabilità

Di seguito sono riportate alcune domande che ti aiuteranno a decidere quale opzione di alta affidabilità di PostgreSQL è più adatta alla 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 caso di errore in una singola zona o in un'intera regione? Alcune opzioni di alta affidabilità sono limitate a una regione, mentre altre possono essere multiregionali.
  • Quali servizi o clienti si affidano al tuo livello dati e qual è il costo per la tua attività in caso di tempi di inattività 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 rispetto a un servizio rivolto ai clienti finali che li serve continuamente.
  • Qual è il tuo budget operativo? Il costo è un fattore importante da considerare: per fornire l'alta affidabilità, è probabile che i costi dell'infrastruttura e dello spazio di archiviazione aumentino.
  • Quanto deve essere automatizzato il processo e quanto velocemente devi eseguire il failover? (Qual è il tuo RTO?) Le opzioni di alta affidabilità 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 seguito del failover? (Qual è il tuo RPO?) A causa della natura distribuita delle topologie ad alta affidabilità, esiste un compromesso tra la latenza di commit e il rischio di perdita di dati a causa di un errore.

Come funziona l'HA

Questa sezione descrive la replica in modalità flusso e in modalità flusso 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 un flusso di record WAL. Rispetto alla replica con log shipping, 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 ad alta affidabilità di PostgreSQL utilizzano la replica in streaming integrata per fornire il meccanismo per mantenere sincronizzati più nodi di replica PostgreSQL con il nodo principale. Alcune di queste opzioni sono descritte nella sezione Architetture PostgreSQL HA più avanti in questo documento.

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

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

Replica di flussi di dati sincrona

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

L'opzione di configurazione synchronous_commit consente inoltre di configurare i seguenti livelli di durabilità della replica progressiva per la transazione:

  • localLe repliche di standby sincrone non sono coinvolte nella conferma di commit. L'istanza principale conferma i commit delle transazioni dopo che i record WAL sono stati scritti e scaricati sul disco locale. I commit delle transazioni sulla replica principale non coinvolgono le repliche in standby. Le transazioni possono andare perse se si verifica un errore nell'istanza principale.
  • on [valore predefinito]: le repliche in standby sincrone scrivono le transazioni di cui è stato eseguito il commit nel proprio WAL prima di inviare la conferma all'istanza principale. L'utilizzo della configurazione on garantisce che la transazione possa essere persa solo se la replica principale e tutte le repliche in standby sincrone subiscono errori di archiviazione simultanei. Poiché le repliche inviano una conferma solo dopo aver scritto i record WAL, i client che eseguono query sulla replica non vedranno le modifiche finché i rispettivi record WAL non verranno applicati al database della replica.
  • remote_write: le repliche in 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 se si verifica un errore sia nell'istanza principale che in quella secondaria prima che i record vengano scritti. remote_write ha una durabilità inferiore rispetto all'opzione on.
  • remote_apply: le repliche in standby sincrone confermano la ricezione della transazione e l'applicazione corretta al database prima di confermare il commit della transazione al client. L'utilizzo della configurazione remote_apply garantisce 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 standby che partecipano al processo di replica sincrona. Se non vengono specificati nomi di standby sincroni, i commit delle transazioni non attendono la replica.

Architetture HA PostgreSQL

Al livello più elementare, l'HA del livello dati è costituita da:

  • Un meccanismo per identificare se si verifica un errore del nodo principale.
  • Un processo per eseguire un failover in cui il nodo di replica viene promosso a nodo principale.
  • Un processo 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 primari e di replica pre-failover nelle loro capacità originali.

Le sezioni seguenti forniscono una panoramica delle seguenti architetture ad alta affidabilità:

  • Il template Patroni
  • Estensione e servizio pg_auto_failover
  • MIG stateful e disco permanente a livello di regione

Queste soluzioni ad alta affidabilità riducono al minimo i tempi di inattività in caso di interruzione dell'infrastruttura o della zona. Quando scegli tra queste opzioni, bilancia la latenza di commit e la durabilità in base alle tue esigenze aziendali.

Un aspetto critico di un'architettura ad alta affidabilità è il tempo e l'impegno manuale necessari per preparare un nuovo ambiente di standby per il failover o il fallback successivo. 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 ad alta affidabilità in grado di eseguire failover o switchover manuali con l'infrastruttura di produzione.

HA utilizzando il template Patroni

Patroni è un modello software open source (con licenza MIT) maturo e gestito attivamente che fornisce gli strumenti per configurare, eseguire il deployment e gestire un'architettura PostgreSQL ad alta affidabilità. 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 il DCS e gli agenti Patroni operano sui nodi PostgreSQL.

Patroni esegue un processo agente su ogni nodo PostgreSQL. Il processo dell'agente gestisce il processo PostgreSQL e la configurazione del nodo di dati. L'agente Patroni si coordina con altri nodi tramite il DCS. Il processo dell'agente Patroni espone anche un'API REST su cui puoi eseguire query per determinare la Service Health e la configurazione del servizio PostgreSQL per ogni nodo.

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

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

Un leader del cluster integro aggiorna il blocco del leader mentre i candidati leader osservano.

Figura 2. Diagramma di un cluster integro.

La Figura 2 mostra un cluster integro: il nodo B e il nodo C osservano mentre il nodo A aggiorna correttamente la chiave leader.

Rilevamento errori

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, isola il nodo arrestandosi o retrocede il nodo a una replica. Come mostrato nel seguente diagramma, se il nodo compromesso è quello principale, la sua chiave leader nel DCS scade e viene eseguita una nuova elezione del leader.

Un cluster compromesso elegge un nuovo leader dopo la scadenza della chiave del leader esistente.

Figura 3. Diagramma di un cluster compromesso.

La Figura 3 mostra un cluster compromesso: un nodo principale inattivo 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.

Sui sistemi host Linux, Patroni esegue anche un watchdog a livello di sistema operativo sui nodi principali. Questo watchdog rimane in ascolto dei messaggi keep-alive provenienti dal processo dell'agente Patroni. Se il processo non risponde e l'keepalive non viene inviato, il watchdog riavvia l'host. Il watchdog aiuta a prevenire una condizione di split brain in cui il nodo PostgreSQL continua a fungere da nodo principale, ma la chiave leader nel DCS è scaduta a causa di un errore dell'agente ed è stato eletto un nodo principale (leader) diverso.

Processo di failover

Se il blocco del leader scade nel DCS, i nodi di 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 ottenere le posizioni dei log WAL degli altri nodi di replica, come mostrato nel seguente diagramma.

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

Immagine 4. Diagramma del processo di failover di Patroni.

La Figura 4 mostra le query sulla posizione del log WAL e i rispettivi risultati dai nodi di replica attivi. Il nodo A non è disponibile e i nodi integri B e C restituiscono la stessa posizione WAL l'uno all'altro.

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 nodo può creare la chiave leader nel DCS. Il primo nodo che crea correttamente la chiave leader è il vincitore della gara per il ruolo di leader, come mostrato nel seguente diagramma. In alternativa, puoi designare i candidati di failover preferiti impostando il tag failover_priority nei file di configurazione.

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

Figura 5. Diagramma della gara dei leader.

La Figura 5 mostra una gara per la leadership: due candidati leader cercano 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.

Una volta vinta l'elezione del leader, la replica si promuove a nuova istanza principale. A partire dal momento in cui la replica viene promossa, la nuova istanza principale aggiorna la chiave leader nel DCS per mantenere il blocco leader e gli altri nodi fungono da repliche.

Patroni fornisce anche lo strumento di controllo patronictl che consente di eseguire i cambi per testare il processo di failover dei nodi. Questo strumento aiuta gli operatori a testare le configurazioni HA in produzione.

Routing delle query

Il processo dell'agente Patroni eseguito su ogni nodo espone gli endpoint API REST che rivelano il ruolo del nodo corrente: primario o replica.

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

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

Procedura di riserva

Se si verifica un errore del nodo, il cluster rimane in uno stato di funzionamento ridotto. La procedura di fallback di Patroni aiuta a ripristinare lo stato di integrità di un cluster ad alta disponibilità dopo un failover. Il processo 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 sottostante. Se il nodo è il nodo principale e impiega più tempo del TTL della chiave leader per riavviarsi, viene attivata un'elezione del leader e viene selezionato e promosso un nuovo nodo principale. Quando viene avviato il processo Patroni principale non aggiornato, rileva che non ha il blocco leader, si retrocede automaticamente a replica e si unisce al cluster in questa capacità.

Se si verifica un errore del nodo non recuperabile, ad esempio un improbabile errore a livello di zona, devi avviare un nuovo nodo. Un operatore di database può avviare manualmente un nuovo nodo oppure puoi utilizzare un gruppo di istanze gestite (MIG) regionale stateful con un numero minimo di nodi per automatizzare il processo. Dopo la creazione del nuovo nodo, Patroni rileva che il nuovo nodo 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 ad alta affidabilità estendendo le funzionalità PostgreSQL esistenti. pg_auto_failover non ha dipendenze diverse da PostgreSQL.

Per utilizzare l'estensione pg_auto_failover con un'architettura ad alta affidabilità, devi avere almeno tre nodi, ciascuno con PostgreSQL in esecuzione con l'estensione abilitata. Qualsiasi nodo può non funzionare senza influire sull'uptime del gruppo di database. Una raccolta di nodi gestiti da pg_auto_failover è chiamata formazione. Il seguente diagramma mostra un'architettura pg_auto_failover.

Un'architettura pg_auto_failover contiene una formazione di nodi.

Immagine 6. Diagramma di un'architettura pg_auto_failover.

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

Monitora il servizio

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

Agente Keeper

In ogni nodo dati pg_auto_failover, l'estensione avvia un processo dell'agente Keeper. Questo processo Keeper osserva e gestisce il servizio PostgreSQL. Il Keeper invia aggiornamenti di stato al nodo Monitor e riceve ed esegue le azioni che il Monitor invia 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 number_sync_standby impostata sul monitor.

Rilevamento errori

Gli agenti Keeper sui nodi di dati principali e secondari si connettono periodicamente al nodo Monitor per comunicare il loro stato attuale e verificare se sono presenti azioni da eseguire. Il nodo Monitor si connette anche ai nodi dati per eseguire un controllo di integrità eseguendo le chiamate API del protocollo PostgreSQL (libpq), imitando l'applicazione client PostgreSQL pg_isready(). Se nessuna di queste azioni ha esito positivo dopo un periodo di tempo (30 secondi per impostazione predefinita), il nodo Monitor determina che si è verificato un errore del nodo dati. Puoi modificare le impostazioni di configurazione di PostgreSQL per personalizzare i tempi di monitoraggio e il numero di nuovi tentativi. Per saperne di più, consulta Failover e tolleranza di errore.

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

  • Se il nodo dati non integro è un nodo primario, il monitor avvia un failover.
  • Se il nodo dati non integro è un nodo secondario, il monitor disattiva la replica sincrona per il nodo non integro.
  • Se il nodo con errori è il nodo Monitor, il failover automatico non è possibile. Per evitare questo single point of failure, devi assicurarti che siano in atto il monitoraggio e il ripristino di emergenza corretti.

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

Gli scenari di errore di pg_auto_failover per gli errori dei nodi primario, secondario e di monitoraggio.

Immagine 7. Diagramma degli scenari di errore di pg_auto_failover.

Processo di failover

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

  • replication_quorum: un'opzione booleana. Se replication_quorum è impostato su true, il nodo viene 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à di failover. La priorità dei nodi come potenziali candidati per il failover viene stabilita in base al valore candidate_priority. I nodi con un valore candidate_priority più alto hanno una priorità più alta. Il processo di failover richiede che almeno due nodi abbiano una priorità candidata diversa da zero in qualsiasi formazione pg_auto_failover.

In caso di errore del nodo principale, i nodi secondari vengono presi in considerazione per la promozione a principale se hanno una replica sincrona attiva e se sono membri di 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
  • Standby con la posizione del log WAL più avanzata pubblicata nel monitor
  • Selezione casuale come spareggio finale

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

Routing delle query

pg_auto_failure non fornisce funzionalità di routing delle query lato server. Invece, pg_auto_failure si basa sul routing 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 parola chiave host.

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

Processi di fallback e switchover

Quando il processo Keeper riavvia un nodo con errori o avvia un nuovo nodo sostitutivo, controlla il nodo Monitor per determinare l'azione successiva da eseguire. Se un nodo in errore riavviato era in precedenza il nodo principale e il Monitor ha già scelto un nuovo nodo principale in base al processo di failover, il Keeper reinizializza questo nodo principale obsoleto come replica secondaria.

pg_auto_failure fornisce lo strumento pg_autoctl, che consente di eseguire i cambi per testare il processo di failover dei nodi. Oltre a consentire agli operatori di testare le configurazioni HA in produzione, lo strumento ti aiuta a ripristinare lo stato di integrità di un cluster HA dopo un failover.

HA utilizzando MIG stateful e un disco permanente a livello di regione

Questa sezione descrive un approccio ad alta affidabilità che utilizza i seguenti componenti Google Cloud:

  • Persistent Disk a livello di regione. Quando utilizzi i Persistent Disk a livello di regione, i dati vengono replicati in modo sincrono tra due zone di una regione, quindi non è necessario utilizzare la replica in streaming. Tuttavia, l'alta disponibilità è limitata esattamente a due zone in una regione.
  • Gruppi di istanze gestite stateful. Una coppia di MIG stateful viene utilizzata come parte di un control plane per mantenere in esecuzione un nodo PostgreSQL principale. Quando il MIG stateful avvia una nuova istanza, può collegare il disco permanente regionale esistente. In un singolo 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 quale dei due MIG esegue il nodo del database primario e in quale MIG deve essere creata un'istanza di failover.
  • Controlli di integrità e ripristino automatico dei MIG. Il controllo di integrità monitora l'integrità delle istanze. Se il nodo in esecuzione non è integro, il controllo di integrità avvia il processo di riparazione automatica.
  • Logging. Quando il ripristino automatico arresta il nodo principale, viene registrata una voce in Logging. Le voci di log pertinenti vengono esportate in un argomento sink Pub/Sub utilizzando un filtro.
  • Cloud Run Functions basate su eventi. Il messaggio Pub/Sub attiva Cloud Run Functions. Cloud Run Functions utilizza la configurazione in Cloud Storage per determinare le azioni da 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 ricreazione dell'istanza viene astratta dal client.

Il seguente diagramma mostra un esempio di HA che utilizza MIG stateful e Persistent Disk regionali:

Un'architettura ad alta affidabilità utilizza MIG stateful e Persistent Disk a livello di regione.

Immagine 8. Diagramma di un'architettura ad alta affidabilità che utilizza MIG stateful e dischi permanenti a livello di regione.

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 dei client alla VM in esecuzione come parte del MIG. I volumi di dati sono archiviati su Persistent Disk a livello di regione montati.

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

Disco permanente a livello di regione

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

Se l'istanza VM del nodo primario non è disponibile a causa di un errore dell'infrastruttura o di un'interruzione a livello di zona, puoi forzare il collegamento del disco permanente regionale a un'istanza VM nella zona di backup all'interno della stessa regione.

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

  • Mantieni un'istanza VM di cold standby nella zona di backup. Un'istanza VM di standby cold è un'istanza VM arrestata su cui non è montato un Persistent Disk regionale, ma è un'istanza VM identica all'istanza VM del nodo primario. In caso di errore, la VM cold standby viene avviata e il disco permanente regionale viene montato su di essa. L'istanza in standby cold e l'istanza del nodo primario hanno gli stessi dati.
  • Crea una coppia di MIG stateful utilizzando lo stesso template di istanza. I MIG forniscono controlli di integrità e fungono da parte del control plane. Se il nodo principale non funziona, viene creata un'istanza di failover nel MIG di destinazione in modo dichiarativo. Il MIG di destinazione è definito nell'oggetto Cloud Storage. Per collegare il disco permanente regionale viene utilizzata una configurazione per istanza.

Se l'interruzione del servizio dati viene identificata tempestivamente, l'operazione di collegamento forzato viene in genere completata in meno di un minuto, per cui è possibile ottenere un RTO misurato in minuti.

Se la tua attività può tollerare il tempo di inattività aggiuntivo necessario per rilevare e comunicare un'interruzione e per eseguire il failover manualmente, non è necessario automatizzare il processo di collegamento forzato. Se la tua tolleranza per l'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 ad alta affidabilità.

Rilevamento degli errori e processo di failover

L'approccio HA utilizza le funzionalità di ripristino automatico dei gruppi di istanze per monitorare l'integrità dei nodi utilizzando un controllo di integrità. Se un controllo di integrità non va a buon fine, l'istanza esistente viene considerata non integra e viene arrestata. Questo arresto 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 a livello di regione montato, uno dei due MIG verrà configurato da Cloud Run Functions per creare un'istanza in una delle due zone in cui è disponibile il disco permanente a livello di regione. In caso di errore di un nodo, l'istanza sostitutiva viene avviata nella zona alternativa, in base allo stato persistente in Cloud Storage.

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

Figura 9. Diagramma di un errore a livello di zona in un MIG.

Nella figura 9, il nodo principale precedente nella zona A ha riscontrato un errore e Cloud Run Functions ha configurato il MIG B per avviare una nuova istanza principale nella zona B. Il meccanismo di rilevamento degli errori viene configurato automaticamente per monitorare lo stato del nuovo nodo primario.

Routing delle query

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

Procedura di riserva

Se il nodo del database non supera un controllo di integrità a causa di un problema hardware sottostante, il nodo viene ricreato su un'istanza sottostante diversa. A questo punto, l'architettura viene riportata allo stato originale senza ulteriori passaggi. Tuttavia, se si verifica un errore a livello di zona, la configurazione continua a funzionare in uno stato ridotto finché la prima zona non viene ripristinata. Sebbene sia altamente improbabile, se si verificano errori simultanei in entrambe le zone configurate per la replica del Persistent Disk a livello di regione e il MIG stateful, l'istanza PostgreSQL non può essere recuperata e il database non è disponibile per gestire le richieste durante l'interruzione.

Confronto tra le opzioni di alta affidabilità

Le tabelle seguenti forniscono un confronto delle opzioni di alta disponibilità disponibili per Patroni, pg_auto_failover e MIG stateful con Persistent Disk a livello di regione.

Configurazione e architettura

Patroni pg_auto_failover MIG stateful con Persistent Disk a livello di regione

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

Non richiede dipendenze esterne oltre a PostgreSQL. Richiede un nodo dedicato come monitor. Il nodo di monitoraggio richiede HA e RE per garantire che non sia un single point of failure (SPOF). Architettura costituita esclusivamente da servizi Google Cloud. Esegui un solo nodo di database attivo alla volta.

Configurabilità dell'alta affidabilità

Patroni pg_auto_failover MIG stateful con Persistent Disk a livello di regione
Estremamente configurabile: supporta la replica sincrona e asincrona e consente di specificare quali nodi devono essere sincroni e asincroni. Include la gestione automatica dei nodi sincroni. Consente configurazioni HA multizona e multiregione. Il DCS deve essere accessibile. Simile a Patroni: molto configurabile. Tuttavia, poiché il monitor è disponibile solo come istanza singola, qualsiasi tipo di configurazione deve considerare l'accesso a questo nodo. Limitata a due zone in una singola regione con replica sincrona.

Capacità di gestire la partizione di rete

Patroni pg_auto_failover MIG stateful con Persistent Disk a livello di regione
Il self-fencing, insieme a un monitor a livello di sistema operativo, fornisce protezione contro lo split brain. Qualsiasi errore di connessione al DCS comporta la retrocessione dell'istanza principale a replica e l'attivazione di un failover per garantire la durabilità rispetto alla disponibilità. Utilizza una combinazione di controlli di integrità dalla replica principale al monitor e alla replica per rilevare una partizione di rete e si retrocede se necessario. Non applicabile: esiste un solo nodo PostgreSQL attivo alla volta, quindi non esiste una partizione di rete.

Costo

Patroni pg_auto_failover MIG stateful con Persistent Disk a livello di regione
Costo elevato perché dipende dal DCS scelto e dal numero di repliche PostgreSQL. L'architettura Patroni non aggiunge costi significativi. Tuttavia, la spesa complessiva è influenzata dall'infrastruttura sottostante, che utilizza più istanze di computing per PostgreSQL e il DCS. Poiché utilizza più repliche e un cluster DCS separato, questa opzione può essere la più costosa. Costo medio perché comporta l'esecuzione di un nodo di monitoraggio e di almeno tre nodi PostgreSQL (un nodo principale e due repliche). Costo ridotto perché è sempre attivo un solo nodo PostgreSQL. Paghi solo per una singola istanza di computing.

Configurazione client

Patroni pg_auto_failover MIG stateful con Persistent Disk 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 gestibile con un bilanciatore del carico. Trasparente per il client perché si connette a un bilanciatore del carico.

Scalabilità

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

Automation dell'inizializzazione dei nodi PostgreSQL, gestione della configurazione

Patroni pg_auto_failover MIG stateful con Persistent Disk a livello di regione
Fornisce strumenti per gestire la configurazione di PostgreSQL (patronictl edit-config) e inizializza automaticamente i nuovi nodi o i nodi 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 di replica. La gestione della configurazione è limitata alle configurazioni relative a pg_auto_failover. Il gruppo di istanze stateful con disco condiviso elimina la necessità di inizializzare i nodi PostgreSQL. Poiché è sempre in esecuzione un solo nodo, la gestione della configurazione avviene su un singolo nodo.

Personalizzazione e ricchezza di funzionalità

Patroni pg_auto_failover MIG stateful con Persistent Disk a livello di regione

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

Configurabilità ricca di funzionalità, come il supporto per diversi tipi di DCS, diversi mezzi per inizializzare le repliche e diversi modi per fornire la configurazione di PostgreSQL.

Consente di configurare cluster in standby che consentono cluster di replica a cascata per facilitare la migrazione tra cluster.

Limitata perché si tratta di un progetto relativamente nuovo. Non applicabile.

Maturità

Patroni pg_auto_failover MIG stateful con Persistent Disk a livello di regione
Il progetto è disponibile dal 2015 ed è 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 ad alta affidabilità PostgreSQL sono fondamentali per garantire alta affidabilità, integrità dei dati e prestazioni ottimali. Le sezioni seguenti forniscono alcune best practice per il monitoraggio e la manutenzione di un cluster PostgreSQL ad alta affidabilità.

Esegui backup regolari e test di ripristino

Esegui regolarmente il backup dei database PostgreSQL e testa il processo di ripristino. In questo modo, puoi garantire l'integrità dei dati e ridurre al minimo i tempi di inattività in caso di interruzione. Testa il processo di recupero per convalidare i backup e identificare potenziali problemi prima che si verifichi un'interruzione.

Monitora i server PostgreSQL e il ritardo di replica

Monitora i server PostgreSQL per verificare che siano in esecuzione. Monitora il ritardo della replica tra i nodi primari e di replica. Un ritardo eccessivo può portare a incoerenza dei dati e a una maggiore perdita di dati in caso di failover. Configura avvisi per aumenti significativi del ritardo e indaga tempestivamente sulla causa principale. L'utilizzo di viste come pg_stat_replication e pg_replication_slots può aiutarti a monitorare il ritardo di replica.

Implementa 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 della 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 connection pooling per PostgreSQL.

Implementa un monitoraggio completo

Per ottenere insight sui cluster PostgreSQL ad alta affidabilità, configura sistemi di monitoraggio efficaci come segue:

  • Monitora le metriche chiave di PostgreSQL e del sistema, come l'utilizzo della CPU, la memoria utilizzata, l'I/O del disco, l'attività di rete e le connessioni attive.
  • Raccogli i log di PostgreSQL, inclusi i log del server, i log WAL e i log di autovacuum, per un'analisi approfondita e la risoluzione dei problemi.
  • Utilizza strumenti di monitoraggio e dashboard per visualizzare metriche e log per una rapida identificazione dei problemi.
  • Integra metriche e log con i sistemi di avviso per la notifica proattiva di potenziali problemi.

Per saperne di più sul monitoraggio di un'istanza Compute Engine, consulta la panoramica di Cloud Monitoring.

Passaggi successivi

Collaboratori

Autore: Alex Cârciu | Solutions Architect