← На главную

PgDog на Rust чинит SET и LISTEN/NOTIFY без правок, 2M запросов/с

07.07.2026 15:36 · hackernews

PgDog — это прокси для масштабирования Postgres. Главная фишка — пул соединений: много клиентов могут использовать одну базу, не превышая лимит. Классические решения вроде PgBouncer, RDS Proxy, Pgpool-II или Supavisor тоже это умеют, но PgDog решает проблему иначе.

Проблема других пулеров — «дырявая абстракция». Они заставляют менять код приложения. PgBouncer или RDS Proxy работают, но ты сразу замечаешь, что добавил прослойку, которая ломает привычное использование базы. Приходится идти на компромиссы, часто переписывая тысячи строк продакшен-кода. С PgDog этого не требуется.

Первое, что ломается при добавлении пулера — управление сессией, а именно команды SET. Они переопределяют настройки для конкретной сессии. Пулеры переиспользуют соединения между клиентами, и состояние одного «утекает» в другое. Если это SET statement_timeout TO '5m', то чужой медленный запрос может устроить инцидент. А если завязана Row Level Security (RLS) на сессионной переменной — строки просто исчезнут. Типичный совет — вообще не использовать SET. Но это значит отказаться от реальной фичи Postgres.

PgDog кладёт на это болт. Он поставляется со встроенным SQL парсером. Он детектит SET, запоминает переменные и значения для каждого клиента в прокси. Когда клиент шлёт запрос, PgDog сверяет состояние клиента и сервера, и если надо — подгоняет сервер серией SET. Алгоритм быстрый, а если нужно поменять несколько переменных — использует query pipelining, чтобы сделать это за один round trip. Производительность страдает незначительно, а ты продолжаешь пользоваться фичами Postgres.

Вторая проблема — LISTEN/NOTIFY. Это встроенная publish/subscribe очередь внутри Postgres. Удобная штука, но при добавлении пулера в transaction mode от неё приходилось отказываться. Многие мигрировали на SQS или Redis. PgDog и это чинит. Он обрабатывает обе команды внутри прокси, пересылая сообщения между своими процессами. Для клиента выглядит, будто PgDog — сам брокер, но на деле брокером остаётся Postgres. Транзакционная семантика NOTIFY сохраняется, включая те граничные случаи, из-за которых некоторые уронили базу (разработчики это пофиксили). Внутри используется Tokio broadcast channel для пересылки сообщений между клиентами в одном процессе, а для поддержки нескольких процессов — выделенное соединение с Postgres. Хитрое инженерное решение, чтобы фича «просто работала» при масштабировании.

Ещё одна особенность — многопоточность. PgDog построен на Tokio (Rust async runtime) с многопоточными воркерами. Каждый клиент — отдельная async задача, число задач растёт линейно с числом соединений. Это позволяет утилизировать несколько CPU, обслуживая больше клиентов и запросов в секунду из одного процесса. PgBouncer с SO_REUSEPORT и RDS Proxy с автоскейлингом заставляют «шардировать» пулы — каждый процесс имеет свой набор соединений, и клиент не может переключиться, если процесс перегружен. Многопоточность PgDog позволяет держать больше клиентов на меньшее число серверных соединений, эффективнее их используя. И внезапные всплески запросов обрабатываются без ожидания автоскейлинга. Плюс упрощается runbook — один источник метрик и health checks, без сложностей в ядре Linux или плоскости управления AWS RDS.

Проект работает в продакшене больше года, пулит соединения на скорости 2M запросов в секунду. Это open source, бесплатно, можно развернуть где угодно.

Читать оригинал →