[英]Best solution for running multiple intensive jobs at specific times
我們有一個Web應用程序,該應用程序使用IMAP在用戶定義的時間有條件地將郵件插入用戶的郵箱。
這些“作業”中的每一個都存儲在帶有時間戳的MySQL數據庫中,該時間戳表示應在何時運行該作業(可能是未來數月)。 用戶可以隨時取消作業。
問題在於建立IMAP連接是一個緩慢的過程,在插入消息之前,我們經常必須有條件地檢查收件箱(或類似郵件)中是否有人的答復,這給每個作業增加了可觀的處理開銷。
當前,我們有一個系統,每分鍾左右運行一次cron腳本,以便從數據庫中獲取需要在接下來的X分鍾內交付的所有作業。 然后,將它們拆分為Z個作業的批處理,並為每個批次執行異步POST請求,並將這些Z個作業的所有數據返回到同一服務器(以實現“偽”多線程)。 然后,服務器處理通過HTTP傳入的每批Z作業。
我們使用異步HTTP POST進行多線程處理而不是使用諸如pnctl_fork之類的原因是,以便我們可以添加其他服務器,並讓它們將數據發布到這些服務器,然后讓它們運行作業而不是當前服務器。
所以我的問題是-有更好的方法嗎?
我很喜歡可以使用像beantalkd這樣的工作隊列,但是它們是否適合必須在特定時間運行作業的模型?
另外,由於我們仍然需要將作業保留在數據庫中(因為我們需要為用戶提供用於管理作業的UI),因此在某個地方添加工作隊列實際上會增加而不是減少開銷?
我敢肯定,有更好的方法可以滿足我們的需求-任何建議將不勝感激!
我們正在使用PHP來完成所有這些工作,因此基於PHP的兼容解決方案確實是我們所需要的。
Beanstalkd將是執行此操作的合理方法。 它的概念put-with-delay
,所以你可以定期填補你的一條消息主存儲隊列,這將能夠被保留,並運行,在X
你希望它運行秒(時間-
現在的時間)。
然后,工作程序將正常運行,連接到beantalkd守護程序,並等待保留新作業。 如果沒有HTTP連接的開銷,它的效率也將大大提高。 舉例來說,我曾經通過HTTP將消息發布到Amazon SQS。 最多最多只能達到20 QPS,但是Beanstalkd幾乎不費勁就接受了每秒超過一千的速度。
編輯添加:您可以在不知道作業ID的情況下刪除作業,盡管可以將其存儲在外部。 OTOH,用戶是否必須能夠在最后一刻之前隨時刪除作業? 您不必提前數周或數月就將作業放入隊列中,因此,您仍然只有一個DB讀取器,每隔1至5分鍾運行一次,以將接下來的幾份作業放入隊列中,並且仍然擁有所需數量的工人,他們可以帶來更高的效率。
最終,它取決於您正在執行的數據庫讀/寫的數量,以及數據庫服務器如何處理它們。
如果您現在所做的不是問題,並且在增加負載后也不會變得如此,請繼續。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.