Управление пулом подключений

PostgreSQL имеет ресурсоемкую архитектуру обработки соединений. Каждое входящее соединение создает новый серверный процесс. Это неэффективно, если речь идет о большом количестве подключений в производственном окружении. Когда клиент отправляет запрос к серверу PostgreSQL, создается соединение с базой данных. Пока сервер не ответит клиенту, соединение остается открытым. Под каждое из таких соединений выделяется память на сервере. Если соединения открываются достаточно часто, это может приводить к проблемам. Вот почему необходим PgBouncer. PgBouncer — это программа, управляющая пулом соединений PostgreSQL, которая позволяет увеличивать количество соединений без снижения производительности.

ПРИМЕЧАНИЕ
PgBouncer доступен в версии ADPG Enterprise. См. Настройка PgBouncer.

Как ADPG/PostgreSQL устанавливает соединения

ADPG/PostgreSQL реализует клиент-серверную модель по схеме "один процесс для одного пользователя". В этой модели каждый клиентский процесс подключается к одному серверному процессу. Поскольку изначально не определено, сколько соединений будет установлено, сервер PostgreSQL должен использовать процесс-супервизор, который запускает новый процесс каждый раз, когда запрашивается соединение. Этот процесс-супервизор называется postmaster и прослушивает указанный порт TCP/IP на предмет входящих соединений. Всякий раз, когда он обнаруживает запрос на соединение, он запускает новый backend-процесс. Эти серверные процессы взаимодействуют друг с другом и с другими процессами экземпляра сервера (a server instance), используя семафоры и общую память (shared memory) для обеспечения целостности данных при конкурентном доступе к ним. Каждый из этих серверных процессов может расширяться в зависимости от данных, к которым он обращается.

Несмотря на то, что под каждый новый backend-процесс выделяется память, количество доступной памяти не является основным ограничивающим фактором. Более тонкий и важный момент заключается в том, что postmaster и его внутренние процессы совместно используют память для коммуникации, и некоторые части этого общего пространства являются глобальными узкими местами. Например, в PostgreSQL существует структура (PROC_HDR), которая отслеживает каждый текущий процесс или транзакцию. Операции, которые происходят в любом backend-процессе, требуют прохождения всего списка процессов или транзакций, сохраненных в этой структуре. Для добавления нового процесса используется эксклюзивная блокировка. Совокупный эффект заключается в том, что производительность любого backend-процесса обратно пропорциональна количеству всех активных backend-процессов в системе.

Конфигурационный параметр ADPG/PostgreSQL max_connections определяет максимальное количество одновременных подключений к серверу. Значение по умолчанию — 100. С большой долей вероятности такого количества подключений может быть недостаточно в производственном окружении.

Как работает PgBouncer

PgBouncer — это утилита, которая управляет пулом соединений. Клиентское приложение может подключиться к PgBouncer, как если бы это был сервер ADPG/PostgreSQL.

Когда PgBouncer получает запрос на клиентское соединение, он выполняет аутентификацию от имени сервера PostgreSQL. PgBouncer поддерживает все механизмы аутентификации, которые доступны в PostgreSQL. Важным моментом является то, что PgBouncer кеширует соединения.

Если аутентификация прошла успешно, PgBouncer проверяет наличие кешированного соединения с комбинацией тех же имени пользователя и базы данных. Если кешированное соединение найдено, PgBouncer возвращает соединение клиенту. Если соединение не найдено, PgBouncer создает новое соединение. Эта операция не должна нарушать ограничения, установленные в следующих параметрах: default_pool_size, max_client_conn, max_db_connections и max_user_connections. Все эти значения можно определить в настройках PgBouncer. Если создание нового соединения нарушает какие-либо ограничения, PgBouncer ставит соединение в очередь до тех пор, пока не появится возможность открыть новое, если только не превышено значение max_client_conn. Превышение значения max_client_conn прерывает соединение.

В режиме transaction или statement операции, следующие за аутентификацией, выполняются только тогда, когда клиент начинает выполнять транзакцию или оператор соответственно. Режимы пула PgBouncer описаны ниже.

Схема работы PgBouncer
Схема работы PgBouncer
Схема работы PgBouncer
Схема работы PgBouncer

Прежде чем вернуть соединение в пул, PgBouncer выполняет запрос сброса, чтобы удалить всю информацию о сессии. Такой подход делает безопасным совместное использование соединений клиентами.

PgBouncer может помочь оптимизировать:

  • сетевой трафик;

  • накладные расходы на запуск нового серверного процесса и аутентификацию.

PgBouncer не поддерживает автоматическую балансировку нагрузки или режим высокой отказоустойчивости, но ADPG Enterprise Edition предоставляет эти функции. См. Балансировка нагрузки.

PgBouncer имеет следующие преимущества:

  • Не требует изменения кода на стороне клиента.

  • Предоставляет сквозную аутентификацию. PgBouncer может безопасно аутентифицировать пользователя, не имея доступа к его паролям. Это делает PgBouncer более безопасным и простым в обслуживании — не нужно обновлять PgBouncer каждый раз, когда пользователь обновляет свой пароль.

  • Представляет собой одиночный процесс, и все команды клиента и ответы сервера проходят через него без какой-либо обработки. Следовательно, он занимает небольшой объем памяти.

  • Может значительно улучшить количество транзакций в секунду, которые обрабатывает сервер, и хорошо масштабируется для многочисленных клиентов.

Режимы PgBouncer

Режимы PgBouncer позволяют пользователю решать, когда соединение должно быть возвращено в пул. Доступны следующие режимы:

Установить нужный режим можно на вкладке Primary Configuration сервиса ADPG. См. Настройка PgBouncer.

Session

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

Transaction

В режиме transaction соединение возвращается в пул, когда клиент завершает транзакцию. Нет никакой гарантии, что две транзакции, выполняемые на одном и том же клиентском соединении PgBouncer, будут выполняться на одном и том же серверном соединении PgBouncer. Соединение с сервером назначается клиентскому соединению всякий раз, когда клиент начинает новую транзакцию, и освобождается в пул, когда клиент завершает транзакцию, например, с использованием ROLLBACK или COMMIT, a не тогда, когда клиент отключается. Обратите внимание, что в PostgreSQL если транзакция не запускается явно, каждый запрос выполняется в виде индивидуальной транзакции. См. Transactions.

Режим transaction обеспечивает лучшую производительность и позволяет сократить количество простаивающих транзакций, в дополнение к сокращению времени, затрачиваемого на установление соединений и аутентификацию пользователей.

В этом режиме необходимо быть осторожным при использовании последовательностей, рекомендательных блокировок и %_SHARED в функциях PL/Perl. Кроме того, планы запросов, созданные операторами PREPARE, кешируются и существуют вне транзакции. Их использование в режиме transaction может привести к ошибкам или неожиданным результатам.

Полный список функционала PostgreSQL, основанного на специфике сессий, который не поддерживается в режиме transaction:

За дополнительной информацией обратитесь к статье PgBouncer features.

Statement

В режиме statement соединение возвращается в пул сразу после выполнения оператора. Это самый агрессивный режим. Его можно рассматривать как пул транзакций с одним ограничением: транзакции с несколькими операторами не допускаются. Режим statement предназначен для обеспечения режима автоматической фиксации на клиенте, в первую очередь ориентированного на PL/Proxy.

Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней