PgBouncer
Удивительное дело, что я до сих пор не написал про PgBouncer. Как написано на сайте — это «Lightweight connection pooler for PostgreSQL». Я бы первел это следующим образом. PgBouncer — это легкий менеджер соединений для PostgreSQL.
Дело в том, что postgres для каждого соединения создает новый процесс. Чтобы «удешевить» соединение с БД, современные библиотеки используют пул соединений. То есть, они один раз соединяются с БД, а потом многократно используют это соединение. Если в библиотеке работы с БД нет возможности «пулить» соединения, то здесь приходит на помощь PgBouncer. Вместо того, чтобы каждый раз создавать дорогое соединение с postgres, создается легкое соединение с PgBouncer, который пользуется уже существующим соединением с БД.
Если же встроенный пул соединений есть, то вроде бы и PgBouncer не нужен. Это действительно так, если у вас запущено
несколько процессов с вашим приложением. Но если ваша система достаточно велика, то сотни процессов вашего приложения
будут держать по одному или несколько соединений с БД. И тогда сотни процессов postgres, запущенные
на одной, пусть даже и мощной, машине, будут впустую тратить память и процессорное время. Вот тут приходит на помощь
PgBouncer, но не сразу. Для этого есть специальный режим pool_mode=transaction
. В этом случае, приложение будет
думать, что оно держит настоящее соединение, но на самом деле оно будет держать его только на время одной транзакции. Тут есть
свои минусы, если вы меняете какие-то параметры внутри сессии (соединения), то для вашего приложения в следующий раз
может достаться другое реальное соединение к БД и это будет очень неожиданно.
Именно поэтому модное нововведение в Rails 3.1 с компиляцией планов исполнения не будет работать в таком режиме, потому что скомпилированные планы запросов хранятся в сессии БД (то есть привязаны к конкретному соединению). Когда мы перейдем на Групоне на rails 3.1, я расскажу, что можно сделать, у меня есть две идеи.
Помимо экономии ресурсов, очень важная возможность при использовании PgBouncer — незаметная перезагрузка или переключение БД. То есть, вы можете настроить репликацию на новый сервер, дождаться, пока он синхронизируется со старым и переключить сервер в PgBouncer. При этом для приложения соединения просто повиснут на некоторое время. То же самое при рестарте postgres, если вам надо поменять какой-то параметр в конфиге, который не подхватывается на лету.
Такая «горячая» перезагрузка и смена postgres неоднократно испытывалась мною и значительно облегчала мне жизнь.