
PgBouncer umożliwia stworzenie puli połączeń określonej "min_pool_size
", które zostaną nawiązane do klastra postgresa "na stałe", z możliwością powiększenia kontrolowanego do "default_pool_size" / "pool_size
" jeżeli zajdzie taka potrzeba i zamykania połączeń nieaktywnych przez "server_idle_timeout
" do limitu "min_pool_size
". A w sytuacjach awaryjnych, jeżeli w kolejce będą znajdowały się połączenia, które nie zostały obsłużone przez "reserve_pool_timeout
", otworzy zapasowe połączenia, do maksymalnie "reserve_pool_size
". Dzięki temu, że w pgBouncer połączenia nawiązane są tylko raz, a następnie mogą być wielokrotnie ponownie wykorzystane przez różnych klientów. Unikamy potrzeby ciągłego nawiązywania nowych połączeń, co jest dość kosztowną operacją.
Ponadto, pozwala na stworzenie kolejki dla połączeń przychodzących do pgbouncera "max_client_conn
", które będą obsługiwane po kolei przez połączenia z puli.
Mamy dostępne trzy tryby pracy, "pool_mode
":
pgbouncer wymaga uwierzytelniania podczas ustanawiania połączenia. Sposób uwierzytelniania ustawiamy parametrem "auth_type
", obsługiwane opcje to:
auth_hba_file
, który użytkownik może się zalogować oraz z jakim typem uwierzytelniania, metoda ta pozwala na zdefiniowanie różnych typów uwierzytelniania,auth_file
jest ignorowany w tej metodzie oraz nie można jej ustawić w trybie hba.Przykład prostej konfiguracji. W miejsce host=pg1 podajmy naszego aktualnego lidera patroni. W tym pliku będą już sekcje "[databases]" i "[pgbouncer]". Trzeba je wykomentować przed wklejeniem poniższego lub stworzyć ten plik na nowo.
# /etc/pgbouncer/pgbouncer.ini[databases]
postgres = host=pg1 port=5432 dbname=postgres min_pool_size=10 pool_size=20
* = host=pg1 port=5432 pool_size=20[pgbouncer]
logfile = /var/log/postgresql/pgbouncer.log
pidfile = /var/run/postgresql/pgbouncer.pid
unix_socket_dir = /var/run/postgresqllisten_addr = *
listen_port = 6432
pool_mode = transaction
max_client_conn = 1000
reserve_pool_size = 5
reserve_pool_timeout = 5
server_idle_timeout = 60
max_db_connections = 100auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
admin_users = postgres
Do pliku userlist.txt kopiujemy hash md5 hasła dla użytkownika, który powinien móc się połączyć z postgresem. Możemy go znaleźć w widoku pg_shadow na dowolnym z hostów Patroni:
postgres=# \x
Expanded display is on.
postgres=# select * from pg_shadow ;
-[ RECORD 1 ]+------------------------------------
usename | postgres
usesysid | 10
usecreatedb | t
usesuper | t
userepl | t
usebypassrls | t
passwd | md5a9f68b14e99c2c1fc6b28e1291488e53
valuntil |
useconfig |
Wartości z kolumn usename oraz passwd przenosimy do pliku /etc/pgbouncer/userlist.txt na hoście 4 - czyli tam, gdzie pgbouncer. Jeżeli plik nie istnieje, należy go stworzyć:
sudo vi /etc/pgbouncer/userlist.txt
"postgres" "md5a9f68b14e99c2c1fc6b28e1291488e53"
Uruchamiamy pgbouncer za pomocą usługi pgbouncer.service:
sudo systemctl start pgbouncer
Przetestujmy teraz, jaką wydajność możemy osiągnąć dla tego samego klastra za pomocą pgbench.
Przed testem wykonajmy inicjalizację danych pgbench na serwerze lidera patroni.
Dla poprawnego działania pgbench musimy zainstalować jako użytkownik systemowy z uprawnieniami do sudo na wszystkich serwerach patroni i hoscie pgbouncer:
sudo apt install postgresql-client-15 postgresql-15
Następnie inicjalizujemy bazę z przykładowymi danymi (z poziomu użytkownika systemowego postgres):
pgbench -i -s 10
Gdyby podczas poniższych testów Postgresql pytał nas o hasło, podajemy to, które skonfigurowaliśmy w sekcji "authentication" w pliku /etc/patroni/config.yml
dowolnego z serwerów klastra Patroni, a najlepiej z serwera, który uruchomiliśmy jako pierwszy i który zainicjował klaster. Jeśli mamy za sobą nasz rozdział o Patroni, to tam ustawialiśmy hasło na "haslo_postgres".
postgres@ubuntu:~$ pgbench -h <nazwa_hosta_lidera_patroni> -p 5432 -S -c 80 -P 5 -T 30 -C
pgbench (15.3 (Ubuntu 15.3-1.pgdg22.04+1))
starting vacuum...end.
progress: 5.0 s, 257.0 tps, lat 288.754 ms stddev 174.237
progress: 10.0 s, 255.8 tps, lat 308.288 ms stddev 183.066
progress: 15.0 s, 252.1 tps, lat 307.900 ms stddev 212.583
progress: 20.0 s, 306.1 tps, lat 255.459 ms stddev 148.380
progress: 25.0 s, 259.8 tps, lat 300.960 ms stddev 179.012
progress: 30.0 s, 257.8 tps, lat 307.302 ms stddev 159.319
transaction type: <builtin: select only>
scaling factor: 1000
query mode: simple
number of clients: 80
number of threads: 1
duration: 30 s
number of transactions actually processed: 8023
latency average = 293.352 ms
latency stddev = 176.923 ms
average connection time = 3.650 ms
tps = 265.967665 (including reconnection times)
postgres@ubuntu:~$ pgbench -p 6432 -S -c 80 -P 5 -T 30 -C
pgbench (15.3 (Ubuntu 15.3-1.pgdg22.04+1))
starting vacuum...end.
progress: 5.0 s, 3692.3 tps, lat 10.438 ms stddev 12.292
progress: 10.0 s, 3609.6 tps, lat 10.520 ms stddev 6.427
progress: 15.0 s, 4323.0 tps, lat 9.355 ms stddev 5.307
progress: 20.0 s, 3041.1 tps, lat 12.704 ms stddev 8.346
progress: 25.0 s, 2347.5 tps, lat 16.138 ms stddev 9.176
progress: 30.0 s, 3262.3 tps, lat 11.846 ms stddev 6.609
transaction type: <builtin: select only>
scaling factor: 1000
query mode: simple
number of clients: 80
number of threads: 1
duration: 30 s
number of transactions actually processed: 101414
latency average = 11.446 ms
latency stddev = 8.498 ms
average connection time = 0.280 ms
tps = 3379.950548 (including reconnection times)
Komentarze (0)
Brak komentarzy...