PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Pula połączeń PostgreSQL z PgBouncer

Pule połączeń to prosty, ale skuteczny sposób na poprawę wydajności aplikacji i zmniejszenie obciążenia serwerów PostgreSQL. Czytaj dalej, aby dowiedzieć się więcej o używaniu PgBouncera do łączenia połączeń PostgreSQL.

Dlaczego łączenie połączeń?

PostgreSQL ma dość ciężką architekturę obsługi połączeń. Dla każdego połączenia przychodzącego postmaster (główny demon Postgres) tworzy nowy proces (tradycyjnie nazywany backendem ) do obsługi. Chociaż ten projekt zapewnia lepszą stabilność i izolację, nie czyni go szczególnie wydajnym w obsłudze połączeń o krótkim czasie życia. Nowe połączenie klienta Postgres obejmuje konfigurację TCP, tworzenie procesów i inicjalizację zaplecza – wszystko to jest kosztowne pod względem czasu i zasobów systemowych.

To oczywiście tylko problem, jeśli połączenia są tworzone zbyt często i odrzucane bez ponownego użycia. Niestety, często zdarza się, że klaster węzłów sieciowych uruchamia aplikacje napisane w PHP lub innych tego typu językach, które muszą łączyć się z bazą danych raz na ładowanie strony. Powszechne są również zadania wsadowe, które szybko tworzą wiele połączeń w krótkich odstępach czasu. Stosuję połączenie połączeń w takich sytuacjach może drastycznie zmniejszyć obciążenie serwera PostgreSQL i znacznie poprawić opóźnienia zapytań.

Dzięki puli połączeń, klienci łączą się z serwerem proxy, który utrzymuje zestaw bezpośrednich połączeń z rzeczywistym serwerem PostgreSQL. Zazwyczaj klienci nie zdają sobie sprawy (i nie powinni) zdawać sobie sprawy, że są podłączeni do serwera proxy, a nie do rzeczywistego serwera. Proxy może działać na tym samym węźle co klient (na przykład na każdym węźle sieciowym), w którym to przypadku klienci mogą łączyć się z proxy przez gniazda domeny Unix, które mają bardzo niski narzut połączenia. Nawet jeśli serwer proxy znajduje się na innym węźle, a klient potrzebuje połączenia TCP, aby dotrzeć do serwera proxy, można uniknąć obciążenia nowego zaplecza Postgres.

Co to jest PgBouncer?

PgBouncer to open-source, lekki, jedno-binarny pooler połączeń dla PostgreSQL. Może łączyć połączenia z jedną lub większą liczbą baz danych (na prawdopodobnie różnych serwerach) i obsługiwać klientów przez gniazda domen TCP i Unix.

PgBouncer utrzymuje pulę połączeń dla każdego unikalnego użytkownika, pary bazy danych. Zwykle jest skonfigurowany do przekazywania jednego z tych połączeń nowemu połączeniu przychodzącemu i zwracania go z powrotem do puli, gdy klient się rozłączy. Możesz skonfigurować PgBouncer tak, aby pula była bardziej agresywna, aby mogła odbierać i zwracać połączenie do puli w granicach transakcji lub instrukcji, a nie granic połączenia. Istnieją jednak pewne potencjalnie niepożądane konsekwencje.

Powinieneś być w stanie zainstalować PgBouncer za pomocą menedżera pakietów swojej dystrybucji:

# RedHat/CentOS/..
$ sudo yum install pgbouncer

# Debian/Ubuntu/..
$ sudo apt-get install pgbouncer

Jest również dostępny w standardowych repozytoriach Postgres APT i YUM, których można użyć, jeśli pakiety twojej dystrybucji są stare lub uszkodzone.

PgBouncer opiera się na głównym pliku konfiguracyjnym, zwykle przechowywanym jako /etc/pgbouncer/pgbouncer.ini . Możesz wywołać pgbouncer jako usługę systemd lub po prostu uruchomić go nawet bez uprawnień administratora ze ścieżką do tego pliku konfiguracyjnego.

Aby to zrobić, stwórzmy bazę danych db1 i użytkownika user1 na naszym serwerze:

$ sudo -u postgres psql
psql (10.6 (Debian 10.6-1.pgdg90+1))
Type "help" for help.

postgres=# create user user1 password 'user1pass';
CREATE ROLE
postgres=# create database db1 owner user1;
CREATE DATABASE
postgres=#

Klienci będą łączyć się z bazą danych db1 z nazwą użytkownika user1 andpassword user1pass . Naszym celem jest, aby klienci połączyli się z PgBouncer, który będzie proxy i pulował połączenia z rzeczywistym serwerem.

Teraz utwórzmy plik (w dowolnym miejscu) z następującą zawartością:

[databases]
db1 = host=localhost dbname=db1

[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 16432
auth_file = userlist.txt

Musimy również utworzyć plik „userlist.txt” w tym samym katalogu, z nazwą użytkownika i (zahaszowanymi) hasłami użytkowników, z którymi PgBouncer pozwoli się połączyć. Utwórz „userlist.txt” z następującą zawartością:

"user1" "md5638b81c77071ea624d1ad4adb1433540"

Druga wartość to MD5 „user1passuser1”, poprzedzone prefiksem „md5”. To jest zwykła konwencja Postgresa.

Teraz zacznijmy PgBouncera na pierwszym planie:

$ /usr/sbin/pgbouncer pgbouncer.ini
2019-02-05 11:46:18.011 10033 LOG file descriptor limit: 1024 (H:1048576), max_client_conn: 100, max fds possible: 130
2019-02-05 11:46:18.012 10033 LOG listening on 127.0.0.1:16432
2019-02-05 11:46:18.013 10033 LOG listening on unix:/tmp/.s.PGSQL.16432
2019-02-05 11:46:18.014 10033 LOG process up: pgbouncer 1.9.0, libevent 2.0.21-stable (epoll), adns: c-ares 1.12.0, tls: OpenSSL 1.1.0j  20 Nov 2018

Uruchomiliśmy teraz PgBouncer, który nasłuchuje na porcie TCP 127.0.0.1 16432, a także na gnieździe domeny uniksowej /tmp/.s.PGSQL.16432 . Jedyną „bazą danych” dostępną na tym serwerze proxy jest db1 . Jedynym użytkownikiem, który może połączyć się z tym serwerem jest user1 . Spróbujmy połączyć się z psql :

$ psql -U user1 -p 16432 -h localhost db1
Password for user user1:
psql (10.6 (Debian 10.6-1.pgdg90+1))
Type "help" for help.

db1=> select inet_server_addr(), inet_server_port();
 inet_server_addr | inet_server_port
------------------+------------------
 127.0.0.1        |             5432
(1 row)

db1=>

Klient (psql) łączy się pomyślnie z hostem lokalnym:16432, ale widać, że połączenie jest w rzeczywistości przekazywane do hosta lokalnego:5432.

Możesz spróbować rozłączyć się i połączyć ponownie kilka razy, a następnie sprawdzić, ile połączeń jest nadal dostępnych na rzeczywistym serwerze:

postgres=# select count(*) from pg_stat_activity
postgres-#   where datname='db1' and usename='user1';
 count
-------
     1
(1 row)

PgBouncer nie rozłącza rzeczywistego połączenia, gdy klient się rozłącza. Możesz skonfigurować minimalne, maksymalne i zarezerwowane połączenia, które PgBouncer będzie utrzymywał dla każdej puli w pliku konfiguracyjnym.

Wdrażanie PgBouncera

Gdzie instalujesz i uruchamiasz PgBouncer? Istnieją różne odpowiedzi, z różnymi zaletami:

  • W węźle serwera Postgres :Możesz zainstalować go obok samego serwera PostgreSQL, na tym samym węźle. Klienci łączą się z portem PgBouncer, a nie portem Postgres. Ma to efekt „ulepszonego” Postgresa, który wewnętrznie tworzy pulę połączeń. Musisz także utrzymywać tylko jedną kopię plików konfiguracyjnych dla PgBouncer. Z drugiej strony wiąże się to z uruchomieniem czegoś innego również w węźle serwera PostgreSQL, co może nie być łatwe lub dozwolone (zapory ogniowe, polityki) lub nawet możliwe (AWSRDS).
  • W węzłach klienta :Możesz zainstalować PgBouncer w każdym węźle klienta, na przykład każdy węzeł sieciowy uruchamia Apache i PHP, a skrypty PHP łączą się z localPgBouncer. Ma to tę zaletę, że nie trzeba zakłócać konfiguracji serwera, a konfigurację puli można wykorzystać do utrzymania przewidywalnego obciążenia serwera. Z drugiej strony, jeśli liczba węzłów klienckich jest ogromna lub może się znacznie różnić w zależności od obciążenia/ ruchu, serwer może być szybko przeciążony.
  • Jako samodzielny klaster :Trzecia opcja, aby mieć klaster niezależnych, bezstanowych węzłów PgBouncer, na czele z systemem równoważenia obciążenia TCP, takim jak HAProxy. Ta konfiguracja, choć jest bardziej skomplikowana niż pozostałe dwie opcje, zapewnia maksymalną kontrolę i konfigurowalność.

Administracja

PgBouncer umożliwia użytkownikom oznaczonym jako administratorzy łączenie się z wirtualną bazą danych o nazwie „pgbouncer” i wydawanie poleceń w celu kontrolowania serwera i przeglądania statystyk. Aby to wypróbować, oznaczmy najpierw użytkownika „user1” jako administratora, modyfikując plik pgbouncer.ini:

[databases]
db1 = host=localhost dbname=db1

[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 16432
auth_file = userlist.txt
admin_users = user1

Teraz użytkownik 1 może połączyć się z bazą danych o nazwie „pgbouncer”:

$ psql -U user1 -p 16432 -h localhost pgbouncer
Password for user user1:
psql (10.6 (Debian 10.6-1.pgdg90+1), server 1.9.0/bouncer)
Type "help" for help.

pgbouncer=#

Z tego miejsca możesz wykonywać różne czynności, takie jak włączanie lub wyłączanie określonej bazy danych, sprawdzanie i ponowne ładowanie konfiguracji i nie tylko:

pgbouncer=# RELOAD;
RELOAD
pgbouncer=# DISABLE db1;
DISABLE
pgbouncer=# ENABLE db1;
ENABLE
pgbouncer=# SHOW FDS;
 fd |  task  | user  | database |   addr    | port  |     cancel     | link | client_encoding | std_strings | datestyle | timezone  | pa
----+--------+-------+----------+-----------+-------+----------------+------+-----------------+-------------+-----------+-----------+---
  6 | pooler |       |          | 127.0.0.1 | 16432 |              0 |    0 |                 |             |           |           |
  7 | pooler |       |          | unix      | 16432 |              0 |    0 |                 |             |           |           |
  9 | server | user1 | db1      | 127.0.0.1 |  5432 | 45404395804679 |    0 | UTF8            | on          | ISO, MDY  | localtime |
(3 rows)

Monitorowanie

Istnieją również polecenia pokazujące różne statystyki dotyczące PgBouncera, w tym:

  • Statystyki bazy danych dotyczące czasu trwania zapytania, czasu oczekiwania klienta, wykorzystania sieci, liczby transakcji
  • Statystyki puli dotyczące liczby aktywnych i oczekujących klientów, bezczynnych i używanych połączeń z serwerem

Statystyki są pobierane za pomocą poleceń w stylu „SHOW xyz”, takich jak ta do pobierania statystyk dotyczących puli:

pgbouncer=# SHOW POOLS;
-[ RECORD 1 ]---------
database   | db1
user       | user1
cl_active  | 0
cl_waiting | 0
sv_active  | 0
sv_idle    | 0
sv_used    | 1
sv_tested  | 0
sv_login   | 0
maxwait    | 0
maxwait_us | 0
pool_mode  | session
-[ RECORD 2 ]---------
database   | pgbouncer
user       | pgbouncer
cl_active  | 1
cl_waiting | 0
sv_active  | 0
sv_idle    | 0
sv_used    | 0
sv_tested  | 0
sv_login   | 0
maxwait    | 0
maxwait_us | 0
pool_mode  | statement

Dalsze czytanie

Strona główna PgBouncera zawiera więcej szczegółów na temat wszystkich różnych funkcji i opcji konfiguracyjnych PgBouncera.

  • Strona główna PgBouncera
  • Repozytorium GitHub PgBouncera
  • Wiki Postgres zawiera informacje na temat puli połączeń
  • Pgpool to kolejna opcja puli połączeń

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wydrukować wynik zapytania PostgreSQL w formacie CSV lub TSV z wiersza poleceń?

  2. Pobieranie listy dat w zakresie w PostgreSQL

  3. Oracle do PostgreSQL — kursory i wspólne wyrażenia tabelowe

  4. Ustaw puste ciągi ('') na NULL w całej bazie danych

  5. Gdzie są logi PostgreSQL w systemie macOS?