#ruby-on-rails #postgresql #pgbouncer
#ruby-on-rails #postgresql #pgbouncer
Вопрос:
У нас есть проект Ruby on Rails 4.2.8, который обращается к большой базе данных PostgreSQL. Мы собираемся добавить новый сервер для пула соединений с помощью PgBouncer.
Поскольку PgBouncer будет обрабатывать пул подключений к БД, нужно ли нам отключать Rails automatic connection pooling? У нас ничего не настроено в нашей базе данных.yml, поэтому я думаю, что используется значение по умолчанию (пул), равное 5.
- Означает ли добавление PgBouncer, что мы должны отключить пул соединений Rails?
- Если да, то как это работает, мы просто устанавливаем Pool равным 0 в database.yml?
Спасибо
Комментарии:
1. что вы, ребята, в итоге сделали?
Ответ №1:
TLDR; ничего не меняйте
Пул в rails отличается от пула в PGBouncer. Пул подключений rails — это группа подключений, доступных любому потоку в этом процессе, обычно всего 1. Каждое соединение в вашем пуле rails будет иметь подключение к вашей базе данных postgres или PGBouncer, если она находится перед postgres. В большом приложении rails вы будете запускать несколько процессов rails на каждом сервере и несколько серверов за балансировщиком нагрузки. Что — то вроде этого:
Без PGBouncer каждое подключение к postgres создает новый процесс postgres. В scale вы захотите ограничить количество запускаемых процессов postgres, чтобы не использовать процессор и память на максимуме. PGBouncer объединяет соединения из всех ваших пулов rails во всех процессах и на всех серверах и эффективно переключается между ними.
Комментарии:
1. Есть веская причина отключить пул соединений, rails 5 плохо работает с пулом транзакций pgbouncer, а долговременные соединения, которые использует пул соединений в rails, плохо работают с пулом сеансов pgbouncer, потому что в пуле сеансов 1 клиентское соединение сопоставляется с 1 серверным соединением. Таким образом, без отключения пула соединений rails для получения недолговечных соединений у нас не может быть больше потоков в rails, чем подключений в моей postgres db.
2. @FrederikBaetens высказывает очень обоснованную точку зрения. Мы столкнулись с тем, что PgBouncer не соблюдает некоторые настройки database.yml, такие как statement_timeout, поскольку SET / RESET не поддерживается в пуле транзакций. Ты пробовал это, Фредерик? (или кого-либо еще .. ?) Я бы подумал, что это приведет к некоторой задержке в приложении Rails, поскольку теперь ему необходимо создать TCP-соединение (при условии, что PgBouncer находится на отдельном компьютере) для каждого запроса, которому требуется DB.
3. Я не рассматривал настройку таких вещей, как statement_timeouts, но все, что нам нужно было сделать, чтобы пул транзакций работал правильно, — это отключить рекомендательные блокировки и отключить подготовленные инструкции . Для пула транзакций Afaik не нужно каждый раз устанавливать новое соединение. Соединения между pgbouncer и сервером БД являются постоянными. Соединения от вашего клиента к pgbouncer также являются постоянными, поскольку пул соединений rails постоянно поддерживает соединения с pgbouncer в пуле.
4. В идеале rails должен выполнять некоторую форму пула транзакций или операторов самостоятельно, с каким-либо субъектом базы данных, а не с 1 подключением на модель потока.
5. Для справки на будущее, afaik отключение пула подключений в rails невозможно, хотя иногда было бы удобнее иметь новые недолговечные подключения к БД по запросу без пула подключений. Но это не проблема, поскольку пул транзакций pgbouncer упомянутые выше измененные настройки решают большинство проблем.