Rails Puma用完了Redis连接

我已经在SO上查看了其他类似的问题但是不能很好地将事情拼凑在一起。 我有一个Rails应用程序(在Heroku上),它使用Puma同时具有多个进程和多个线程。 我的应用程序还使用Redis作为辅助数据存储(除了SQL数据库),直接查询Redis(通过connection_pool gem)。 这是我的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,我发现自己经常超过这个限制,尽管应该是(据我所知)每个进程只有5个连接分布在4个工作进程中。

事实上,当我将REDIS_CONNS_PER_PROCESS设置为1时,我甚至得到max number of clients reached Redis错误。是否为每个线程而不是每个进程调用on_worker_boot

我也尝试过使用一个单独的redis.rb初始化程序,即使REDIS_CONNS_PER_PROCESS为1,它仍然会给我错误。这看起来很奇怪,因为如果我正确地进行数学处理,我应该能够达到4(4个工作进程) + 1个主进程)*每个进程4个连接。 (请注意,出于这个问题的目的,我忽略了部署时出现的错误,因为我假设Heroku可能在该过程中连接新旧进程,即使我没有使用Preboot。)

我在哪里误解这一切是如何组合在一起的?

我有类似的问题。 起初我使用redis-togo,它没有问题。 但是当我从redis-togo更改为Heroku redis之后,我得到了“ERR最大客户端数量达到”错误。

我的应用程序代码没有更改,redis提供商的更改是唯一的。

我在Heroku支持处开了一张票,他们建议我更改超时值的默认设置。

https://devcenter.heroku.com/articles/heroku-redis#configuring-your-instance

在我更改了Heroku redis的默认超时值之后,每个问题都解决了。 我想redis提供程序的redis timeout的默认值是不同的。 和Heroku redis的默认设置为0.“值为零表示连接不会关闭。”

我希望我的经验很有帮助。

在进一步阅读和测试之后,我最终将我的Redis连接池代码移动到一个单独的初始化程序中。 不幸的是,这根本没有解决我的问题 – 尽管有很多修改过程和连接数字,我仍然得到max number of clients reached错误之前的方式。

事实certificate,答案是将Redis提供商从Heroku Redis切换到Redis Cloud。 我不确定为什么Heroku Redis不允许它所宣传的连接数量,但在一些调查中,Redis Cloud实际上似乎允许更多的连接而不是广告(或者至少限制连接透明且没有错误),没有任何问题。 哇。 他们肯定赢得了我的业务。

我也遇到了这个问题,虽然Heroku Redis仪表板只显示了几个连接,但我的连接已经用完了。

然后我联系了Heroku支持,他们告诉我仪表板只显示活动的客户端/连接 ,而不是空闲的客户端/连接

因此Redis超时为0(永不超时),重启后Redis连接空闲,新的连接打开。 所以每次重启都会使情况变得更糟

如本页其他人所述,解决方案是将超时设置为0以外的其他值:

 heroku redis:timeout -s 10 -a APPLICATION_NAME 

这使得连接在10秒后死亡,这应该不是问题,因为在使用它时它将保持打开(没有不必要的关闭)。

当您只有很少的流量时,您可以考虑将其设置为更高的值。