I databasvärlden finns det många vanliga begrepp som High Availability, Failover och Connection pooling. Alla är användbara saker att implementera på alla system, och till och med ett måste i vissa fall.
En anslutningspoolning är en metod för att skapa en pool av anslutningar och återanvända dem för att undvika att öppna nya anslutningar till databasen hela tiden, vilket kommer att öka prestandan för dina applikationer avsevärt. PgBouncer är en populär anslutningspoolare designad för PostgreSQL, men det räcker inte för att uppnå PostgreSQL High Availability i sig eftersom den inte har multi-host-konfiguration, failover eller detektering.
Att använda en lastbalanserare är ett sätt att ha hög tillgänglighet i din databastopologi. Det kan vara användbart för att omdirigera trafik till sunda databasnoder, distribuera trafiken över flera servrar för att förbättra prestanda, eller bara för att ha en enda slutpunkt konfigurerad i din applikation för en enklare konfiguration och failover-process. För detta är HAProxy ett bra alternativ för att komplettera din anslutningspoolare, eftersom det är en proxy med öppen källkod som kan användas för att implementera hög tillgänglighet, lastbalansering och proxy för TCP- och HTTP-baserade applikationer.
I den här bloggen kommer vi att använda båda koncepten, Load Balancer och Connection Pooling (HAProxy + PgBouncer), för att distribuera en High Availability-miljö för din PostgreSQL-databas.
Hur PgBouncer fungerar
PgBouncer fungerar som en PostgreSQL-server, så du behöver bara komma åt din databas med PgBouncer-informationen (IP-adress/värdnamn och port), och PgBouncer skapar en anslutning till PostgreSQL-servern, eller så kommer den att återanvänd en om den finns.
När PgBouncer tar emot en anslutning utför den autentiseringen, vilket beror på metoden som anges i konfigurationsfilen. PgBouncer stöder alla autentiseringsmekanismer som PostgreSQL-servern stöder. Efter detta söker PgBouncer efter en cachad anslutning, med samma användarnamn+databaskombination. Om en cachad anslutning hittas returnerar den anslutningen till klienten, om inte skapar den en ny anslutning. Beroende på PgBouncer-konfigurationen och antalet aktiva anslutningar kan det vara möjligt att den nya anslutningen står i kö tills den kan skapas eller till och med avbrytas.
PgBouncers beteende beror på det konfigurerade poolläget:
- session pooling (standard):När en klient ansluter kommer en serveranslutning att tilldelas den under hela den tid som klienten är ansluten. När klienten kopplar från kommer serveranslutningen att läggas tillbaka till poolen.
- transaktionspoolning :En serveranslutning tilldelas en klient endast under en transaktion. När PgBouncer märker att transaktionen är över kommer serveranslutningen att läggas tillbaka till poolen.
- uttalandepoolning :Serveranslutningen kommer att kopplas tillbaka till poolen omedelbart efter att en förfrågan är klar. Transaktioner med flera uttalanden är inte tillåtna i det här läget eftersom de skulle gå sönder.
För att balansera frågor mellan flera servrar, på PgBouncer-sidan, kan det vara en bra idé att göra server_lifetime mindre och även aktivera server_round_robin. Som standard återanvänds lediga anslutningar av LIFO-algoritmen, vilket kanske inte fungerar så bra när en lastbalanserare används.
Hur man installerar PgBouncer
Vi antar att du har ditt PostgreSQL-kluster och HAProxy distribuerat, och att det är igång, annars kan du följa det här blogginlägget för att enkelt distribuera PostgreSQL för hög tillgänglighet.
Du kan installera PgBouncer på varje databasnod eller på en extern maskin, i alla fall kommer du att ha något sånt här:
För att hämta PgBouncer-mjukvaran kan du gå till PgBouncer-nedladdningssektionen, eller använd RPM- eller DEB-förråden. I det här exemplet kommer vi att använda CentOS 8 och installera det från det officiella PostgreSQL-förrådet.
Hämta först och installera motsvarande arkiv från PostgreSQL-webbplatsen (om du inte har det på plats ännu):
$ 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
Installera sedan PgBouncer-paketet:
$ yum install pgbouncer
Verifiera installationen:
$ 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
När den är klar kommer du att ha en ny konfigurationsfil i /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
Låt oss se dessa parametrar en efter en:
- Databassektionen [databaser]: Detta innehåller key=value-par där nyckeln tas som ett databasnamn och värdet som en libpq-anslutningssträngstillista med key=value-par.
- Användarsektion [användare]: Detta innehåller nyckel=värdepar där nyckeln tas som ett användarnamn och värdet som en libpq-anslutningssträngstillista med nyckel=värdepar av konfigurationsinställningar som är specifika för denna användare.
- loggfil :Anger loggfilen. Loggfilen hålls öppen, så efter rotation döda -HUP eller på konsolen RELOAD; bör göras.
- pidfil :Anger PID-filen. Utan pidfiluppsättningen är demonen inte tillåten.
- listen_addr :Anger en lista över adresser där TCP-anslutningar ska lyssnas. Du kan också använda * som betyder "lyssna på alla adresser". När den inte är inställd accepteras endast Unix-uttagsanslutningar.
- lyssningsport: Vilken port att lyssna på. Gäller både TCP- och Unix-uttag. Standardporten är 6432.
- auth_type: Hur man autentiserar användare.
- auth_file :Namnet på filen som användarnamn och lösenord ska laddas från.
- admin_users :Kommaseparerad lista över databasanvändare som får ansluta och köra alla kommandon på konsolen.
- stats_users :Kommaseparerad lista över databasanvändare som får ansluta och köra skrivskyddade frågor på konsolen.
Detta är bara ett exempel på standardkonfigurationsfilen, eftersom originalet har 359 rader, men resten av raderna kommenteras som standard. För att få alla tillgängliga parametrar kan du kontrollera den officiella dokumentationen.
Hur man använder PgBouncer
Låt oss nu se en grundläggande konfiguration för att få det att fungera.
Konfigurationsfilen 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
Och autentiseringsfilen:
$ cat /etc/pgbouncer/userlist.txt
"admindb" "root123"
Så, i det här fallet har jag installerat PgBouncer i samma databasnod, lyssnar på alla IP-adresser, och den ansluter till en PostgreSQL-databas som heter "världen". Jag hanterar också de tillåtna användarna i filen userlist.txt med ett lösenord i vanlig text som kan krypteras vid behov.
För att starta PgBouncer-tjänsten behöver du bara köra följande kommando:
$ pgbouncer -d /etc/pgbouncer/pgbouncer.ini
Där -d betyder "demon", så den körs i bakgrunden.
$ 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
Som du kan se är PgBouncer uppe och väntar på anslutningar i port 6432. För att komma åt PostgreSQL-databasen, kör följande kommando med din lokala information (port, värd, användarnamn och databasnamn) :
$ psql -p 6432 -h 127.0.0.1 -U admindb world
Password for user admindb:
psql (12.4)
Type "help" for help.
world=#
Tänk på att databasnamnet (världen) är den databas som konfigurerats i din PgBouncer-konfigurationsfil:
[databases]
world = host=127.0.0.1 port=5432 dbname=world
Övervaka och hantera PgBouncer
Istället för att komma åt din PostgreSQL-databas kan du ansluta direkt till PgBouncer för att hantera eller övervaka den. För detta, använd samma kommando som du använde tidigare, men ändra databasen till "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
Nu kan du köra olika PgBouncer-kommandon för att övervaka det:
VISA 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)
VISA SERVRAR:
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)
VISA KUNDER:
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)
VISA POOLER:
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)
Och för att hantera det...
LADDA OM:
pgbouncer=# RELOAD;
RELOAD
PAUS:
pgbouncer=# PAUSE world;
PAUSE
RESUMÉ:
pgbouncer=# RESUME world;
RESUME
De här kommandona är bara ett exempel. För en fullständig lista över kommandon, se den officiella dokumentationen.
Slutsats
Att använda en kombination av PgBouncer + HAProxy + PostgreSQL är ett bra sätt att uppnå hög tillgänglighet för ditt PostgreSQL-kluster och samtidigt förbättra din databasprestanda.
Som du kan se, om du har din PostgreSQL-miljö på plats, som du kan distribuera med ClusterControl med bara några få klick, kan du enkelt lägga till PgBouncer för att dra fördel av att ha en anslutningspooler för dina system.