3

我有大約100臺電腦,每個人都有幾個工作人員。已連接到中央數據庫以查詢作業參數。現在我不得不爲他們做工作安排。一名工作人員的一份工作需要幾分鐘時間,不需要網絡連接(除了處理工作和報告),並且可以隨時按任何順序完成。如何使用數據庫服務器進行分佈式作業調度?

約束:

  • 沒有工作將採取/做兩次
  • 會出現的情況下,工人死亡一timeeout。

我以爲我可以在數據庫中使用單獨的表來安排工作。 如何創建和訪問作業調度表?

回答

4

把它分解成塊:

你有一份工作描述 - 這可能會對它進行,其中一些制約因素 - 你有一個任務隊列來執行,從廣義上講,如果沒有其他的限制你會期望這些工作按順序完成,也就是說,你可以從隊列的前面拿到它們並將它們添加到最後。

如果我們運行隊列作爲一個單一的表,則作業將有3種狀態:

  • 未啓動
  • 在進步
  • 完成

所以找工作做的是隻需要找到第一份工作(或者如果批次中分配工作的前n份工作),然後將其標記爲開始。如果約束比前n個可用作業更復雜,那麼它成爲滿足約束條件的前n個可用作業,但它應該仍然相當簡單。

這意味着以下字段在隊列表:

  • 狀態
  • DateQueued(日期和時間)排序
  • DateStarted(日期和時間)的超時
  • AssignedTo

我們可能會添加一個DateCompleted - 但是如果工作是批處理,這不會是嚴格準確的(它會時間爲,報告爲)。

所以對於工人(工人 「APP」)的過程變爲:

  1. 連接到服務器
  2. 報告完成的工作 - 設置狀態和完成時間
  3. 申請新的工作
    1. 爲工作人員搜索新工作(前n個工作未啓動,工作人員可以執行)
    2. 將新工作分配給工作人員(設置狀態,啓動日期和分配到) - 搜索並分配爲交易。
  4. 名單的工作和斷開

另外你需要處理排隊的工作,尋找那些已經「超時」,這樣的狀態可以復位並存檔或以其他方式明確了工作從隊列中完成的工作。

完整的表格將包含以下內容以及所有需要的審覈字段。

  • ID
  • 作業ID - 假設工作在別處
  • 定義StatusID
  • DateQueued
  • DateStarted
  • AssignedToID
  • DateCompleted

希望幫助.. 。

+0

聽起來正確。 Bigg感謝你的工作。 最後一件事是如何編寫查詢來使適當的事情成爲原子? – 2009-11-14 13:55:57

+0

你必須在交易中包裝東西 - 完全取決於你使用的服務器和開發工具。 – Murph 2009-11-14 15:24:48

0

令人感興趣的部分和所有困難所在的部分是在交易中包裝事物。

您需要兩個表格:可用工作表和正在進行的表記錄工作。 「工作進行中」表對工作可用表具有唯一的外鍵。

希望首先完成工作的進程從要完成的工作表中查找一行。這應該使用隨機排序順序來完成,以減少爭用。

處理刪除「正在進行中」行。這並不意味着在交易之外堅持。它僅用於鎖定。

該過程然後開始一個事務。

該過程然後在「工作進行中」表中創建一行,外鍵引用正在完成的工作。它應該做這項工作。作爲這項工作的一部分,它應該改變正在處理的項目的狀態(例如,使其「完成」並且不再可用於工作)。

該過程提交其交易。

如果某個其他進程抓取了該工作,則該進程的事務將因嘗試向「正在進行中的工作」表提交重複的外鍵而失敗。在這種情況下,這個過程應該回退一段短暫的隨機時間間隔,然後回到起點,嘗試找到一些要做的工作。

小心地監視「工作進行中」表。某些數據庫或某些數據庫的某些版本不希望將此類進行中的工作表用作隊列,並且不斷創建和刪除行。特別是,較早版本的Postgresql難以清理舊的不再使用的行,從而導致表膨脹和性能下降。