我一天收到一两次 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 服务器
# sidekiq
concurrency: 25
我试图获得我的数据库能够处理的最大连接数
# MySQL Max connections ("show global variables like 'max_connections';")
624
最佳答案
数据库的总连接数等于每台服务器的连接数乘以服务器数。
Total DB Connections = Connections per server * server count.
Connections per server = AR Database Pool Size * Processes per server (usually set with WEB_CONCURRENCY or SIDEKIQ_COUNT)
因此对于您拥有的网络服务器:
AR Database Pool Size = 20
Processes per server = 2
Server Count = 3
Total DB Connections(Web Server) = 20 * 2 * 3 = 120
sidekiq 服务器的:
AR Database Pool Size = 20
Processes per server = 1
Server Count = 1
Total DB Connections(Sidekiq Server) = 20 * 1 * 1 = 20
所以预期的数据库连接总数应该是140
,远低于 RDS 实例的限制。
我猜你得到的是 ActiveRecord::ConnectionTimeoutError
因为您的 Sidekiq 并发设置高于 AR 连接池值。所有 Sidekiq 线程都需要 ActiveRecord 数据库连接,因此将 AR 池大小设置为小于 Sidekiq 并发性的数字意味着一些 Sidekiq 线程将阻塞等待空闲数据库连接。在您的情况下,在某个时间点您可能有 25 个线程试图通过最多可以使用 20 个连接的数据库池访问数据库,如果一个线程无法在 5 秒内获得空闲的数据库连接,您将获得一个连接超时错误。
在 Sidekiq 中,总的数据库连接应该是
minimum(Threads That Need a Database Connection, AR Database Pool Size) * Processes per Server (WEB_CONCURRENCY or SIDEKIQ_COUNT) * Server Count.
另外还有 Sidekiq documentation指出
Starting in Rails 5, RAILS_MAX_THREADS can be used to configure Rails and Sidekiq concurrency. Note that ActiveRecord has a connection pool which needs to be properly configured in config/database.yml to work well with heavy concurrency. Set pool equal to the number of threads
pool: <%= ENV['RAILS_MAX_THREADS'] || 10 %>
大部分答案基于来自 Nate Berkopec 的 Sidekiq in Practice 电子邮件系列
关于ruby-on-rails - Rails、Puma、Sidekiq 如何计算总数据库连接数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58426501/