Rails, Puma, Sidekiq, как рассчитать общее количество подключений к БД? - PullRequest
3 голосов
/ 17 октября 2019

Я получаю ActiveRecord::ConnectionTimeoutError один или два раза в день. Может ли кто-нибудь помочь мне рассчитать, сколько соединений мое приложение устанавливает с моей БД? и предложение оптимизировать мои подключения?

Вот моя конфигурация

AWS

Database : Mysql   
Version  : 5.7.23   
Provider : AWS RDS (db.m5.large, vCPU: 2, RAM: 8GB)

3 сервера с нижеуказанными конфигурациями

# database.yml
  pool: 20

# puma.rb 
  RAILS_MAX_THREADS : 5
  WEB_CONCURRENCY   : 2

1 sidekiq serverс нижеуказанной конфигурацией

# sidekiq 
  concurrency:  25

Я пытался получить максимальное количество соединений, которые может обрабатывать моя БД

# MySQL Max connections ("show global variables like 'max_connections';")
  624

1 Ответ

0 голосов
/ 18 октября 2019

Общее количество соединений с базой данных равно числу соединений на сервер, умноженному на количество серверов.

Общее количество соединений с БД = Соединений на сервер * количество серверов.

Соединения на сервер = размер пула базы данных AR * Процессы на сервер (обычно устанавливаются с помощью WEB_CONCURRENCY или SIDEKIQ_COUNT)

Итак, для веб-серверов у вас есть:

Размер пула базы данных AR= 20

Количество процессов на сервере = 2

Количество серверов = 3

Всего подключений к БД (веб-сервер) = 20 * 2 * 3 = 120

Для сервера sidekiq:

Размер пула базы данных AR = 20

Количество процессов на сервере = 1

Количество серверов = 1

Общее количество подключений к БД (сервер Sidekiq) = 20 * 1 * 1 = 20

Таким образом, общее ожидаемое количество подключений к БД должно составлять 140, что значительно ниже предела экземпляра RDS.

Я предполагаю, что вы получаете ActiveRecord::ConnectionTimeoutError, потому что ваш параметр параллелизма Sidekiq выше, чем значение пула соединений AR. Все потоки Sidekiq требуют подключения к базе данных ActiveRecord, поэтому установка размера пула AR на меньше , чем параллелизм Sidekiq, означает, что некоторые потоки Sidekiq будут заблокированы в ожидании свободного подключения к базе данных. В вашем случае, в какой-то момент времени у вас может быть 25 потоков, пытающихся получить доступ к базе данных через пул базы данных, который может использовать не более 20 соединений, и если поток не может получить бесплатное соединение с базой данных в течение 5 секунд, вы получаете соединениеошибка тайм-аута.

В Sidekiq общее количество подключений к БД должно составлять

минимум (потоки, которым требуется подключение к базе данных, размер пула базы данных AR) * Количество процессов на сервер (WEB_CONCURRENCY или SIDEKIQ_COUNT) * Количество серверов.

Кроме того, в документации Sidekiq указано, что

Начиная с Rails 5, RAILS_MAX_THREADS может использоваться для настройки параллелизма Rails и Sidekiq. Обратите внимание, что ActiveRecord имеет пул соединений, который должен быть правильно настроен в config / database.yml, чтобы хорошо работать с тяжелым параллелизмом. Установите пул равным количеству потоков pool: <%= ENV['RAILS_MAX_THREADS'] || 10 %>

Большая часть этого ответа основана на Sidekiq на практике серия электронных писем от Nate Berkopec

...