Apa*_*ith 5 database ruby-on-rails amazon-web-services puma ruby-on-rails-5
我ActiveRecord::ConnectionTimeoutError一天收到一两次。有人可以帮我计算我的应用程序与我的数据库建立了多少连接吗?并建议优化我的连接?
这是我的配置
自动售货机
Database : Mysql
Version : 5.7.23
Provider : AWS RDS (db.m5.large, vCPU: 2, RAM: 8GB)
Run Code Online (Sandbox Code Playgroud)
3台采用波纹管配置的服务器
# database.yml
pool: 20
# puma.rb
RAILS_MAX_THREADS : 5
WEB_CONCURRENCY : 2
Run Code Online (Sandbox Code Playgroud)
1 个带有波纹管配置的 sidekiq 服务器
# sidekiq
concurrency: 25
Run Code Online (Sandbox Code Playgroud)
我试图获得我的数据库能够处理的最大连接数
# MySQL Max connections ("show global variables like 'max_connections';")
624
Run Code Online (Sandbox Code Playgroud)
数据库连接总数等于每台服务器的连接数乘以服务器数。
数据库连接总数 = 每台服务器的连接数 * 服务器数量。
每台服务器的连接数 = AR 数据库池大小 * 每台服务器的进程数(通常使用 WEB_CONCURRENCY 或 SIDEKIQ_COUNT 设置)
因此,对于 Web 服务器,您拥有:
AR 数据库池大小 = 20
每台服务器的进程 = 2
服务器数量 = 3
数据库连接总数(Web 服务器)= 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 %>
此答案的大部分内容基于Nate Berkopec的Sidekiq 实践电子邮件系列
| 归档时间: |
|
| 查看次数: |
1307 次 |
| 最近记录: |