PGSQL 10: PgBouncer — менеджер соединений

Описание:

В этом задании поймем, как настраивать пул соединений к PostgreSQL с PgBouncer.

Типичные веб-проекты, разрабатываемые на чем-то вроде Python или PHP, характерны тем, что они создают огромное количество соединений к СУБД — по одному, иногда даже и по несколько, на каждый HTTP-запрос. Имея классическую архитектуру «один процесс на соединение», PostgreSQL плохосправляется с большим (условно — больше 100) количеством соединений. Решить проблему позволяет пулер соединений под названием PgBouncer. Благодаря использованию библиотеки libevent, PgBouncer может поддерживать большое количество (тысячи) соединений, которые проксируются на несколько (пара десятков) соединений непосредственно к PostgreSQL.

Представим, что на сервере у нас используется Ubuntu Linux, так как сегодня это, по всей видимости, крайне популярный серверный дистрибутив Linux. Отличия описанных шагов для других дистрибутивов будут минимальными. Также предполагается, что на сервере уже установлен PostgreSQL. Установку и начальную настройку PostgreSQL мы уже рассмотрели в задании «Начало работы с PostgreSQL».

Устанавливается PgBouncer очень просто:

sudo apt-get install pgbouncer

По умолчанию он слушает порт 6432.

Логи можно почитать так:

less /var/log/postgresql/pgbouncer.log

Конфигурационный файл называется /etc/pgbouncer/pgbouncer.ini.

Рассмотрим основные параметры.

;; database name = connect string
;;
;; connect string params:
;;   dbname= host= port= user= password=
;;   client_encoding= datestyle= timezone=
;;   pool_size= connect_query=
;;   auth_user=
[databases]

* = host=localhost port=5432

Здесь мы можем указать, на каких серверах какие базы нужно искать. Звездочкой обозначается дефолтный сервер. Кстати, это хоть и примитивный, но уже шардинг.

Не менее важная настройка:

; When server connection is released back to pool:
;   session      - after client disconnects
;   transaction  - after transaction finishes
;   statement    - after statement finishes
pool_mode = transaction

session по умолчанию означает, что сессия будет удерживаться клиентом до тех пор, пока он не закроет соединение. Чаще всего имеет смысл заменить значение на transaction. В этом случае соединение будет возвращаться в общий пул после завершения транзакции.
Значение statement означает, что соединение будет освобождаться после выполнения каждого отдельного выражения, чего вы, скорей всего, не хотите.

Настройки размера пула:

; total number of clients that can connect
max_client_conn = 1000

; default pool size.  20 is good number when transaction pooling
; is in use, in session pooling it needs to be the number of
; max clients you want to handle at any moment
default_pool_size = 20

;; Minimum number of server connections to keep in pool.
;min_pool_size = 0

Я увеличил максимальное количество клиентских соединений до 1000. Значение по умолчанию равно 100.

Настройки аутентификации:

; any, trust, plain, crypt, md5, cert, hba, pam
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
… и доступа к админке pgbouncer:

;;;
;;; Users allowed into database 'pgbouncer'
;;;

; comma-separated list of users, who are allowed to change settings
admin_users = rebrain_admin

; comma-separated list of users who are just allowed to use
;    SHOW command
;stats_users = stats, root

Важно! Параметр auth_type по умолчанию имеет значение trust. То есть, PgBouncer будет пускать всех в базу данных без запроса пароля. Вряд ли вам это подходит.

Файл /etc/pgbouncer/userlist.txt содержит имена пользователей и пароли, с которыми PgBouncer подключается к базе. Например:

"rebrain_admin" "qwerty"

Пароли не обязательно хранить открытым текстом:

"rebrain_admin" "md5175c641eaed0b6c05ae8444b73d789f0"

Здесь хеш 175c641e... был посчитан как MD5 от пароля, следом за которым записано имя пользователя:

echo -n 'qwertyrebrain_admin' | md5sum

Теперь, когда PgBouncer настроен, можно перезапустить его:

systemctl restart pgbouncer

… и ломиться в базу:

psql -p 6432 -U rebrain_admin

Если все было сделано правильно, PgBouncer запросит пароль. В приведенном примере пароль, с которым пользователь ходит в PostgreSQL напрямую, и пароль, запрашиваемый PgBouncer, — один и тот же. Если вдруг что-то не работает, рекомендую начать с проверки настройки аутентификации самого PostgreSQL (файл pg_hba.conf).

Выше пользователь rebrain_admin был добавлен в admin_users, что дает ему доступ в админку PgBouncer. Вход в админку осуществляется так:

psql -p 6432 -U rebrain_admin pgbouncer

Наиболее интересная из доступных команд — это перечитывание конфигурации без перезапуска сервера:

RELOAD; Информацию о других доступных командах можно посмотреть так:

SHOW HELP; Пример вывода:

DETAIL:
    SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|VERSION
    SHOW FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM
    SHOW DNS_HOSTS|DNS_ZONES
    SHOW STATS|STATS_TOTALS|STATS_AVERAGES
    SET key = arg
    RELOAD
    PAUSE [<db>]
    RESUME [<db>]
    DISABLE <db>
    ENABLE <db>
    KILL <db>
    SUSPEND
    SHUTDOWN

Проверяем, что все работает, запустив pgbench с 900 соединениями:

pgbench -i
pgbench -p 6432 -c 900 -C -T 60 -P 1

Если все было сделано правильно, pgbench будет превосходно работать, а команда SHOW CLIENTS;, выполненная в админке PgBouncer, покажет нам 900 соединений. При этом вывод ps wuax | grep postgres покажет, что реально запущено лишь 20 бэкендов PostgreSQL.

Как видите, пользоваться PgBouncer легко и приятно.

Полезные ссылки:

Installation:

Правила выполнения задания:

  1. Время создания окружения занимает до 5 минут.
  2. После нажатия кнопки «Начать выполнение» для вас будет создано окружение для выполнения задания, состоящее из одной или более виртуальнах машин с Ubuntu Linux. К ним будут выданы IP, логин и пароль для доступа по SSH, а также при необходимости — дополнительных ресурсов.
  3. Также, если необходимо, вам могут быть выданы переменные, которые в задании указаны в фигурных скобках, — их надо будет подставить при выполнении задания (например, ${base_domain}).
  4. После выполнения всех пунктов задания нажмите кнопку «Проверить выполнение», и в течение 3-5 минут скрипт проверит выполнение всех условий и выставит вам оценку.
  5. В случае, если вы что-то забыли, можно исправить ошибку и отправить на проверку повторно (нажав кнопку «Проверить выполнение»).
  6. После получения удовлетворительной оценки нажмите кнопку «Завершить задание», чтобы созданное окружение уничтожилось и вы могли приступить к следующему заданию.
  7. Если у вас закончилось время (истек таймер) — окружение будет автоматически уничтожено и вам придется начать выполнение заново.
  8. Также, если вы успешно сдали задание, но у вас остались вопросы — вы всегда сможете задать их куратору после проверки (используя кнопку «Задать вопрос куратору») или в чате практикума в любое удобное для вас время. Обращаем внимание — кураторы проверяют вопросы в течение 24 часов.

Задание:

  1. Установите PostgreSQL v13 на предоставленной VM c OS Ubuntu 20.04.
  2. Добавьте в PostgreSQL пользователя root c правами SUPERUSER.
  3. Подключитесь к PostgreSQL пользователем root.
  4. Создайте базу данных "rebrain_courses_db".
  5. Для работы с базой данных создайте пользователя "rebrain_admin".
  6. Выдайте все права пользователю "rebrain_admin" на базу данных "rebrain_courses_db" (в том числе CONNECT).
  7. Скачайте и установите prometheus-server, проверьте доступность сервиса (systemctl), посмотрите, открыт ли порт TCP/9090 (ss, netstat). Также настройте сбор данных о самом сервере (job_name: 'prometheus').
  8. Скачайте и установите в режиме сервиса последнюю версию node_exporter для OS Ubuntu 20.04 Focal, проверьте доступность сервиса (systemctl), посмотрите, открыт ли порт TCP/9100 (ss, netstat).
  9. Настройте новый источник данных для prometheus-server, подключите сбор данных с node_exporter (job_name: 'node_exporter').
  10. Скачайте последнюю версию Grafana для OS Ubuntu 20.04 Focal, установите ее в режиме сервиса, проверьте доступность сервиса (systemctl), посмотрите, открыт ли порт TCP/3000 (ss, netstat).
  11. Подключите к Grafana сервер prometheus в качесчтве источника данных для панелей мониторинга.
  12. Скачайте и импортируйте Dashboard 1860 для node_exporter. Выберите в качестве источника данных prometheus сервер.
  13. Проверьте работоспособность node_exporter воспользовавшись импортированной панелью мониторинга 1860. Все метрики должны быть видны на графиках и в полях значений.
  14. Скачайте и установите в качестве сервиса самую свежую версию postgres_exporter (можно сразу ставить через apt install prometheus-postgres-exporter), проверьте доступность сервиса (systemctl), посмотрите, открыт ли порт TCP/9187 (ss, netstat). Подключите сбор данных с prometheus-postgres-exporter (job_name: 'postgres_exporter').
  15. Добавьте в PostgreSQL пользователя rebrain_monitoring c правами SUPERUSER.
  16. Настройте окружение для postgres_exporter так, чтобы работало подключение к PostgreSQL к базе данных rebrain_courses_db с правами rebrain_monitoring. Для этого используйте файл "/etc/default/prometheus-postgres-exporter", в него в одну строку внесите данные о подключении (DATA_SOURCE_NAME).
  17. Скачайте и импортируйте Dashboard 9628 для postgres_exporter и мониторинга PostgreSQL. Выберите в качестве источника данных prometheus-server.
  18. Проверьте работоспособность postgres_exporter воспользовавшись импортированной панелью мониторинга 9628. Все метрики должны быть видны на графиках и в полях значений.
  19. Проинициализируйте pgbench для базы данных rebrain_courses_db для пользователя rebrain_monitoring (если это необходимо, поставьте пакет postgresql-client-common).
  20. Установите pgbouncer в качестве сервиса, проверьте доступность сервиса (systemctl), посмотрите, открыт ли порт TCP/6432 (ss, netstat). Настройте pgbouncer так, чтобы:
  • pgbouncer мог подключаться к базе данных "rebrain_courses_db" с именем пользователя "rebrain_monitoring"
  • pgbouncer слушал порт 6432
  • auth_type = md5
  • auth_file = /etc/pgbouncer/userlist.txt
  • pool_mode = transaction
  • настройка размера пула входных конектов на pgbouncer был выставлена так: max_client_conn = 1000
  • размер пула подключений к PostgreSQL был равен: default_pool_size = 30
21. Проинициализируйте pgbench для базы данных rebrain_courses_db. Проведите первый нагрузочный тест с помощью pgbench без pgbouncer (порт 5432, 900 конкурентных клиентов в 5 потоков, 180 секунд). Метрики для PostgreSQL будут изменяться с течением времени. 22. Теперь проведите второй нагрузочный тест с помощью pgbench с использованием pgbouncer в качестве пуллера(менеджера) соединений (порт 6432, 900 конкурентных клиентов в 5 потоков, 180 секунд). Метрики для PostgreSQL будут снова изменяться с течением времени. Обратите внимание на количество коннектов. 23. Проанализируйте графики на обеих панелях мониторинга, убедитесть, что нагрузочные тесты проведены успешно. Согласно графиков, вы должны были увидеть, что с включенным в тракт pgbouncer наблюдается уменьшение нагрузки на CPU, при этотм количество коннектов не превосходит значения, указаного в настройках pgbouncer (default_pool_size), а количесво верно обработанных транзакций в секунду выросло в несколько раз. 23. Если уверены, что все сделали правильно, сдавайте задание на проверку.
Вы ещё ни разу не отправили задание на проверку