Пулы соединений (pgbouncer)
Почему соединения к базе дорогие, как пул их переиспользует и зачем перед Postgres ставят pgbouncer.
Соединение к базе дорогое
В Postgres каждое подключение — отдельный процесс на стороне сервера. Он
ест память и время на установку. Пока приложений мало, это незаметно. Но
когда стоит десять копий приложения из урока про балансировку, и каждая
держит по двадцать соединений, набегает двести процессов. База упирается в
лимит max_connections и начинает отказывать в новых подключениях с
ошибкой too many connections.
Что делает пул
Пул соединений держит небольшой набор уже открытых соединений к базе и выдаёт их приложению на время запроса, а потом забирает обратно. Приложение не открывает соединение под каждый запрос, а берёт готовое из пула.
Пул бывает двух видов. Внутри приложения (библиотека-пул в самом сервисе) и внешний (отдельный сервис перед базой). Внешний нужен, когда копий приложения много: тогда суммарное число соединений к базе режет один общий пул, а не каждая копия по отдельности.
pgbouncer
pgbouncer — лёгкий внешний пул для Postgres. Приложения подключаются не к базе напрямую, а к pgbouncer, а он держит маленький набор соединений к самой базе.
Сотня клиентских подключений может обслуживаться двумя десятками реальных, потому что в каждый момент активно выполняется лишь часть запросов.
У pgbouncer есть режимы. transaction pooling (соединение выдаётся на одну транзакцию) даёт максимальную экономию и используется чаще всего; session pooling (на всю сессию клиента) безопаснее для фич, завязанных на состояние сессии, но экономит меньше.
Где это в проде
Связка простая: приложение знает только адрес pgbouncer, а тот разруливает реальные соединения. Это снимает с базы давление подключений, особенно когда приложение масштабируется горизонтально и копий становится много.
Признак, что пора ставить пул: ошибки too many connections или база ест
память сотнями процессов-соединений при том, что реальной нагрузки на
запросы немного.
Что важно запомнить
Каждое подключение к Postgres — процесс, и при горизонтальном масштабе
приложения их число упирается в max_connections. Пул соединений
переиспользует небольшой набор готовых соединений вместо открытия нового на
каждый запрос.
pgbouncer — внешний пул перед базой: сотни клиентских подключений обслуживаются десятками реальных. Чаще берут transaction pooling ради экономии.
Ставят пул, когда ловят too many connections или база тратит память на
сотни соединений при умеренной нагрузке.
В следующем уроке разберём Redis: кеш и общее состояние для масштабируемых сервисов.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс