Souběžné spouštění úloh za účelem maximalizace využití výpočetních uzlů služby Batch

Využití prostředků na menším počtu výpočetních uzlů ve fondu můžete maximalizovat tím, že na každém uzlu současně spustíte více než jednu úlohu.

I když některé scénáře fungují nejlépe se všemi prostředky uzlu vyhrazenými pro jeden úkol, u některých úloh může dojít k kratším časům úloh a nižším nákladům, když tyto prostředky sdílí více úkolů. Zvažte následující scénáře:

  • Minimalizujte přenos dat pro úlohy, které můžou sdílet data. Poplatky za přenos dat můžete výrazně snížit zkopírováním sdílených dat do menšího počtu uzlů a následným prováděním úloh paralelně na každém uzlu. Tato strategie platí zejména v případě, že data, která se mají zkopírovat do jednotlivých uzlů, musí být přenášena mezi geografickými oblastmi.
  • Maximalizujte využití paměti pro úlohy, které vyžadují velké množství paměti, ale pouze v krátkých časových obdobích a v proměnlivých časech během provádění. Pokud chcete tyto špičky efektivně zvládnout, můžete využít méně, ale větší výpočetních uzlů s větší pamětí. Tyto uzly mají několik úloh spuštěných paralelně na každém uzlu, ale každý úkol může využívat bohatou paměť uzlů v různých časech.
  • Zmírnění omezení počtu uzlů v případě, že se vyžaduje komunikace mezi uzly v rámci fondu. V současné době jsou fondy nakonfigurované pro komunikaci mezi uzly omezené na 50 výpočetních uzlů. Pokud je každý uzel v takovém fondu schopen spouštět úkoly paralelně, může se současně spouštět větší počet úkolů.
  • Replikace místního výpočetního clusteru, například při prvním přesunu výpočetního prostředí do Azure Pokud vaše aktuální místní řešení provádí více úloh na výpočetní uzel, můžete zvýšit maximální počet úloh uzlů, abyste tuto konfiguraci přesněji zrcadlily.

Příklad scénáře

Představte si například aplikaci úloh s požadavky na procesor a paměť, aby Standard_D1 uzly byly dostatečné. K dokončení úlohy v požadovaném čase je však potřeba 1 000 těchto uzlů.

Místo použití uzlů Standard_D1, které mají jedno jádro procesoru, můžete použít uzly Standard_D14 , které mají každý 16 jader, a povolit paralelní spouštění úloh. Mohli byste potenciálně použít 16krát méně uzlů místo 1 000 uzlů, bylo by potřeba pouze 63. Pokud jsou pro každý uzel vyžadovány velké soubory aplikace nebo referenční data, doba trvání a efektivita úlohy se zlepší, protože data se zkopírují pouze do 63 uzlů.

Povolení paralelního spouštění úloh

Výpočetní uzly nakonfigurujete pro paralelní spouštění úloh na úrovni fondu. V knihovně Batch .NET nastavte vlastnost CloudPool.TaskSlotsPerNode při vytváření fondu. Pokud používáte rozhraní BATCH REST API, nastavte element taskSlotsPerNode v textu požadavku během vytváření fondu.

Poznámka

Vlastnost elementu taskSlotsPerNode a TaskSlotsPerNode můžete nastavit pouze při vytváření fondu. Po vytvoření fondu je nelze upravit.

Azure Batch umožňuje nastavit sloty úloh na jeden uzel až do (4x) počtu jader uzlů. Pokud je například fond nakonfigurovaný s uzly o velikosti "Velké" (čtyři jádra), taskSlotsPerNode může být nastavený na 16. Bez ohledu na to, kolik jader uzel má, ale nemůžete mít na jeden uzel více než 256 slotů úloh. Podrobnosti o počtu jader pro jednotlivé velikosti uzlů najdete v tématu Velikosti pro Cloud Services (klasické). Další informace o limitech služby najdete v tématu Kvóty a limity služby Batch.

Tip

Nezapomeňte vzít v taskSlotsPerNode úvahu hodnotu při vytváření vzorce automatického škálování pro váš fond. Například vzorec, který vyhodnocuje $RunningTasks , může být výrazně ovlivněn zvýšením počtu úkolů na uzel. Další informace najdete v tématu Vytvoření automatického vzorce pro škálování výpočetních uzlů ve fondu služby Batch.

Určení distribuce úkolů

Při povolování souběžných úloh je důležité určit, jak se mají úkoly distribuovat mezi uzly ve fondu.

Pomocí vlastnosti CloudPool.TaskSchedulingPolicy můžete určit, že úkoly se mají přiřazovat rovnoměrně napříč všemi uzly ve fondu ("rozprostření"). Nebo můžete určit, že před přiřazením úkolů k jinému uzlu ve fondu ("balení") se má každému uzlu přiřadit co nejvíce úkolů.

Představte si například fond uzlů Standard_D14 (v předchozím příkladu), který je nakonfigurovaný s hodnotou CloudPool.TaskSlotsPerNode 16. Pokud je cloudPool.TaskSchedulingPolicy nakonfigurovaný s výpočetním uzlemFillTypebalíčku, maximalizuje využití všech 16 jader každého uzlu a umožní fondu automatického škálování odebrat nepoužívané uzly (uzly bez přiřazených úkolů) z fondu. Automatické škálování minimalizuje využití prostředků a může ušetřit peníze.

Definování slotů proměnných na úkol

Úlohu lze definovat pomocí vlastnosti CloudTask.RequiredSlots , která určuje, kolik slotů vyžaduje spuštění na výpočetním uzlu. Výchozí hodnota je 1. Proměnné sloty úkolů můžete nastavit, pokud mají vaše úkoly různé váhy spojené s jejich využitím prostředků na výpočetním uzlu. Sloty proměnných úloh umožňují každému výpočetnímu uzlu mít přiměřený počet souběžně spuštěných úloh bez zahlcení systémových prostředků, jako je procesor nebo paměť.

Například pro fond s vlastností taskSlotsPerNode = 8můžete odesílat úlohy s více jádry, které jsou náročné na procesor , requiredSlots = 8zatímco ostatní úlohy lze nastavit na requiredSlots = 1. Při naplánování této smíšené úlohy běží úlohy náročné na procesor výhradně na výpočetních uzlech, zatímco jiné úlohy můžou běžet souběžně (až osm úloh najednou) na jiných uzlech. Smíšené úlohy pomáhají vyrovnávat úlohy mezi výpočetními uzly a zlepšují efektivitu využití prostředků.

Ujistěte se, že neurčíte, jestli má být úkol requiredSlots větší než hodnota fondu taskSlotsPerNode, nebo se úkol nikdy nespustí. Služba Batch v současné době při odesílání úkolů tento konflikt neověřuje. Tento konflikt se neověřuje, protože úloha nemusí mít v době odeslání vázaný fond nebo se může změnit na jiný fond zakázáním nebo opětovným povolením.

Tip

Při použití slotů proměnných úkolů je možné, že velké úlohy s více požadovanými sloty se dočasně nepodaří naplánovat, protože na žádném výpočetním uzlu není k dispozici dostatek slotů, i když jsou na některých uzlech stále nečinné sloty. U těchto úkolů můžete zvýšit prioritu úlohy, abyste zvýšili jejich šanci soutěžit o dostupné sloty na uzlech.

Služba Batch vygeneruje TaskScheduleFailEvent , když se jí nepodaří naplánovat spuštění úlohy, a opakuje pokusy o plánování, dokud nebudou k dispozici požadované sloty. Tuto událost si můžete poslechnout, abyste zjistili potenciální problémy s plánováním úkolů a odpovídajícím způsobem ho zmírnili.

Příklad batch .NET

Následující fragmenty kódu rozhraní Api .NET služby Batch ukazují, jak vytvořit fond s více sloty úloh na uzel a jak odeslat úlohu s požadovanými sloty.

Vytvoření fondu s více sloty úkolů na uzel

Tento fragment kódu ukazuje požadavek na vytvoření fondu, který obsahuje čtyři uzly se čtyřmi sloty úkolů povolenými pro každý uzel. Určuje zásadu plánování úkolů, která před přiřazením úkolů k jinému uzlu ve fondu vyplní každý uzel úkoly.

Další informace o přidávání fondů pomocí rozhraní Batch .NET API najdete v tématu BatchClient.PoolOperations.CreatePool.

CloudPool pool =
    batchClient.PoolOperations.CreatePool(
        poolId: "mypool",
        targetDedicatedComputeNodes: 4
        virtualMachineSize: "standard_d1_v2",
        VirtualMachineConfiguration: new VirtualMachineConfiguration(
            imageReference: new ImageReference(
                                publisher: "MicrosoftWindowsServer",
                                offer: "WindowsServer",
                                sku: "2019-datacenter-core",
                                version: "latest"),
            nodeAgentSkuId: "batch.node.windows amd64");

pool.TaskSlotsPerNode = 4;
pool.TaskSchedulingPolicy = new TaskSchedulingPolicy(ComputeNodeFillType.Pack);
pool.Commit();

Vytvoření úkolu s požadovanými sloty

Tento fragment kódu vytvoří úlohu s nedefaultním kódem requiredSlots. Tato úloha se spustí, pokud je na výpočetním uzlu k dispozici dostatek volných slotů.

CloudTask task = new CloudTask(taskId, taskCommandLine)
{
    RequiredSlots = 2
};

Výpis výpočetních uzlů s počty spuštěných úloh a slotů

Tento fragment kódu obsahuje seznam všech výpočetních uzlů ve fondu a vytiskne počty spuštěných úloh a slotů úloh na uzel.

ODATADetailLevel nodeDetail = new ODATADetailLevel(selectClause: "id,runningTasksCount,runningTaskSlotsCount");
IPagedEnumerable<ComputeNode> nodes = batchClient.PoolOperations.ListComputeNodes(poolId, nodeDetail);

await nodes.ForEachAsync(node =>
{
    Console.WriteLine(node.Id + " :");
    Console.WriteLine($"RunningTasks = {node.RunningTasksCount}, RunningTaskSlots = {node.RunningTaskSlotsCount}");

}).ConfigureAwait(continueOnCapturedContext: false);

Výpis počtů úkolů pro úlohu

Tento fragment kódu získá počty úkolů pro úlohu, což zahrnuje jak počet úkolů, tak počet slotů úkolů podle stavu úkolu.

TaskCountsResult result = await batchClient.JobOperations.GetJobTaskCountsAsync(jobId);

Console.WriteLine("\t\tActive\tRunning\tCompleted");
Console.WriteLine($"TaskCounts:\t{result.TaskCounts.Active}\t{result.TaskCounts.Running}\t{result.TaskCounts.Completed}");
Console.WriteLine($"TaskSlotCounts:\t{result.TaskSlotCounts.Active}\t{result.TaskSlotCounts.Running}\t{result.TaskSlotCounts.Completed}");

Příklad služby Batch REST

Následující fragmenty kódu rozhraní Batch REST API ukazují, jak vytvořit fond s více sloty úloh na uzel a jak odeslat úkol s požadovanými sloty.

Vytvoření fondu s více sloty úkolů na uzel

Tento fragment kódu ukazuje požadavek na vytvoření fondu, který obsahuje dva velké uzly s maximálně čtyřmi úkoly na uzel.

Další informace o přidávání fondů pomocí rozhraní REST API najdete v tématu Přidání fondu k účtu.

{
  "odata.metadata":"https://myaccount.myregion.batch.azure.com/$metadata#pools/@Element",
  "id":"mypool",
  "vmSize":"large",
  "virtualMachineConfiguration": {
    "imageReference": {
      "publisher": "canonical",
      "offer": "ubuntuserver",
      "sku": "20.04-lts"
    },
    "nodeAgentSKUId": "batch.node.ubuntu 20.04"
  },
  "targetDedicatedComputeNodes":2,
  "taskSlotsPerNode":4,
  "enableInterNodeCommunication":true,
}

Vytvoření úkolu s požadovanými sloty

Tento fragment kódu zobrazuje požadavek na přidání úkolu s nestandardním requiredSlotskódem . Tato úloha se spustí pouze v případě, že je na výpočetním uzlu k dispozici dostatek volných slotů.

{
  "id": "taskId",
  "commandLine": "bash -c 'echo hello'",
  "userIdentity": {
    "autoUser": {
      "scope": "task",
      "elevationLevel": "nonadmin"
    }
  },
  "requiredSLots": 2
}

Ukázka kódu na GitHubu

Projekt ParallelTasks na GitHubu znázorňuje použití vlastnosti CloudPool.TaskSlotsPerNode .

Tato konzolová aplikace C# používá knihovnu Batch .NET k vytvoření fondu s jedním nebo více výpočetními uzly. Na těchto uzlech provádí konfigurovatelný počet úloh, které simulují zatížení proměnných. Výstup z aplikace ukazuje, které uzly provedly jednotlivé úlohy. Aplikace také poskytuje souhrn parametrů úlohy a doby trvání.

Následující příklad ukazuje souhrnnou část výstupu ze dvou různých spuštění ukázkové aplikace ParallelTasks. Zde uvedené doby trvání úloh nezahrnují čas vytvoření fondu, protože každá úloha byla odeslána do dříve vytvořeného fondu, jehož výpočetní uzly byly v době odeslání ve stavu nečinnosti .

První spuštění ukázkové aplikace ukazuje, že s jedním uzlem ve fondu a výchozím nastavením jednoho úkolu na uzel je doba trvání úlohy více než 30 minut.

Nodes: 1
Node size: large
Task slots per node: 1
Max slots per task: 1
Tasks: 32
Duration: 00:30:01.4638023

Druhé spuštění ukázky ukazuje významné snížení doby trvání úlohy. Toto snížení je způsobeno tím, že fond byl nakonfigurovaný se čtyřmi úkoly na uzel, což umožňuje paralelní provádění úkolů dokončit úlohu téměř za čtvrtinu času.

Nodes: 1
Node size: large
Task slots per node: 4
Max slots per task: 1
Tasks: 32
Duration: 00:08:48.2423500

Další kroky