2014-04-01 68 views
4

場景:可擴展的作業隊列系統

TL; DR - 我需要根據未來的時間戳,而不是將其插入

順序觸發工作隊列系統我有一個條目的MySQL數據庫,用於詳細說明需要執行的特定事件(主要包括一系列算術計算和數據庫插入/更新),並基於時間戳進行精確排序。條目插入的時間和事件「執行」的時間沒有關聯,並且由外部因素決定。該表還包含第二列毫秒,這增加了時間精度。

這表是工作「隊列」,這將包含設置爲從幾秒鐘之間的任何地方在未來執行幾天條目的一部分,並可能有多達數千個條目的添加每一秒。隊列需要不斷解析(每秒) - 也許在這第二次做一個選擇已經過期的所有的時間標記,並在毫秒排序,然後執行由項的詳細每個事件。

問題

目前後端完全用PHP編寫的Apache服務器上使用MySQL(即標準LAMP架構)。現在,我能想到的,以實現我指定什麼的唯一方式是編寫一個自定義的PHP作業隊列腳本,將做分析和執行,每循環使用第二this method。我沒有其他的工作系統可以根據指定的時間戳/毫秒而不是輸入時間對作業進行排隊。

然而,即使在紙上,這種方法聽起來也是不可行的CPU - 我必須每秒鐘執行一次巨大的MySQL查詢,併爲每個檢索行執行某種函數,並有可能運行超過一秒的執行時間將開始在解析時間中引入延遲並搞亂循環腳本。

我當然試圖創建一個解決方案,將可擴展應該有系統,此解決方案悲慘的失敗了,因爲它會繼續落後作爲條目的數量變大上交通繁忙。

的問題

我寧願堅持標準的LAMP架構,但沒有任何其他的技術,我可以很好地集成到能更好地處理一下,我試圖堆棧在這裏做?

是否有另一種方法來完全準確地在指定的未來日期的觸發事件沒有凌亂擺弄隨着不斷的隊列檢查?

如果沒有上述選項都適合,有沒有循環更好的方式在後臺PHP腳本?在最壞的情況下,我可以接受很長的執行時間,並在多個「工作人員」之間分配任務。

更新

的RabbitMQ是一個很好的建議,但不幸的是因爲它「到期」不盡快執行任務 - 它必須先通過一個隊列,等待了任何任務面前說尚未到期。到期時間的範圍在幾秒到幾天之間,並且每次添加新事件時都需要對隊列進行排序,因此到期時間總是在隊列中排序。就我在RabbitMQ中知道的情況而言,這是不可能的,而且聽起來也不是很有效。是否有替代或程序修復?

回答

0

有時,製作一個方形釘適合圓孔需要很多努力。儘管使用MySQL來創建隊列可能會很有效,但它的擴展變得非常棘手。我建議這可能是RabbitMQ的一個機會。

基本上,你會設置一個消息隊列,你可以把事件放進去。然後,您將有一個「扇出」架構,讓您的員工處理每個隊列。每個工作人員都會監聽隊列並檢查是否需要處理特定事件。我想像一下"Work Queues""Routing"技術的組合可以在可擴展和可靠的方式下實現你正在尋找的東西。

我想象的作品是這樣一個系統:

  1. 產卵工人聽隊列,使用路由鍵消減他們多少消息得到
  2. 每個工人檢查消息,看是否他們現在要執行
  3. 如果要執行消息,執行它並確認 - 否則,重新發送消息以供將來處理。有一些simple techniques可用於此。

隨着您需要更多規模,您需要添加更多工作人員。 RabbitMQ非常強大,並且當您最終限制隊列服務器時容易集羣。還有其他基於雲的排隊系統,如Iron.IOStormMQ

+1

我做了一些研究,RabbitMQ的,直到我碰到這次來到它看起來非常有前途:http://www.rabbitmq.com/ttl.html(注意事項) 。我需要設置每條消息的TTL來定義執行任務的時間,但正如我所提到的,它可能從幾秒到幾天不等。我需要在計時器到期時立即執行任務,但它看起來像rabbitMQ將等待隊列首先彈出。我需要一些方法對隊列進行排序,以便首先到期的任務位於隊列頭部,並按順序彈出。有針對這個的解決方法嗎? – user1334061

+0

可能不是,我試圖如何處理它:讓消息本身有執行時間。接收消息的作業可以立即確認,讀取時間,如果現在或過去,執行。如果是將來,請重新派遣同一時間,以便其他工作人員可以拿起它。我會讓所有工作人員在抓取和重新發送(1-100毫秒)之間睡眠一段時間,這樣您就不會忙於等待隊列服務器。 – Sam