2013-07-28 36 views
17

我需要一些幫助,在我的RoR4 Heroku應用程序上配置Puma(多線程+多核服務器)。 Heroku的文檔並不是最新的。我遵循這個:Concurrency and Database Connections的配置,它沒有提到集羣的配置,所以我不得不同時使用兩種類型(線程和多核)。Heroku上的美洲獅羣集配置

我目前的配置:

./Procfile

web: bundle exec puma -p $PORT -C config/puma.rb 

./config/puma.rb

environment production 
threads 0,16 

workers 4 
preload_app! 

on_worker_boot do 
    ActiveRecord::Base.connection_pool.disconnect! 

    ActiveSupport.on_load(:active_record) do 
    config = Rails.application.config.database_configuration[Rails.env] 
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds 
    config['pool']    = ENV['DB_POOL'] || 5 
    ActiveRecord::Base.establish_connection 
    end 
end 

問題:

a)是否需要像Unicorn那樣的before_fork/after_fork配置,因爲Cluster worker是分叉的?
b)如何調整我的線程數取決於我的應用程序 - 將其放下的原因是什麼? /在什麼情況下會有所作爲?是不是0:16已經優化?
c)Heroku數據庫允許500個連接。取決於線程,工作人員和動態計數,DB_POOL的值是多少? - 平行工作時,每個測功機每個工作線程的每個線程都需要唯一的數據庫連接嗎?

總的來說:我的配置對於併發性和性能應該如何?

+0

說到調整線程數。我閱讀了關於Unicorn工作調優的教程,該教程建議運行「ab」並增加工作者數(在您的案例中爲線程),直到性能下降(請求需要更多時間完成)爲止。這是很好的承擔了相當的動態網頁,並查看請求如何不同/併發比例首先採取行動(也有記住,如果你做多的要求Heroku上可能會打斷您懷疑DoS)的 –

+0

@MichaelSzyndel所以我基本上第一次去,雖然每個工人,檢查性能,然後通過線程並再次檢查?這不取決於究竟是什麼要求? – Nikom

+1

從我讀的地方Heroku有兩個核心(4個虛擬)每個測功機。每個測試程序擁有一個進程是最佳選擇,然後由您決定每個進程需要運行多少個線程。我會用ab來測試。請記住,如果您通過521MB的RAM,Heroku將發送警報,並在大於1GB時交換(與heroku文檔一起確認) –

回答

26

a)我需要像在 獨角獸那樣的before_fork/after_fork配置,因爲Cluster worker是分叉的嗎?

通常不會,但是因爲您使用的是preload_app,是的。預裝應用程序會啓動並運行一個實例,然後爲工作人員分配內存空間;結果是你的初始化器只能運行一次(可能分配數據庫連接等)。在這種情況下,您的on_worker_boot代碼是適當的。如果您沒有使用preload_app,那麼每個工作人員都會自行啓動,在這種情況下,使用初始化工具將非常適合您設置自定義連接。事實上,如果沒有preload_app,你的on_worker_boot塊會出錯,因爲那時ActiveRecord和朋友都沒有加載。

b)如何調整我的線程數取決於我的應用程序 - 什麼 將是它的理由呢? /它會在什麼情況下產生 差異?是不是0:16已經優化?

在Heroku(和我的測試)你是最符合您min/max線程,與max < = DB_POOL設置。 min線程允許您的應用程序在沒有負載的情況下減少資源,這通常很好釋放服務器上的資源,但在Heroku上可能不太需要;該dyno已經致力於提供Web請求,可能已經準備好了。雖然設置你的max線程< =不需要你DB_POOL環境變量,運行在池中的消耗你的所有數據庫連接的風險,那麼你有一個線程想要一個連接,但無法得到它,你可以得到舊的「ActiveRecord :: ConnectionTimeoutError - 無法在5秒內獲得數據庫連接。」錯誤。這取決於你的應用程序,但你很可能有max>DB_POOL並沒問題。我會說你DB_POOL應至少與您的min線程值,即使你的連接沒有即時加載(5:5個線程不會打開5個連接,如果你的應用程序從未訪問數據庫)。

c)在Heroku的數據庫允許500個連接。取決於線程,工作人員和動態計數,DB_POOL的值爲 會怎樣? - 當 並行工作時, 每個工人每個測功機的每個線程都需要唯一的DB連接嗎?

Production Tier允許500,是明確的:)

每個工人賽道每個線程都可以消耗的連接,這取決於他們是否都試圖在同一時間訪問數據庫。通常情況下,連接完成後會重新使用,但正如我在b)中所提到的,如果您的線程超過了您的池,則可能會有不好的時間。連接將被重用,所有這些都由ActiveRecord處理,但有時候並不理想。有時連接閒置或死亡,這就是爲什麼打開收割者建議,來檢測和回收死亡連接。

+0

我是對的,「工人2」意味着額外的美洲獅工人流程,所以總共有3個流程? – gaussblurinc

2

您不希望數據庫連接少於線程。請記住,每個單獨的進程都有自己的連接池,因此如果您的數據庫支持20個連接,並且您想運行2個進程,則可以運行的大多數線程不會冒超時,其中10個線程每個都有10個連接池。

你要離開鐵軌控制檯會話連接數。也要注意後臺工作人員,以及他們是否都是線程的。

如果你的員工都在一個單獨的進程(sidekiq),他們都會有自己的游泳池。如果您的工作線程是從web進程派生的(girl_friday或sucker_punch),您將希望DB_POOL大於Web線程的最大數量,因爲它們將共享連接池。