Отключение пула соединений в Rails для использования PgBouncer

#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.

  1. Означает ли добавление PgBouncer, что мы должны отключить пул соединений Rails?
  2. Если да, то как это работает, мы просто устанавливаем 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 упомянутые выше измененные настройки решают большинство проблем.