嘿。我使用delayed_job進行後臺處理。我有8個CPU服務器,MySQL和我開始7 delayed_job的處理Rails運行多個delayed_job - 鎖表
RAILS_ENV=production script/delayed_job -n 7 start
Q1: 我想知道是有可能,2個或更多的delayed_job進程開始處理同樣的處理(相同的記錄行中數據庫delayed_jobs)。我檢查了delayed_job插件的代碼,但無法以應該的方式找到鎖定指令(無鎖定表或SELECT ... FOR UPDATE)。
我認爲每個進程都應該在執行lock_by列上的UPDATE之前鎖定數據庫表。他們通過更新locked_by字段來鎖定記錄(UPDATE delayed_jobs SET locked_by ...)。這真的夠了嗎?不需要鎖定?爲什麼?我知道UPDATE的優先級高於SELECT,但我認爲這在這種情況下不起作用。
我的MULTY線程情況的理解是:
Process1: Get waiting job X. [OK]
Process2: Get waiting jobs X. [OK]
Process1: Update locked_by field. [OK]
Process2: Update locked_by field. [OK]
Process1: Get waiting job X. [Already processed]
Process2: Get waiting jobs X. [Already processed]
我認爲在某些情況下,更多的就業機會可以得到相同的信息,並可以開始處理相同的過程。
Q2: 是7 delayed_jobs對8CPU服務器來說是一個好數字嗎?爲什麼是/不是。
Thx 10x!
所以你說每個過程都是原子風格的過程,並且是安全的? – xpepermint 2010-04-25 14:24:51
我認爲這裏缺少的是SELECT ... FOR UPDATE。 ? – xpepermint 2010-04-25 15:25:55
查詢是原子的。因此,如果執行查詢UPDATE作業SET locked_at ='..',locked_by = 1 WHERE id = 12和(locked_at爲null或locked_at <'..')',那麼locked_at和locked_by只會在沒有其他有效的鎖。 DBMS首先檢查where條件然後執行更新,並確保行之間沒有更改。因此你不能覆蓋一個存在的鎖。 – gregor 2010-04-25 17:20:59