← Данные
11 мин · средне · Урок 3 из 5

Пулы соединений (pgbouncer)

Почему соединения к базе дорогие, как пул их переиспользует и зачем перед Postgres ставят pgbouncer.

Соединение к базе дорогое

В Postgres каждое подключение — отдельный процесс на стороне сервера. Он ест память и время на установку. Пока приложений мало, это незаметно. Но когда стоит десять копий приложения из урока про балансировку, и каждая держит по двадцать соединений, набегает двести процессов. База упирается в лимит max_connections и начинает отказывать в новых подключениях с ошибкой too many connections.

Что делает пул

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

приложение пул · 20 соединений Postgres

Пул бывает двух видов. Внутри приложения (библиотека-пул в самом сервисе) и внешний (отдельный сервис перед базой). Внешний нужен, когда копий приложения много: тогда суммарное число соединений к базе режет один общий пул, а не каждая копия по отдельности.

pgbouncer

pgbouncer — лёгкий внешний пул для Postgres. Приложения подключаются не к базе напрямую, а к pgbouncer, а он держит маленький набор соединений к самой базе.

app ×10 pgbouncer Postgres 200 клиентских держит набор 25 реальных

Сотня клиентских подключений может обслуживаться двумя десятками реальных, потому что в каждый момент активно выполняется лишь часть запросов.

У pgbouncer есть режимы. transaction pooling (соединение выдаётся на одну транзакцию) даёт максимальную экономию и используется чаще всего; session pooling (на всю сессию клиента) безопаснее для фич, завязанных на состояние сессии, но экономит меньше.

Где это в проде

Связка простая: приложение знает только адрес pgbouncer, а тот разруливает реальные соединения. Это снимает с базы давление подключений, особенно когда приложение масштабируется горизонтально и копий становится много.

Признак, что пора ставить пул: ошибки too many connections или база ест память сотнями процессов-соединений при том, что реальной нагрузки на запросы немного.

Что важно запомнить

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

pgbouncer — внешний пул перед базой: сотни клиентских подключений обслуживаются десятками реальных. Чаще берут transaction pooling ради экономии.

Ставят пул, когда ловят too many connections или база тратит память на сотни соединений при умеренной нагрузке.

В следующем уроке разберём Redis: кеш и общее состояние для масштабируемых сервисов.

Прошли материал до конца? Отметьте урок пройденным.