Skapa aktivitetsberoenden för att köra aktiviteter som är beroende av andra aktiviteter

Med Batch-aktivitetsberoenden skapar du aktiviteter som är schemalagda för körning på beräkningsnoder när en eller flera överordnade aktiviteter har slutförts. Du kan till exempel skapa ett jobb som renderar varje bildruta i en 3D-film med separata, parallella uppgifter. Den sista uppgiften sammanfogar de återgivna bildrutorna till hela filmen först när alla bildrutor har renderats. Den slutliga aktiviteten är med andra ord beroende av de tidigare överordnade aktiviteterna.

Några scenarier där aktivitetsberoenden är användbara är:

  • MapReduce-arbetsbelastningar i molnet.
  • Jobb vars databehandlingsuppgifter kan uttryckas som en riktad acyklisk graf (DAG).
  • Processer för förrendering och efterrendering, där varje uppgift måste slutföras innan nästa uppgift kan börja.
  • Alla andra jobb där underordnade aktiviteter är beroende av utdata från överordnade aktiviteter.

Som standard schemaläggs beroende aktiviteter endast för körning när den överordnade aktiviteten har slutförts. Du kan också ange en beroendeåtgärd för att åsidosätta standardbeteendet och köra den beroende aktiviteten även om den överordnade aktiviteten misslyckas.

I den här artikeln diskuterar vi hur du konfigurerar aktivitetsberoenden med hjälp av Batch .NET-biblioteket . Vi visar först hur du aktiverar aktivitetsberoende för dina jobb och visar sedan hur du konfigurerar en uppgift med beroenden. Vi beskriver också hur du anger en beroendeåtgärd för att köra beroende aktiviteter om den överordnade åtgärden misslyckas. Slutligen diskuterar vi de beroendescenarier som Batch stöder.

Aktivera aktivitetsberoenden

Om du vill använda aktivitetsberoenden i Batch-programmet måste du först konfigurera jobbet så att det använder aktivitetsberoenden. I Batch .NET aktiverar du det på ditt CloudJob genom att ange egenskapen UsesTaskDependencies till true:

CloudJob unboundJob = batchClient.JobOperations.CreateJob( "job001",
    new PoolInformation { PoolId = "pool001" });

// IMPORTANT: This is REQUIRED for using task dependencies.
unboundJob.UsesTaskDependencies = true;

I föregående kodfragment är "batchClient" en instans av klassen BatchClient .

Skapa beroende uppgifter

Om du vill skapa en aktivitet som är beroende av slutförandet av en eller flera överordnade aktiviteter kan du ange att aktiviteten "är beroende av" de andra aktiviteterna. I Batch .NET konfigurerar du egenskapen CloudTask.DependsOn med en instans av klassen TaskDependencies :

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

Det här kodfragmentet skapar en beroende uppgift med aktivitets-ID:t "Flowers". Uppgiften "Blommor" beror på uppgifterna "Regn" och "Sol". Aktiviteten "Flowers" schemaläggs att köras på en beräkningsnod först efter att aktiviteterna "Rain" och "Sun" har slutförts.

Anteckning

Som standard anses en aktivitet ha slutförts när den är i slutfört tillstånd och dess slutkod är 0. I Batch .NET innebär det att ett CloudTask.State-egenskapsvärde är Completed och cloudtasks egenskapsvärde TaskExecutionInformation.ExitCode är 0. Information om hur du ändrar detta finns i avsnittet Beroendeåtgärder .

Beroendescenarier

Det finns tre grundläggande scenarier för aktivitetsberoenden som du kan använda i Azure Batch: ett-till-en-, en-till-många- och aktivitets-ID-intervallberoende. Dessa tre scenarier kan kombineras för att ge ett fjärde scenario: många-till-många.

Scenario Exempel Illustration
En-till-en taskB är beroende av att taskA

taskB inte schemaläggs för körning förrän taskA har slutförts

Diagram som visar beroendescenariot för en-till-en-uppgift.
En-till-många taskC är beroende av att både taskA och taskB

taskC inte schemaläggs för körning förrän både taskA och taskB har slutförts

Diagram som visar beroendescenariot för en-till-många-aktiviteter.
Aktivitets-ID-intervall taskD är beroende av att ett antal aktiviteter

som uppgiftSD inte schemaläggs för körning förrän aktiviteterna med ID 1 till 10 har slutförts

Diagram som visar beroendescenariot för aktivitets-ID-intervallet.

Tips

Du kan skapa många-till-många-relationer, till exempel var uppgifter C, D, E och F var och en är beroende av uppgifter A och B. Detta är användbart, till exempel i parallelliserade förbearbetningsscenarier där dina underordnade uppgifter är beroende av utdata från flera överordnade aktiviteter.

I exemplen i det här avsnittet körs en beroende aktivitet först när de överordnade aktiviteterna har slutförts. Det här beteendet är standardbeteendet för en beroende aktivitet. Du kan köra en beroende aktivitet när en överordnad aktivitet misslyckas genom att ange en beroendeåtgärd som åsidosätter standardbeteendet.

En-till-en

I en en-till-en-relation beror en aktivitet på att en överordnad aktivitet har slutförts. Om du vill skapa beroendet anger du ett enda aktivitets-ID till den statiska metoden TaskDependencies.OnId när du fyller i egenskapen CloudTask.DependsOn .

// Task 'taskA' doesn't depend on any other tasks
new CloudTask("taskA", "cmd.exe /c echo taskA"),

// Task 'taskB' depends on completion of task 'taskA'
new CloudTask("taskB", "cmd.exe /c echo taskB")
{
    DependsOn = TaskDependencies.OnId("taskA")
},

En-till-många

I en en-till-många-relation beror en aktivitet på slutförandet av flera överordnade aktiviteter. Om du vill skapa beroendet anger du en samling specifika aktivitets-ID:t till den statiska metoden TaskDependencies.OnIds när du fyller i egenskapen CloudTask.DependsOn .

// 'Rain' and 'Sun' don't depend on any other tasks
new CloudTask("Rain", "cmd.exe /c echo Rain"),
new CloudTask("Sun", "cmd.exe /c echo Sun"),

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

Viktigt

Det går inte att skapa beroende aktiviteter om den kombinerade längden på överordnad aktivitets-ID är större än 6 4000 tecken. Om du vill ange ett stort antal överordnade aktiviteter bör du överväga att använda ett aktivitets-ID-intervall i stället.

Aktivitets-ID-intervall

I ett beroende av ett intervall av överordnade aktiviteter beror en aktivitet på slutförandet av aktiviteter vars ID ligger inom ett intervall som du anger.

Om du vill skapa beroendet anger du det första och sista aktivitets-ID:t i intervallet till den statiska metoden TaskDependencies.OnIdRange när du fyller i egenskapen CloudTask.DependsOn .

Viktigt

När du använder aktivitets-ID-intervall för dina beroenden väljs endast uppgifter med ID:er som representerar heltalsvärden av intervallet. Till exempel väljer intervallet 1..10 uppgifter 3 och 7, men inte 5flamingoes.

Inledande nollor är inte signifikanta när du utvärderar intervallberoenden, så aktiviteter med strängidentifierare 404 , och 004 kommer alla att ligga inom intervallet, eftersom alla behandlas som uppgift 4, kommer den första som ska slutföras att uppfylla beroendet.

För att den beroende aktiviteten ska kunna köras måste varje aktivitet i intervallet uppfylla beroendet, antingen genom att slutföras eller genom att slutföras med ett fel som mappas till en beroendeåtgärd inställd på Uppfyller.

// 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 CloudTask("1", "cmd.exe /c echo 1"),
new CloudTask("2", "cmd.exe /c echo 2"),
new CloudTask("3", "cmd.exe /c echo 3"),

// Task 4 depends on a range of tasks, 1 through 3
new CloudTask("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 TaskIdRange,
    // but their ids (above) are string representations of the ids.
    DependsOn = TaskDependencies.OnIdRange(1, 3)
},

Beroendeåtgärder

Som standard körs en beroende aktivitet eller uppsättning aktiviteter endast när en överordnad aktivitet har slutförts. I vissa fall kanske du vill köra beroende aktiviteter även om den överordnade aktiviteten misslyckas. Du kan åsidosätta standardbeteendet genom att ange en beroendeåtgärd som anger om en beroende aktivitet är berättigad att köras.

Anta till exempel att en beroende aktivitet väntar på data från slutförandet av den överordnade aktiviteten. Om den överordnade aktiviteten misslyckas kan den beroende aktiviteten fortfarande köras med äldre data. I det här fallet kan en beroendeåtgärd ange att den beroende aktiviteten är berättigad att köras trots att den överordnade aktiviteten misslyckades.

En beroendeåtgärd baseras på ett avslutsvillkor för den överordnade aktiviteten. Du kan ange en beroendeåtgärd för något av följande avslutsvillkor:

  • När ett förbearbetningsfel inträffar.
  • När ett filuppladdningsfel inträffar. Om uppgiften avslutas med en slutkod som har angetts via exitCodes eller exitCodeRanges och sedan påträffar ett filuppladdningsfel har åtgärden som anges av slutkoden företräde.
  • När uppgiften avslutas med en slutkod som definierats av egenskapen ExitCodes .
  • När uppgiften avslutas med en slutkod som ligger inom ett intervall som anges av egenskapen ExitCodeRanges .
  • Standardfallet om aktiviteten avslutas med en slutkod som inte definierats av ExitCodes eller ExitCodeRanges, eller om aktiviteten avslutas med ett förbearbetningsfel och egenskapen PreProcessingError inte har angetts, eller om aktiviteten misslyckas med ett filuppladdningsfel och egenskapen FileUploadError inte har angetts.

För .NET definieras dessa villkor som egenskaper för klassen ExitConditions .

Om du vill ange en beroendeåtgärd anger du egenskapen ExitOptions.DependencyAction för avslutsvillkoret till något av följande:

  • Uppfyller: Anger att beroende aktiviteter är berättigade att köras om den överordnade aktiviteten avslutas med ett angivet fel.
  • Blockera: Anger att beroende aktiviteter inte är berättigade att köras.

Standardinställningen för egenskapen DependencyAction är Uppfyller för slutkod 0 och Blockera för alla andra avslutsvillkor.

Följande kodfragment anger egenskapen DependencyAction för en överordnad aktivitet. Om den överordnade aktiviteten avslutas med ett förbearbetningsfel eller med de angivna felkoderna blockeras den beroende aktiviteten. Om den överordnade aktiviteten avslutas med ett annat fel som inte är noll är den beroende aktiviteten berättigad att köras.

// Task A is the parent task.
new CloudTask("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 List<ExitCodeMapping>
        {
            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).
        Default = new ExitOptions
        {
            DependencyAction = DependencyAction.Satisfy
        }
    }
},
// Task B depends on task A. Whether it becomes eligible to run depends on how task A exits.
new CloudTask("B", "cmd.exe /c echo B")
{
    DependsOn = TaskDependencies.OnId("A")
},

Kodexempel

Exempelprojektet TaskDependencies på GitHub visar:

  • Så här aktiverar du aktivitetsberoende för ett jobb.
  • Så här skapar du uppgifter som är beroende av andra aktiviteter.
  • Så här kör du dessa uppgifter i en pool med beräkningsnoder.

Nästa steg