2007年12月16日 星期日

GridGain 程式開發(3) - Grid Tasks & Grid Jobs

了解 Grid Task 與 Grid Jobs 之間資訊(session、attribute、checkpoint)的交換方式與種類介紹後,接下來這個部分也是 GridGain 程式運作的基礎:GridTask & GridJob

以下就分成幾個部分來說明這兩個概念:

GridTask & GridJob Interfaces

由於分散式運算所需注意的地方很多,因此 GridGain 將應該要有的功能清楚的定義在 GridTaskGridJob 兩個 interface 中,讓使用者可以知道如何建立一個 Grid Task,然後對其進行後續的操作。

第一篇提到,Grid Task 即是使用者送出的工作,而 GridGain 在 GridTask interface 中定義了幾個功能,分別是:
  1. 將使用者派送的工作,根據自訂的規則拆成(split)多個 Grid Job

  2. 接收 remote grid node 處理 Grid Job 的結果

  3. 將所有的處理結果進行彙整(reduce)

而若要建立 Grid Task,必須實作 GridTask interface,其中當 GridTask.map(List, T) method 被呼叫時,就可以取得由該 Grid Task 所拆開的 Grid Jobs 的資訊(會被派送到那個 grid node 去執行的相關訊息),再由 GridGain 將 Grid Job 序列化(serialize)傳送至 remote grid node 執行。


Grid Task Execution Sequence

這個部分要說明 Grid Task 執行的步驟細節:
  1. 接收到 grid task 的執行要求,並根據使用者給定的名稱,準備開始將 grid task 部署到 Grid 上。

  2. Grid 將會產生與此 grid task 相對應的 session 資訊。

  3. Grid 會根據使用者在程式中所加入的 annotation,注入(inject)所需要的 resource 到 grid task instance 上。

  4. 接著 Grid 會呼叫 GridTask.map(List, T) method,將 Grid Task 拆成多個 Grid Jobs 之後,再取得 Grid Job 與 remote grid node 對應的相關執行時的資訊。

  5. 有了 Grid Job 與 remote grid node 的對應資訊後,就可以開始將 job 丟到 remote grid node 上去執行。

  6. 當 job 傳到 node 準備執行前,會根據使用者在 GridCollisionSpi SPI 中所設定的方式進行處理,有可能會有以下三項:
    • WAIT:job 會進入 waiting list,等待有新 job 到達或是先前 job 已經處理完後,才會被移到 active list 中開始執行(此時 Collision SPI 會被呼叫,job 才會有所動作)。
    • EXECUTE:job 會直接被移到 active list 中執行。
    • REJECT:如果目前 active list 中有 job 正在執行,則此 job 會被拒絕執行;此時會將包含有 GridExecutionRejectedException 例外的 GridJobResult instance 傳入 GridTask.result(GridJobResult, List<GridJobResult>) 作為參數。

  7. 對於位於 node active list 中的 job,Grid 會將使用者指定的所有 annotation resource 注入(inject)到 Grid Job instance 中。

  8. remote grid node 會執行使用者在 GridJob.execute() 中所實作的工作。

  9. 當 job 在遠端執行完成後,會將結果回傳至 Grid Task,並傳入 GridTask.result(GridJobResult, List<GridJobResult>) 作為參數;若執行期間有例外產生,在可檢查到的例外發生情況下,可透過 GridJobResult.getException() 取得例外資訊;若無法檢查到的例外,會被統一包裝為 GridUserUndeclaredException 例外。

  10. 每個 job 執行完都會呼叫一次 GridTask.result(GridJobResult, List<GridJobResult>) method,此 method 會回傳 GridJobResultPolicy instance,而 Grid 會根據所回傳的 policy instance 來決定後續的 job 的處理方式,可以有以下三種作法:
    • GridJobResultPolicy.WAIT:Grid Task 會持續等待其他工作的完成,直到最後一個工作完成後,會呼叫 GridTask.reduce(List) method 將結果彙整。
    • GridJobResultPolicy.REDUCE:當收到的 policy 為 REDUCE,則會馬上呼叫 GridTask.reduce(List) method 進行結果的彙整,而其他未完成的 job 則會收到 cancel 的命令。
    • GridJobResultPolicy.FAILOVER:job 在執行中若是發生錯誤時,就會收到 FAILOVER policy;此時會根據使用者在 GridFailoverSpi 中的實作來決定要將 job 傳到何處繼續執行(若使用的是 Grid Task Adapter,則在發生 node crash 或是 job rejection 時,就會自動將 job 派送到其他 node 繼續執行)。

  11. 當所有 job 都處理完,也都收到回傳結果後,就會呼叫 GridTask.reduce(List) method 將結果彙整。

  12. 最後 Grid 會將相關的 session resource 全部清除,包含 attribute、checkpoint .... 等等,此時表示 Grid Task 正式執行完畢。

還有一點需要注意的! 當 job 在 remote grid node 執行到一半時收到中斷執行(cancel)的命令時,GridJob.cancel() method 就會被呼叫;使用者可以在此 method 進行實作,可以決定讓 job 忽略中斷繼續執行、直接中斷,或是進行其他不同的工作 .... 等等。

而通常 job 會再執行到一半被中斷的原因,有可能會有以下幾種:
  • Collision SPI 中斷了正在執行的 job。

  • Grid Task 已經執行完畢,而不需要再繼續等待其他 job 執行回傳的結果。

  • 使用者呼叫了 GridTaskFuture.cancel() method 停止整個 Grid Task 繼續執行。


Resource Injection

在 GridTask 與 GridJob 之間訊息的傳遞,或是控制資訊的交換,在 GridGain 中通稱為 Grid Resource。

而 GridGain 使用 IoC(Inverse of Control) 的方式,讓使用者可以透過 annotation 的方式將 resource 注入(inject),而 annotation 可以用在 field 上,也可以用在 method 上喔!!

以下介紹幾個常用的 Grid Resource:

Grid Resource
描述
GridTaskSessionResource 此即為上一篇所提到的 Distributed Grid Task Session(可以根據需求自訂 resource 為 primitive type 或是 object)
GridInstanceResource
正在執行的 task 所屬的 Grid instance
GridLoggerResource
GridLogger instance,而此 Logger instance 將會被 Grid instance 所使用
GridHomeResource
GridGain 安裝目錄的資訊
GridExecutorServiceResource
java.util.concurrent.ExecutorService instance (供 Grid 所使用)
GridLocalNodeIdResource
本地端 Grid Node ID,型態為 java.util.UUID
GridMBeanServerResource
javax.management.MBeanServer instance (供 Grid 所使用)
GridJobIdResource
代表 Grid Job 的唯一 ID 值,型態為 java.util.UUID

在 GridGain 中定義的 Grid Resource 一共就是以上這八種,詳細的使用方式可以參考官方網站的說明。


Convenience Adapters

之前介紹的 Grid Task、Grid Job、Grid Resource .... 等等不同的部分,要瞭解這些部分才能順利的開發程式,其實有蠻多細節是必須要注意的! 實際學習上也不是這麼容易!

因此 GrinGain 中提供了幾個 adapter,可以讓使用者在程式開發上更容易上手喔!!

以下來介紹這些 adapter:

Adapter
描述
GridTaskAdapter
GridTaskAdapter 提供了預設的 GridTask.result(GridJobResult, List<GridJobResult>) 實作,當 remote grid node 在執行工作時發生 node crash(拋出 GridTopologyException 例外) 或是 job 被拒絕執行(拋出 GridExecutionRejectException 例外)時,會自動處理 Job Failover 的工作。
GridTaskSplitAdapter
GridTaskAdapter 提供了讓使用者透過自行實作 GridTaskSplitAdapter.split(int, T) method 的方式,讓使用者可以根據需求決定要如何將 Grid Task 拆成 Grid Jobs,隱藏了 job 與 node 的配對相關資訊,讓整個工作更為簡化。
GridJobAdapter
GridJobAdapter 提供了預設沒有實作內容的 GridJob.cancel(),因此若無此需求,使用者可以不用再實作此 method;並允許使用者根據需求取得或設定 job 的參數。

GridGain 提供的 Adapter 不只以上這三種,若想要更瞭解 Adapter 的相關細節,可以參考官方網站的文件


Distributed Session Attributes and Checkpoints

這個部分其實在上一篇都有說明到了! 重點再說明一次:

在 Session Attributes 的部分,藉由設定 session attributes 的方式可以讓 Grid Task 與 Grid Jobs 之間,或是 Grid Sibling Jobs 之間作溝通。
有了這個機制之後,工作較快執行結束的 node,可以根據 session attributes 的值,等待其他 node 將工作處理完畢,因此可以達到一定程度的工作執行流程控制。

另外在 Checkpoints 的部分,則是持續不斷的儲存 job 的執行期間的相關資訊,以便錯誤發生時,可以將此 job failover 到其他的 node 繼續執行,而不需要全部從頭開始。
而這個功能,對於長時間執行的工作來說,是特別的重要的!

沒有留言:

張貼留言