簡體   English   中英

Rails Puma用盡Redis連接

[英]Rails Puma running out of Redis connections

我已經在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錯誤的max number of clients reached 。是否為每個線程而不是每個進程調用on_worker_boot

我還嘗試過使用單獨的redis.rb初始化程序,即使REDIS_CONNS_PER_PROCESS為1時,該初始化程序仍然會給我帶來錯誤。這似乎很奇怪,因為如果我正確地進行數學運算,則我最多可以將其設置為4(4個輔助進程) + 1個主進程)*每個進程4個連接。 (請注意,出於這個問題的目的,我忽略了部署過程中發生的錯誤,因為我假設Heroku在該過程中可能同時連接了新舊進程,即使我沒有使用Preboot。)

我在哪里誤解了這一切如何融合在一起?

我有類似的問題。 最初,我使用redis-gogo,它沒有問題。 但是,當我從redis-togo更改為Heroku redis之后,我得到了“ ERR達到最大客戶端數”錯誤。

我的應用程序的代碼未更改,redis提供程序的更改是唯一的。

我在Heroku支持人員處打開了故障單,他們建議我更改超時值的默認設置。

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

更改Heroku redis的默認超時值后,所有問題都解決了。 我猜redis提供程序的redis超時默認值是不同的。 而Heroku redis的默認設置為0。“零值表示連接不會關閉。”

希望我的經驗對您有所幫助。

在進一步閱讀和測試之后,我最終將Redis連接池代碼移到了單獨的初始化程序中。 不幸的是,這根本解決不了我的問題-盡管對進程和連接號進行了很多修改,但在max number of clients reached應有的錯誤max number of clients reached之前,我仍在獲得max number of clients reached

事實證明,答案是將Redis提供程序從Heroku Redis切換到Redis Cloud。 我不知道為什么的Heroku的Redis是不允許其通告的連接數,但在一番調查Redis的雲實際上似乎允許比廣告(或者至少限制連接,透明,不錯誤)不用任何問題, 更多的連接。 哇。 他們當然贏得了我的生意。

我也遇到了這個問題,盡管Heroku Redis儀表板只顯示了幾個連接,但連接用盡了。

然后我聯系了Heroku支持,他們告訴我儀表板僅顯示活動的客戶端/連接 ,而不顯示空閑的客戶端/連接

因此,由於Redis超時為0(從不超時),因此在重新啟動時,Redis連接處於空閑狀態並打開了新的連接。 因此,每次重新啟動時情況都會變得更糟

正如該頁面上其他人所提到的,一種解決方案是將超時設置為非0的值:

heroku redis:timeout -s 10 -a APPLICATION_NAME

這會使連接在10秒鍾后死掉,這不成問題,因為在使用時它將保持打開狀態(沒有不必要的關閉)。

當您的流量很少時,您可以考慮將其設置為更高的流量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM