ruby-on-rails - Rails、Puma、Sidekiq 如何计算总数据库连接数?

标签 ruby-on-rails database amazon-web-services ruby-on-rails-5 puma

我一天收到一两次 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 BerkopecSidekiq in Practice 电子邮件系列

关于ruby-on-rails - Rails、Puma、Sidekiq 如何计算总数据库连接数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58426501/

相关文章:

javascript - 将 ruby​​ 数组转换为 javascript 数组无法正常工作

ruby-on-rails - 如何用第二个表中的列值覆盖表列值(如果存在)?

sql - Rails 按 :created_at, 返回 :status column, 的计数对表进行分组,然后使用每个唯一值的计数对 :status 列进行子分组

amazon-web-services - 在身份验证配置中找不到 Pod 执行角色或没有所有必需的权限。我该如何调试?

asp.net-mvc-4 - 作为 ASP.NET 的 session 提供程序的 AWS Dynamo DB 上的 400 错误请求

spring - 如何在 AWS Lambda 函数中从 AWS API Gateway URI 访问请求和路径变量

ruby-on-rails - Rails 4 嵌套表单 has_many 通过关联和数据库

php - postgres/pdo 查询绑定(bind)值错误

php - fatal error : Call to a member function prepare() on a non-object ERROR

database - 如何保护存储的用户数据 : phone numbers?