33.3. Настройка встроенного пула соединений

33.3.1. Включение пула соединений

Управление пулом соединений осуществляется в первую очередь с помощью двух параметров конфигурации: session_pool_size и max_sessions. Для включения пула соединений в параметре session_pool_size нужно задать ненулевой размер пула. Если этот параметр задан, Postgres Pro задействует пулы обслуживающих процессов для работы со всеми базами данных, за исключением баз, обслуживаемых выделенными процессами.

Переменная session_pool_size устанавливает максимальное число обслуживающих процессов в пуле для отдельно взятой базы данных. Таким образом, общее число обслуживающих процессов, работающих в пуле, ограничивается значением session_pool_size * N, где N — число баз. Оптимальное значение session_pool_size во многом зависит от системных ресурсов. Если значение будет слишком маленьким, сервер не сможет использовать все имеющиеся ресурсы, а если слишком большим, производительность может снизиться из-за постоянных конфликтов блокировок и снимков.

Параметр max_sessions определяет максимальное число сеансов, которые могут обслуживаться одним процессом. Таким образом, максимальное число подключений для одной базы данных ограничивается значением session_pool_size * max_sessions. От параметра max_sessions зависит только потенциальный размер очереди в каждом обслуживающем процессе; негативного влияния на потребление ресурсов он не оказывает. Значение по умолчанию — 1000.

Кроме того, вы можете настроить количество приёмников, которые будут получать стартовые пакеты клиентов и определять, к какому конкретному пулу должно относиться соединение. По умолчанию используется два процесса-приёмника. Изменить это число позволяет параметр конфигурации connection_pool_workers.

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

33.3.2. Выделенные обслуживающие процессы

Postgres Pro позволяет отключить использование пула для некоторых пользователей и баз данных, чтобы для каждого соединения запускался отдельный процесс. Такие пользователи и базы данных не используют обслуживающие процессы из общего пула, а получают выделенные процессы, обслуживающие только одно соединение. Количество таких процессов не ограничивается, поэтому таким клиентам не нужно ждать освобождения одного из общих процессов в пуле — они могут обращаться к своим базам данных немедленно.

По умолчанию выделенные обслуживающие процессы задействуются для подключений к базам данных postgres, template0 и template1, а также для любых подключений пользователя postgres. Если вы хотите поменять это поведение и задействовать выделенные процессы для других пользователей или баз данных, измените параметры dedicated_users и dedicated_databases, соответственно, и вызовите pg_reload_conf().

33.3.3. Выбор политики распределения

Так как postmaster распределяет сеансы клиентов между обслуживающими процессами в момент подключения, нагрузка может распределиться неравномерно: одни процессы будут простаивать, а другие будут перегружены, и подключённые к последним клиенты столкнутся с задержками при выполнении запросов. Для изменения метода распределения сеансов между процессами предназначен параметр конфигурации session_schedule, определяющий политику распределения. Воспользовавшись им, вы можете выбрать политику round-robin (по порядку; это вариант по умолчанию), random (случайное распределение) и load-balancing (распределение нагрузки).

Политики random и round-robin должны хорошо работать с равномерными нагрузкой, однако если характер нагрузки иной, более подходящей может быть политика load-balancing. С такой политикой postmaster выбирает для нового подключения процесс с наименьшей нагрузкой, которая определяется по числу сеансов, ожидающих выполнения транзакций в данном процессе.

Вы можете проверить текущую нагрузку обслуживающего процесса, вызвав функцию pg_backend_load_average(pid), где pid — идентификатор интересующего вас процесса (см. Таблицу 27.34). К сожалению, даже с самым удачным распределением во время подключения нельзя гарантировать, что характер нагрузки не изменится в будущем: некоторые сеансы могут завершиться, а простаивающие сеансы могут в любой момент активироваться.

33.3.4. Освобождение ресурсов в пуле

Процессы, запускаемые для обслуживания подключающихся клиентов, продолжают работать и тогда, когда все их клиенты отключаются. Хотя это позволяет повторно использовать освободившиеся процессы для будущих подключений, иногда возникает потребность завершить их. Например, вы не сможете удалить базу данных или пользователя, пока в связанном с базой или пользователем пуле работает хотя бы один процесс.

Чтобы завершить неиспользуемые обслуживающие процессы без перезапуска сервера, можно сделать следующее:

  1. Задать для переменной restart_pooler_on_reload значение true.

  2. Вызвать функцию pg_reload_conf() для перезагрузки конфигурации сервера.

Также можно задать параметр конфигурации idle_pool_backend_timeout, чтобы неиспользуемые процессы завершались и системные ресурсы освобождались автоматически после заданного тайм-аута.