建立工作相依性,以便執行相依於其他工作的工作

您可以利用 Batch 工作相依性,建立排定於一或多項父系工作完成後,才在計算節點上執行的工作。 例如,您可以建立一個將 3D 電影的每個影格以個別、平行工作轉譯的工作。 在所有影像圖檔順利完成算圖後,系統才會觸發最後的合併工作,將這些影像圖檔合併成完整影片。 換句話說,最終工作相依於先前的父系工作。

一些實用的工作相依性案例包括︰

  • 雲端中的 MapReduce 樣式工作負載。
  • 資料處理工作可表示為有向非循環圖 (DAG) 的工作。
  • 預先呈現和後處理過程,其中每項任務必須完成後,才能開始下一項任務。
  • 下游工作相依於上游工作輸出的任何其他工作。

根據預設,相依工作會排定只會在父系工作順利完成之後執行。 您可以選擇是否指定相依性動作,以覆寫預設行為,並在父系工作失敗時執行相依工作。

本文說明如何利用 Batch .NET 函式庫來配置任務相依關係。 本文說明如何在作業上啟用任務相依性、如何設定具有相依性的任務,以及如何指定相依性動作,以便在父任務失敗時執行相依任務。 它也描述了批次支援的 相依情境 。

啟用工作相依性

若要在 Batch 應用程式中使用工作相依性,您必須先將作業設定成使用工作相依性。 在 Batch .NET 中,請在你的 BatchJobCreateOptions 上啟用此功能,方法是將其 UsesTaskDependencies 屬性設定為 true:

BatchJobCreateOptions unboundJob = new BatchJobCreateOptions("job001", new BatchPoolInfo() { PoolId = "pool001" })
{
    // IMPORTANT: This is REQUIRED for using task dependencies.
    UsesTaskDependencies = true
};
await batchClient.CreateJobAsync(unboundJob);

在上述程式碼片段中,"batchClient" 是 BatchClient 類別的執行個體。

建立相依的工作

若要建立相依於一或多個父系工作完成的工作,您可以指定此工作「相依於」其他工作。 在批次.NET中,設定 BatchTaskCreateOptions.DependsOn 屬性,並設定 BatchTaskDependencies 類別的實例:

// Task 'Flowers' depends on completion of both 'Rain' and 'Sun'
// before it is run.
BatchTaskCreateOptions flowers = new BatchTaskCreateOptions("Flowers", "cmd.exe /c echo Flowers")
{
    DependsOn = new BatchTaskDependencies()
    {
        TaskIds = { "Rain", "Sun" }
    }
};

此程式碼片段會使用工作識別碼 "Flowers" 建立相依工作。 "Flowers" 工作相依於 "Rain" 和 "Sun" 工作。 只有在「雨」和「太陽」任務順利完成之後,任務「花」才會排程在計算節點上執行。

附註

根據預設,當工作處於已完成狀態且其結束代碼是 0 時,才會將其視為已順利完成。 在批次.NET中,這表示 BatchTask.State屬性值為 Completed,而 batchTask 的 BatchTaskExecutionInfo.ExitCode屬性值為 0。 若要深入了解變更方式,請參閱相依性動作一節。

相依性案例

Azure Batch 中可使用的基本工作相依性案例有三種︰一對一、一對多、工作識別碼範圍相依性。 結合這三種案例即可提供第四種案例:多對多。

狀況 範例 圖例
一對一 taskB 相依於 taskA

taskB 要等到 taskA 順利完成後,才會排定執行

圖例顯示一對一工作相依性案例。
一對多 taskC 相依於 taskA 和 taskB

taskC ,在 taskA 和 taskB 都順利完成之前,將不會排程執行 taskC

圖例顯示一對多工作相依性案例。
工作識別碼範圍 taskD 依賴一些任務

taskD 不會被安排執行,直到標識符為 1 到 10 的任務成功完成。

圖例顯示工作識別碼範圍工作相依性案例。

秘訣

您可以建立 多對多 關聯性,例如工作 C、D、E 和 F 各自相依於工作 A 和 B。例如,在平行處理的前置處理案例中,您的下游工作相依於多個上游工作的輸出,這非常有用。

在本節的範例中,相依工作只會在父系工作順利完成之後才執行。 這是相依工作的默認行為。 指定相依性動作來覆寫預設行為,即可在父系工作失敗時執行相依工作。

一對一

在一對一關聯性中,工作相依於一項父系工作的成功完成。 要建立相依關係,請在填寫 BatchTaskCreateOptions.DependsOn 屬性時,將 BatchTaskDependencies.TaskIds 設為單一任務 ID。

IList<BatchTaskCreateOptions> tasks = new List<BatchTaskCreateOptions>
{
    // Task 'taskA' doesn't depend on any other tasks
    new BatchTaskCreateOptions("taskA", "cmd.exe /c echo taskA"),

    // Task 'taskB' depends on completion of task 'taskA'
    new BatchTaskCreateOptions("taskB", "cmd.exe /c echo taskB")
    {
        DependsOn = new BatchTaskDependencies() { TaskIds = { "taskA" } }
    },
};

一對多

在一對多關聯性中,工作相依於多項父工作的完成。 要建立相依關係,請在填充 BatchTaskCreateOptions.DependsOn 屬性時,將父任務 ID 填入 BatchTaskDependencies.TaskIds。

IList<BatchTaskCreateOptions> tasks = new List<BatchTaskCreateOptions>
{
    // 'Rain' and 'Sun' don't depend on any other tasks
    new BatchTaskCreateOptions("Rain", "cmd.exe /c echo Rain"),
    new BatchTaskCreateOptions("Sun", "cmd.exe /c echo Sun"),

    // Task 'Flowers' depends on completion of both 'Rain' and 'Sun'
    // before it is run.
    new BatchTaskCreateOptions("Flowers", "cmd.exe /c echo Flowers")
    {
        DependsOn = new BatchTaskDependencies() { TaskIds = { "Rain", "Sun" } }
    },
};

重要事項

如果父系工作識別碼的合併長度大於 64000 個字元,則您的相依工作建立會失敗。 若要指定大量的父系工作,請考慮改用工作識別碼範圍。

工作識別碼範圍

在父系工作範圍的相依性中,工作相依於識別碼落在指定範圍內的工作完成。

要建立相依關係,請在填充 BatchTaskCreateOptions.DependsOn 屬性時,將 BatchTaskDependencies.TaskIdRange 填入 BatchTaskIdRange。

重要事項

當您使用工作 ID 範圍來設定依存性時,範圍只會選取具有代表整數值之 ID 的工作。 例如,範圍 1..10 會選取 3 和 7 工作,但不會選取 5flamingoes。

評估範圍相依性時,前置零並不重要,因此具有字串標識碼 4、 04和 004的工作都在範圍內 ,因為它們全都視為工作 4,所以第一個完成的工作符合相依性。

對於要執行的相依工作,範圍中的每項工作必須藉由下列方式來符合相依性:順利完成,或完成但對應至相依性動作的錯誤設定為 [符合]。

IList<BatchTaskCreateOptions> tasks = new List<BatchTaskCreateOptions>
{
    // Tasks 1, 2, and 3 don't depend on any other tasks. Because
    // we will be using them for a task range dependency, we must
    // specify string representations of integers as their ids.
    new BatchTaskCreateOptions("1", "cmd.exe /c echo 1"),
    new BatchTaskCreateOptions("2", "cmd.exe /c echo 2"),
    new BatchTaskCreateOptions("3", "cmd.exe /c echo 3"),

    // Task 4 depends on a range of tasks, 1 through 3
    new BatchTaskCreateOptions("4", "cmd.exe /c echo 4")
    {
        // To use a range of tasks, their ids must be integer values.
        // Note that we pass integers as parameters to BatchTaskIdRange,
        // but their ids (above) are string representations of the ids.
        DependsOn = new BatchTaskDependencies()
        {
            TaskIdRanges = { new BatchTaskIdRange(1, 3) }
        }
    },
};

相依性動作

根據預設,相依工作或一組工作只會在父工作順利完成之後執行。 在某些情況下,即使父系工作失敗,您也想要執行相依工作。 您可以藉由指定相依性動作來覆寫預設行為,以指出相依工作是否符合執行資格。

例如,假設相依工作正在等候上游工作完成的資料。 如果上游工作失敗,相依工作仍然可以使用較舊的資料來執行。 在此情況下,儘管父系工作失敗,相依性動作仍可指定相依工作是否有資格執行。

相依性動作是以父系工作的結束情況為基礎。 您可以針對下列任一個結束條件指定相依性動作:

  • 每當發生前置處理錯誤時。
  • 每當發生檔案上傳錯誤時。 如果工作結束時的結束代碼是透過 exitCodes 或 exitCodeRanges 所指定,又發生檔案上傳錯誤,則優先執行結束代碼指定的動作。
  • 每當工作以 ExitCodes 屬性所定義的結束代碼結束時。
  • 每當工作結束時,結束代碼會落在 ExitCodeRanges 屬性所指定的範圍內。
  • 如果工作以 ExitCodes 或 ExitCodeRanges 未定義的結束代碼結束,或者工作結束時出現前置處理錯誤且未設定 PreProcessingError 屬性,或工作失敗且檔案上傳錯誤且未設定 FileUploadError 屬性,則為預設案例。

針對 .NET,這些條件會定義為 ExitConditions 類別的屬性。

若要指定相依性動作,請將結束條件的 ExitOptions.DependencyAction 屬性設定為下列其中一個選項:

  • 符合:表示如果父系工作結束時出現指定的錯誤,相依工作就有資格執行。
  • 封鎖:表示相依工作不符合執行資格。

結束代碼 0 的DependencyAction 屬性預設設定為 [符合],而所有其他結束情況的預設設定則為 [封鎖]。

下列程式碼片段可設定父系工作的 DependencyAction 屬性。 如果父工作結束並出現前置處理錯誤或具有指定的錯誤碼,則會封鎖相依工作。 如果父系工作因任何其他非零錯誤而結束,則相依工作就有資格執行。

IList<BatchTaskCreateOptions> tasks = new List<BatchTaskCreateOptions>
{
    // Task A is the parent task.
    new BatchTaskCreateOptions("A", "cmd.exe /c echo A")
    {
        // Specify exit conditions for task A and their dependency actions.
        ExitConditions = new ExitConditions()
        {
            // If task A exits with a pre-processing error, block any downstream tasks (in this example, task B).
            PreProcessingError = new ExitOptions()
            {
                DependencyAction = DependencyAction.Block
            },
            // If task A exits with the specified error codes, block any downstream tasks (in this example, task B).
            ExitCodes =
            {
                new ExitCodeMapping(10, new ExitOptions() { DependencyAction = DependencyAction.Block }),
                new ExitCodeMapping(20, new ExitOptions() { DependencyAction = DependencyAction.Block })
            },
            // If task A succeeds or fails with any other error, any downstream tasks become eligible to run
            // (in this example, task B).
            DefaultExitOptions = new ExitOptions()
            {
                DependencyAction = DependencyAction.Satisfy
            }
        }
    },
    // Task B depends on task A. Whether it becomes eligible to run depends on how task A exits.
    new BatchTaskCreateOptions("B", "cmd.exe /c echo B")
    {
        DependsOn = new BatchTaskDependencies() { TaskIds = { "A" } }
    },
};

程式碼範例

GitHub 上的 TaskDependencies 範例專案示範:

  • 如何啟用作業的工作相依性。
  • 如何建立相依於其他工作的工作。
  • 如何在運算節點集區上執行這些工作。

後續步驟