小编典典

Rails Puma用尽Redis连接

redis

我已经在SO上寻找了其他类似的问题,但是不能很好地将事情拼凑在一起。我有一个Rails应用程序(在Heroku上),该应用程序在多个进程和多个线程中都使用了Puma。我的应用程序还使用Redis作为辅助数据存储(除了SQL数据库),直接(通过connection_poolgem)查询Redis
。这是我的Puma配置文件:

workers Integer(ENV["WEB_CONCURRENCY"] || 4)
threads_count = Integer(ENV["MAX_THREADS"] || 5)
threads threads_count, threads_count

preload_app!

rackup DefaultRackup
port ENV["PORT"] || 3000
environment ENV["RACK_ENV"] || "development"

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  ActiveRecord::Base.establish_connection

  redis_connections_per_process = Integer(ENV["REDIS_CONNS_PER_PROCESS"] || 5)
  $redis = ConnectionPool.new(size: redis_connections_per_process) do
    Redis.new(url: ENV["REDIS_URL"] || "redis://localhost:6379/0")
  end
end

我的Redis实例的连接限制为20,尽管有4个工作进程中每个进程应该有5个连接(据我所知),但我发现自己经常超过该限制。

实际上,max number of clients reached当我设置REDIS_CONNS_PER_PROCESS为1
时,我什至会收到Redis错误。是on_worker_boot为每个线程而不是每个进程调用的吗?

我也尝试过使用单独的redis.rb初始化程序,即使在REDIS_CONNS_PER_PROCESS1
时也仍然会出现错误。这似乎很奇怪,因为如果我正确地进行数学运算,我应该可以将其设置为4(4个工作进程+ 1个主进程)
)*每个进程4个连接。(请注意,出于这个问题的目的,我忽略了部署过程中发生的错误,因为我假设Heroku在该过程中可能同时连接了新旧进程,即使我没有使用Preboot。)

我在哪里误解了这一切如何融合在一起?


阅读 484

收藏
2020-06-20

共1个答案

小编典典

经过进一步的阅读和测试之后,我最终将Redis连接池代码移到了单独的初始化程序中。不幸的是,这根本解决不了我的问题-
尽管对进程和连接号进行了很多修改,但max number of clients reached在我本应该解决之前,我仍然遇到了错误。

事实证明,答案是将Redis提供程序从Heroku Redis切换到Redis
Cloud。我不知道为什么的Heroku的Redis是不允许其通告的连接数,但在一番调查Redis的云实际上出现,让 更多
的连接比广告(或者至少限制连接,透明,不错误)没有任何问题的任何责任。哇。他们当然赢得了我的生意。

2020-06-20