PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come ottenere l'elevata disponibilità di PostgreSQL con pgBouncer

Nel mondo dei database, ci sono molti concetti comuni come High Availability, Failover e Connection pooling. Sono tutte cose utili da implementare su qualsiasi sistema e in alcuni casi anche indispensabili.

Un pool di connessioni è un metodo per creare un pool di connessioni e riutilizzarle evitando di aprire continuamente nuove connessioni al database, il che aumenterà considerevolmente le prestazioni delle tue applicazioni. PgBouncer è un popolare pool di connessioni progettato per PostgreSQL, ma non è sufficiente per ottenere l'elevata disponibilità di PostgreSQL da solo in quanto non dispone di configurazione, failover o rilevamento multi-host.

L'utilizzo di un sistema di bilanciamento del carico è un modo per avere un'elevata disponibilità nella topologia del database. Potrebbe essere utile per reindirizzare il traffico a nodi di database integri, distribuire il traffico su più server per migliorare le prestazioni o semplicemente per avere un singolo endpoint configurato nell'applicazione per una configurazione più semplice e un processo di failover. Per questo, HAProxy è una buona opzione per completare il pool di connessioni, in quanto è un proxy open source che può essere utilizzato per implementare alta disponibilità, bilanciamento del carico e proxy per applicazioni basate su TCP e HTTP.

In questo blog, utilizzeremo entrambi i concetti, Load Balancer e Connection pooling (HAProxy + PgBouncer), per distribuire un ambiente ad alta disponibilità per il tuo database PostgreSQL.

Come funziona PgBouncer

PgBouncer funge da server PostgreSQL, quindi è sufficiente accedere al database utilizzando le informazioni PgBouncer (Indirizzo IP/Nome host e porta) e PgBouncer creerà una connessione al server PostgreSQL, altrimenti riutilizzane uno se esiste.

Quando PgBouncer riceve una connessione, esegue l'autenticazione, che dipende dal metodo specificato nel file di configurazione. PgBouncer supporta tutti i meccanismi di autenticazione supportati dal server PostgreSQL. Successivamente, PgBouncer verifica la presenza di una connessione memorizzata nella cache, con la stessa combinazione nome utente + database. Se viene trovata una connessione memorizzata nella cache, restituisce la connessione al client, in caso contrario crea una nuova connessione. A seconda della configurazione di PgBouncer e del numero di connessioni attive, potrebbe essere possibile che la nuova connessione venga accodata fino a quando non può essere creata, o addirittura interrotta.

Il comportamento di PgBouncer dipende dalla modalità di pooling configurata:

  • pooling di sessioni (impostazione predefinita):quando un client si connette, gli verrà assegnata una connessione al server per l'intera durata della connessione del client. Quando il client si disconnette, la connessione al server verrà rimessa nel pool.
  • pool di transazioni :una connessione server viene assegnata a un client solo durante una transazione. Quando PgBouncer si accorge che la transazione è terminata, la connessione al server verrà rimessa nel pool.
  • gruppo di dichiarazioni :la connessione al server verrà ripristinata nel pool subito dopo il completamento di una query. Le transazioni con più estratti conto non sono consentite in questa modalità poiché si interromperebbero.

Per bilanciare le query tra più server, sul lato PgBouncer, potrebbe essere una buona idea ridurre server_lifetime e anche attivare server_round_robin. Per impostazione predefinita, le connessioni inattive vengono riutilizzate dall'algoritmo LIFO, che potrebbe non funzionare molto bene quando viene utilizzato un bilanciamento del carico.

Come installare PgBouncer

Supponiamo che tu abbia distribuito il tuo cluster PostgreSQL e HAProxy e che sia attivo e funzionante, altrimenti puoi seguire questo post del blog per distribuire facilmente PostgreSQL per l'alta disponibilità.

Puoi installare PgBouncer su ogni nodo del database o su una macchina esterna, in ogni caso avrai qualcosa del genere:

Per ottenere il software PgBouncer puoi andare nella sezione download di PgBouncer, oppure utilizzare i repository RPM o DEB. Per questo esempio, utilizzeremo CentOS 8 e lo installeremo dal repository PostgreSQL ufficiale.

Per prima cosa, scarica e installa il repository corrispondente dal sito PostgreSQL (se non lo hai ancora installato):

$ wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm

$ rpm -Uvh pgdg-redhat-repo-latest.noarch.rpm

Quindi, installa il pacchetto PgBouncer:

$ yum install pgbouncer

Verifica l'installazione:

$ pgbouncer --version

PgBouncer 1.14.0

libevent 2.1.8-stable

adns: c-ares 1.13.0

tls: OpenSSL 1.1.1c FIPS  28 May 2019

Al termine, avrai un nuovo file di configurazione che si trova in /etc/pgbouncer/pgbouncer.ini:

[databases]

[users]

[pgbouncer]

logfile = /var/log/pgbouncer/pgbouncer.log

pidfile = /var/run/pgbouncer/pgbouncer.pid

listen_addr = 127.0.0.1

listen_port = 6432

auth_type = trust

auth_file = /etc/pgbouncer/userlist.txt

admin_users = postgres

stats_users = stats, postgres

Vediamo questi parametri uno per uno:

  • Sezione database [database]: Questo contiene coppie chiave=valore in cui la chiave verrà presa come nome del database e il valore come un elenco di stili di stringa di connessione libpq di coppie chiave=valore.
  • Sezione utente [utenti]: Questo contiene coppie chiave=valore in cui la chiave verrà presa come nome utente e il valore come un elenco di stili di stringa di connessione libpq di coppie chiave=valore di impostazioni di configurazione specifiche per questo utente.
  • file di registro :specifica il file di registro. Il file di registro viene mantenuto aperto, quindi dopo la rotazione kill -HUP o su console RELOAD; dovrebbe essere fatto.
  • pidfile :Specifica il file PID. Senza il file pid impostato, il demone non è consentito.
  • ascolta_addr :specifica un elenco di indirizzi in cui ascoltare le connessioni TCP. Puoi anche usare * che significa "ascolta su tutti gli indirizzi". Quando non è impostato, sono accettate solo connessioni socket Unix.
  • listen_port: Su quale porta ascoltare. Si applica a socket TCP e Unix. La porta predefinita è 6432.
  • auth_type: Come autenticare gli utenti.
  • file_auth :il nome del file da cui caricare nomi utente e password.
  • admin_users :elenco separato da virgole di utenti del database autorizzati a connettersi ed eseguire tutti i comandi sulla console.
  • stats_users :elenco separato da virgole di utenti del database autorizzati a connettersi ed eseguire query di sola lettura sulla console.

Questo è solo un esempio del file di configurazione predefinito, poiché l'originale ha 359 righe, ma il resto delle righe è commentato per impostazione predefinita. Per ottenere tutti i parametri disponibili, puoi consultare la documentazione ufficiale.

Come usare PgBouncer

Ora, vediamo una configurazione di base per farlo funzionare.

Il file di configurazione pgbouncer.ini:

$ cat /etc/pgbouncer/pgbouncer.ini

[databases]

world = host=127.0.0.1 port=5432 dbname=world

[pgbouncer]

logfile = /var/log/pgbouncer/pgbouncer.log

pidfile = /var/run/pgbouncer/pgbouncer.pid

listen_addr = *

listen_port = 6432

auth_type = md5

auth_file = /etc/pgbouncer/userlist.txt

admin_users = admindb

E il file di autenticazione:

$ cat /etc/pgbouncer/userlist.txt

"admindb" "root123"

Quindi, in questo caso, ho installato PgBouncer nello stesso nodo del database, ascoltando tutti gli indirizzi IP, e si connette a un database PostgreSQL chiamato "world". Gestisco anche gli utenti consentiti nel file userlist.txt con una password in testo semplice che può essere crittografata se necessario.

Per avviare il servizio PgBouncer è sufficiente eseguire il seguente comando:

$ pgbouncer -d /etc/pgbouncer/pgbouncer.ini

Dove -d significa "demone", quindi verrà eseguito in background.

$ netstat -pltn

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name

tcp        0      0 0.0.0.0:6432            0.0.0.0:*               LISTEN      4274/pgbouncer

tcp6       0      0 :::6432                 :::*                    LISTEN      4274/pgbouncer

Come puoi vedere, PgBouncer è attivo e in attesa di connessioni nella porta 6432. Per accedere al database PostgreSQL, esegui il seguente comando usando le tue informazioni locali (porta, host, nome utente e nome del database) :

$ psql -p 6432 -h 127.0.0.1 -U admindb world

Password for user admindb:

psql (12.4)

Type "help" for help.



world=#

Tieni presente che il nome del database (world) è il database configurato nel tuo file di configurazione di PgBouncer:

[databases]

world = host=127.0.0.1 port=5432 dbname=world

Monitoraggio e gestione di PgBouncer

Invece di accedere al tuo database PostgreSQL, puoi connetterti direttamente a PgBouncer per gestirlo o monitorarlo. Per questo, usa lo stesso comando che hai usato in precedenza, ma cambia il database in "pgbouncer":

$ psql -p 6432 -h 127.0.0.1 -U admindb pgbouncer

Password for user admindb:

psql (12.4, server 1.14.0/bouncer)

Type "help" for help.



pgbouncer=# SHOW HELP;

NOTICE:  Console usage

DETAIL:

SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|USERS|VERSION

SHOW FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM

SHOW DNS_HOSTS|DNS_ZONES

SHOW STATS|STATS_TOTALS|STATS_AVERAGES|TOTALS

SET key = arg

RELOAD

PAUSE [<db>]

RESUME [<db>]

DISABLE <db>

ENABLE <db>

RECONNECT [<db>]

KILL <db>

SUSPEND

SHUTDOWN



SHOW

Ora puoi eseguire diversi comandi PgBouncer per monitorarlo:

MOSTRA STATS_TOTALS:

pgbouncer=# SHOW STATS_TOTALS;

 database  | xact_count | query_count | bytes_received | bytes_sent | xact_time | query_time | wait_time

-----------+------------+-------------+----------------+------------+-----------+------------+-----------

 pgbouncer |          1 |           1 |              0 |          0 |         0 |          0 |         0

 world     |          2 |           2 |             59 |     234205 |      8351 |       8351 |      4828

(2 rows)

MOSTRA SERVER:

pgbouncer=# SHOW SERVERS;

 type |  user   | database | state  |   addr    | port | local_addr | local_port |      connect_time       |      request_time

| wait | wait_us | close_needed |      ptr       |      link      | remote_pid | tls

------+---------+----------+--------+-----------+------+------------+------------+-------------------------+-------------------------

+------+---------+--------------+----------------+----------------+------------+-----

 S    | admindb | world    | active | 127.0.0.1 | 5432 | 127.0.0.1  |      45052 | 2020-09-09 18:31:57 UTC | 2020-09-09 18:32:04 UTC

|    0 |       0 |            0 | 0x55b04a51b3d0 | 0x55b04a514810 |       5738 |

(1 row)

MOSTRA CLIENTI:

pgbouncer=# SHOW CLIENTS;

 type |  user   | database  | state  |   addr    | port  | local_addr | local_port |      connect_time       |      request_time

  | wait | wait_us | close_needed |      ptr       |      link      | remote_pid | tls

------+---------+-----------+--------+-----------+-------+------------+------------+-------------------------+-----------------------

--+------+---------+--------------+----------------+----------------+------------+-----

 C    | admindb | pgbouncer | active | 127.0.0.1 | 46950 | 127.0.0.1  |       6432 | 2020-09-09 18:29:46 UTC | 2020-09-09 18:55:11 UT

C | 1441 |  855140 |            0 | 0x55b04a5145e0 |                |          0 |

 C    | admindb | world     | active | 127.0.0.1 | 47710 | 127.0.0.1  |       6432 | 2020-09-09 18:31:41 UTC | 2020-09-09 18:32:04 UT

C |    0 |       0 |            0 | 0x55b04a514810 | 0x55b04a51b3d0 |          0 |

(2 rows)

MOSTRA PISCINE:

pgbouncer=# SHOW POOLS;

 database  |   user    | cl_active | cl_waiting | sv_active | sv_idle | sv_used | sv_tested | sv_login | maxwait | maxwait_us | pool_

mode

-----------+-----------+-----------+------------+-----------+---------+---------+-----------+----------+---------+------------+------

-----

 pgbouncer | pgbouncer |         1 |          0 |         0 |       0 |       0 |         0 |        0 |       0 |          0 | state

ment

 world     | admindb   |         1 |          0 |         1 |       0 |       0 |         0 |        0 |       0 |          0 | sessi

on

(2 rows)

E per gestirlo...

RICARICA:

pgbouncer=# RELOAD;

RELOAD

PAUSA:

pgbouncer=# PAUSE world;

PAUSE

RIPRENDI:

pgbouncer=# RESUME world;

RESUME

Questi comandi sono solo un esempio. Per un elenco completo dei comandi, fare riferimento alla documentazione ufficiale.

Conclusione

L'uso di una combinazione di PgBouncer + HAProxy + PostgreSQL è un buon modo per ottenere un'elevata disponibilità per il tuo cluster PostgreSQL migliorando allo stesso tempo le prestazioni del tuo database.

Come puoi vedere, se disponi del tuo ambiente PostgreSQL, che puoi distribuire utilizzando ClusterControl in pochi clic, puoi facilmente aggiungere PgBouncer per trarre vantaggio dall'avere un pool di connessioni per i tuoi sistemi.