Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
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/postgresql listen_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 = 100 auth_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)Łącząc się przez pgbouncera, otrzymaliśmy dwunastokrotnie większą liczbę transakcji na sekundę, pomimo wykorzystania puli tylko 20 połączeń, które obsługiwały 80 połączeń przychodzących z pgbench.
Komentarze (0)
Brak komentarzy...