簡體   English   中英

后台作業需要兩倍於rails內相同操作的時間

[英]Background job taking twice the time that the same operation within rails

在我的Rails應用程序中,我有一個很長的計算需要大量的數據庫訪問。

為了縮短它,我的計算耗時25秒。

在后台作業(一個大的單個工作者)中實現相同的計算時,相同的計算需要兩倍的相同時間(即50秒)。 我已經嘗試了幾種技術來將工作放在后台進程中,沒有對我的性能產生影響=>使用DelayJob / Sidekiq /在我的rails中執行該過程但是在為工作創建的線程中,但是所有都具有相同的影響我的表現* 2。

這種性能差異僅存在於rails'生產'環境中。 看起來有一個由rails完成的優化,這在我的后台作業中沒有完成。

我的技術環境如下=>

  • 我正在使用ruby 2.0 / rails 4
  • 我正在使用獨角獸(但沒有它我有同樣的問題)。
  • 這項工作是使用Rails.cache來存儲一些部分計算。
  • 我正在使用postgresql

有沒有人知道這種影響可能來自哪里?

我假設您將后台作業速度與Web請求期間運行操作的速度進行比較? 如果是這樣,您可能會受益於Rails的QueryCache ,后者在Web請求期間緩存數據庫查詢。 嘗試禁用它,如下所述:

全局禁用Rails SQL查詢緩存

如果這導致作業的Web請求版本與后台作業一樣長,那么您就找到了罪魁禍首。 然后,您可以在后台作業上啟用查詢緩存以加快速度(如果它對您的應用程序有意義)。

后台工作不是需要用於加速事情的東西。 它的主要意義是“發射並忘記”並同步刪除25秒計算並異步添加更多計算。 因此,您可以提供她請求正在處理的用戶響應,並在以后計算時返回。

您可以通過將大任務分成一些小任務並同時運行來從后台工作中獲取速度增益。 在你的情況下,我認為這是不可能使用的,因為在你的計算中依賴於操作。

因此,如果您想加快計算速度,則需要研究數據結構的非規范化,並在更新此計算的源數據時為您的大計算存儲一些計算值。 因此,您將根據用戶對結果的請求計算較少,而對數據存儲的計算更多。 這是使用后台工作的好地方。 因此,您完成數據更新,為更新緩存創建后台任務。 如果用戶在此任務完成之前請求計算,您仍需要等待緩存填充。

更新:我想我仍然需要回答你的主要問題。 所以基本上這個后台任務處理的額外時間來自實現。 由於“火災和遺忘”的方法,沒有人需要后台任務調度程序將消耗大量的處理器時間來監控新的工作。 我不完全確定,但如果你的計算會復雜兩倍,那么時間增益將是25秒。

我的猜測是,額外的時間來自后台工作人員加載rails和所有應用程序的需要。 我的線索是,你說在生產模式下Rails的差異最大。 在生產模式下,對應用程序的后續調用使用app和類緩存。

如何檢查這個假設:

更改后台作業以執行以下操作:

  1. 啟動工作程序之前打印日志消息
  2. 啟動工人
  3. 運行你的計算。 作為計算啟動的一部分,打印日志消息
  4. 打印另一條日志消息
  5. 再次運行您的計算
  6. 打印另一條日志消息

然后比較兩次運行計算。

當然,你也可以從數據庫緩存中獲得額外的時間好處,代碼可能仍然駐留在內存中等等。但是如果第二次運行速度要快得多,那么第二次運行沒有重啟Rails的事實就更為重要。

此外,步驟1和3之間的日志消息之間的時間也將幫助您了解啟動時間。

修復

干嘛要等? 最重要的是:為什么你需要更快的結果? 例如,告訴您的用戶結果將在計算后通過電子郵件發送給他們。 或者讓您的用戶看到計算在后台進行,然后向他們顯示結果。

任何長時間運行計算的關鍵是在后台進行,並鼓勵用戶不要等待結果。 他們應該能夠做其他事情,直到他們得到結果。

自動開始計算一旦用戶登錄,或在他們做了一些有趣的事情后,就開始計算。 這樣,當(和如果)用戶要求計算時,答案將要么已經完成,要么很快就會完成。

根據需要緩存結果並破壞緩存與上面類似,定期自動開始計算。 如果用戶更改了某些數據,則通過破壞緩存重新開始計算。 如果計算過程中更改了數據,還有一些方法可以暫停任何正在進行的計算。

預先計算部分計算為什么要花費25秒或更多時間進行dbms計算? 可能是你應該改變計算。 調查添加索引,匯總表,反規范化,將計算拆分為可預先計算的較小步驟等。

暫無
暫無

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

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