Sdílet prostřednictvím


Vytvoření závislostí úkolů pro spouštění úloh, které závisí na jiných úkolech

Pomocí závislostí úkolů služby Batch vytvoříte úkoly, které jsou naplánované pro provádění na výpočetních uzlech po dokončení jednoho nebo více nadřazených úkolů. Můžete například vytvořit úlohu, která vykreslí každý rámec 3D filmu s samostatnými paralelními úkoly. Poslední úloha sloučí vykreslované snímky do celého videa až po úspěšném vykreslení všech snímků. Jinými slovy, konečný úkol je závislý na předchozích nadřazených úkolech.

Mezi scénáře, ve kterých jsou závislosti úkolů užitečné, patří:

  • Úlohy ve stylu MapReduce v cloudu
  • Úlohy, jejichž úlohy zpracování dat lze vyjádřit jako směrovaný acyklický graf (DAG).
  • Předkreslovací a pozkreslovací procesy, kdy musí být každý úkol dokončen před zahájením dalšího úkolu.
  • Jakákoli jiná úloha, ve které podřízené úkoly závisí na výstupu nadřazených úkolů.

Ve výchozím nastavení jsou závislé úkoly naplánované na spuštění až po úspěšném dokončení nadřazeného úkolu. Volitelně můžete zadat akci závislosti, která přepíše výchozí chování a spustí závislý úkol, i když nadřazený úkol selže.

V tomto článku probereme, jak nakonfigurovat závislosti úkolů pomocí knihovny Batch .NET . Nejprve vám ukážeme, jak povolit závislost úkolů na vašich úlohách, a pak předvedeme, jak nakonfigurovat úkol se závislostmi. Popisujeme také, jak určit akci závislosti pro spuštění závislých úloh v případě selhání nadřazeného objektu. Nakonec probereme scénáře závislostí, které Služba Batch podporuje.

Povolení závislostí úkolů

Pokud chcete použít závislosti úkolů v aplikaci Batch, musíte nejprve nakonfigurovat úlohu tak, aby používala závislosti úkolů. Ve službě Batch .NET ji povolte ve své službě CloudJob nastavením vlastnosti UsesTaskDependencies na true:

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

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

V předchozím fragmentu kódu je batchClient instancí třídy BatchClient .

Vytváření závislých úkolů

Pokud chcete vytvořit úkol, který závisí na dokončení jednoho nebo více nadřazených úkolů, můžete určit, že úkol "závisí na" ostatních úkolech. Ve službě Batch .NET nakonfigurujte vlastnost CloudTask.DependsOn s instancí Třídy 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")
},

Tento fragment kódu vytvoří závislý úkol s ID úkolu "Květiny". Úkol "Květiny" závisí na úkolech "Déšť" a "Slunce". Úkol "Květiny" se naplánuje tak, aby běžel na výpočetním uzlu až po úspěšném dokončení úkolů Rain a Sun.

Poznámka:

Ve výchozím nastavení se úkol považuje za úspěšně dokončený, pokud je v dokončeném stavu a jeho ukončovací kód je 0. Ve službě Batch .NET to znamená, že hodnota vlastnosti CloudTask.State je Completed a hodnota vlastnosti TaskExecutionInformation.ExitCode v CloudTask je 0. Informace o tom, jak to změnit, najdete v části Akce závislostí.

Scénáře závislostí

Ve službě Azure Batch můžete použít tři základní scénáře závislostí úkolů: 1:1, 1:N a závislost rozsahu ID úlohy. Tyto tři scénáře je možné kombinovat a poskytnout čtvrtý scénář: M:N.

Scénář Příklad Ilustrace
Vzájemný ÚkolB závisí na úkolu A

úkoluB nebude naplánovaný na provádění, dokud úkolA úspěšně nedokončí.

Diagram znázorňující scénář závislosti mezi 1:1
Vztah jednoho k několika jiným ÚkolC závisí na úkolu A i úkoluB

– úkolC nebudou naplánované na provádění, dokud se úkol A i úkolB úspěšně nedokončí.

Diagram znázorňující scénář závislostí mezi 1:N
Rozsah ID úkolu ÚkolD závisí na rozsahu úkolů

, které se neplánují pro provádění, dokud se úkoly s ID 110 úspěšně nedokončí.

Diagram znázorňující scénář závislostí rozsahu ID úlohy

Tip

Můžete vytvořit relace M:N , například kde úkoly C, D, E a F závisí na úkolech A a B. To je užitečné například v paralelizovaných scénářích předběžného zpracování, ve kterých podřízené úkoly závisejí na výstupu více nadřazených úloh.

V příkladech v této části se závislý úkol spustí až po úspěšném dokončení nadřazených úkolů. Toto chování je výchozím chováním závislého úkolu. Závislý úkol můžete spustit po selhání nadřazeného úkolu zadáním akce závislosti, která přepíše výchozí chování.

Vzájemný

V relaci 1:1 závisí úkol na úspěšném dokončení jednoho nadřazeného úkolu. Chcete-li vytvořit závislost, zadejte jedno ID úlohy TaskDependencies.OnId static metoda při naplnění CloudTask.DependsOn vlastnost.

// 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")
},

1:N

V relaci 1:N závisí úkol na dokončení více nadřazených úkolů. Chcete-li vytvořit závislost, zadejte kolekci konkrétních ID úloh pro statickou metodu TaskDependencies.OnIds při naplnění Vlastnosti 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")
},

Důležité

Vytvoření závislého úkolu selže, pokud je kombinovaná délka ID nadřazených úkolů větší než 64 000 znaků. Pokud chcete zadat velký počet nadřazených úkolů, zvažte místo toho použití rozsahu ID úkolu.

Rozsah ID úkolu

V závislosti na rozsahu nadřazených úkolů závisí úkol na dokončení úkolů, jejichž ID leží v zadaném rozsahu.

Chcete-li vytvořit závislost, zadejte ID první a poslední úlohy v rozsahu na TaskDependencies.OnIdRange statická metoda při naplnění CloudTask.DependsOn vlastnost.

Důležité

Při použití rozsahů ID úkolů pro závislosti budou podle rozsahu vybrány pouze úkoly s ID představujícími celočíselné hodnoty. Oblast například 1..10 vybere úkoly 3 , 7ale ne 5flamingoes.

Počáteční nuly nejsou při vyhodnocování závislostí rozsahu významné, takže úkoly s řetězcovými identifikátory 404 a 004 všechny budou v rozsahu, protože všechny budou považovány za úkol 4, první, který se dokončí, splní závislost.

Aby se závislý úkol spustil, musí každý úkol v rozsahu závislosti splňovat buď úspěšné dokončení, nebo dokončením selhání, které je namapováno na akci závislostí nastavenou na Možnost Uspokojovat.

// 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)
},

Akce závislostí

Ve výchozím nastavení se závislý úkol nebo sada úkolů spustí až po úspěšném dokončení nadřazeného úkolu. V některých scénářích můžete chtít spustit závislé úlohy i v případě, že nadřazený úkol selže. Výchozí chování můžete přepsat zadáním akce závislosti, která určuje, jestli má závislý úkol nárok na spuštění.

Předpokládejme například, že závislý úkol čeká na data od dokončení nadřazeného úkolu. Pokud nadřazený úkol selže, může být závislý úkol stále schopen spustit pomocí starších dat. V tomto případě může akce závislosti určit, že závislý úkol může běžet i přes selhání nadřazené úlohy.

Akce závislosti je založena na výstupní podmínce nadřazené úlohy. Můžete zadat akci závislosti pro některou z následujících podmínek ukončení:

  • Pokud dojde k chybě předběžného zpracování.
  • Když dojde k chybě nahrání souboru. Pokud se úloha ukončí s ukončovacím kódem zadaným prostřednictvím exitCodes nebo exitCodeRanges a pak dojde k chybě nahrání souboru, má přednost akce určená ukončovacím kódem.
  • Když úloha ukončí ukončovací kód definovaný vlastností ExitCodes .
  • Když úloha ukončí ukončovací kód, který spadá do rozsahu určeného ExitCodeRanges vlastnost.
  • Výchozí případ, pokud úloha ukončí ukončovací kód, který není definován exitCodes nebo ExitCodeRanges, nebo pokud úloha skončí s chybou předběžného zpracování a PreProcessingError vlastnost není nastavena nebo pokud úloha selže s chybou nahrání souboru a vlastnost FileUploadError není nastavena.

Pro .NET jsou tyto podmínky definovány jako vlastnosti ExitConditions třídy.

Chcete-li zadat akci závislosti, nastavte vlastnost ExitOptions.DependencyAction pro podmínku ukončení na jednu z následujících možností:

  • Splněno: Označuje, že závislé úkoly mají nárok na spuštění, pokud nadřazený úkol skončí se zadanou chybou.
  • Blok: Označuje, že závislé úlohy nemají nárok na spuštění.

Výchozí nastavení vlastnosti DependencyAction je Satisfy for exit code 0 a Block for all other exit conditions.

Následující fragment kódu nastaví vlastnost DependencyAction pro nadřazenou úlohu. Pokud nadřazený úkol ukončí chybu předběžného zpracování nebo se zadanými kódy chyb, zablokuje se závislý úkol. Pokud nadřazený úkol ukončí jinou nenulovou chybu, je závislý úkol způsobilý ke spuštění.

// 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")
},

Ukázka kódu

Ukázkový projekt TaskDependencies na GitHubu ukazuje:

  • Jak povolit závislost úkolů na úloze
  • Jak vytvořit úkoly, které závisejí na jiných úkolech.
  • Jak tyto úlohy spouštět ve fondu výpočetních uzlů

Další kroky