Dela via


Köra uppgifter samtidigt för att maximera användningen av Batch-beräkningsnoder

Du kan maximera resursanvändningen på ett mindre antal beräkningsnoder i poolen genom att köra mer än en aktivitet samtidigt på varje nod.

Vissa scenarier fungerar bäst med alla en nods resurser som är dedikerade till en enda uppgift, men vissa arbetsbelastningar kan se kortare jobbtider och lägre kostnader när flera aktiviteter delar dessa resurser. Föreställ dig följande scenarier:

  • Minimera dataöverföring för uppgifter som kan dela data. Du kan minska kostnaderna för dataöverföring avsevärt genom att kopiera delade data till ett mindre antal noder och sedan köra uppgifter parallellt på varje nod. Den här strategin gäller särskilt om data som ska kopieras till varje nod måste överföras mellan geografiska regioner.
  • Maximera minnesanvändningen för uppgifter som kräver en stor mängd minne, men bara under korta tidsperioder och vid varierande tidpunkter under körningen. Du kan använda färre, men större, beräkningsnoder med mer minne för att effektivt hantera sådana toppar. Dessa noder har flera uppgifter som körs parallellt på varje nod, men varje uppgift kan dra nytta av nodernas rikliga minne vid olika tidpunkter.
  • Minimera nodnummergränser när kommunikation mellan noder krävs i en pool. För närvarande är pooler som konfigurerats för kommunikation mellan noder begränsade till 50 beräkningsnoder. Om varje nod i en sådan pool kan köra uppgifter parallellt kan ett större antal aktiviteter köras samtidigt.
  • Replikera ett lokalt beräkningskluster, till exempel när du först flyttar en beräkningsmiljö till Azure. Om den aktuella lokala lösningen kör flera uppgifter per beräkningsnod kan du öka det maximala antalet nodaktiviteter för att bättre spegla den konfigurationen.

Exempelscenario

Tänk dig till exempel ett aktivitetsprogram med processor- och minneskrav så att Standard_D1 noder räcker. Men för att slutföra jobbet under den tid som krävs behövs 1 000 av dessa noder.

I stället för att använda Standard_D1 noder som har en processorkärna kan du använda Standard_D14 noder som har 16 kärnor vardera och aktivera parallell aktivitetskörning. Du kan potentiellt använda 16 gånger färre noder i stället för 1 000 noder. Endast 63 krävs. Om stora programfiler eller referensdata krävs för varje nod förbättras jobbvaraktigheten och effektiviteten eftersom data endast kopieras till 63 noder.

Aktivera parallell uppgiftskörning

Du konfigurerar beräkningsnoder för parallell aktivitetskörning på poolnivå. Med Batch .NET-biblioteket anger du egenskapen CloudPool.TaskSlotsPerNode när du skapar en pool. Om du använder Batch REST API anger du elementet taskSlotsPerNode i begärandetexten när poolen skapas.

Anmärkning

Du kan endast ange taskSlotsPerNode elementet och TaskSlotsPerNode egenskapen vid poolens skapande. De kan inte ändras när en pool redan har skapats.

Med Azure Batch kan du ange aktivitetsfack per nod upp till (4 gånger) antalet nodkärnor. Om poolen till exempel har konfigurerats med noder med storleken "Large" (fyra kärnor) taskSlotsPerNode kan den vara inställd på 16. Oavsett hur många kärnor noden har kan du dock inte ha fler än 256 aktivitetsfack per nod. Mer information om antalet kärnor för var och en av nodstorlekarna finns i Storlekar för Molntjänster (klassisk). Mer information om tjänstbegränsningar finns i Batch-tjänstkvoter och -gränser.

Tips/Råd

Tänk på att ta hänsyn till taskSlotsPerNode-värdet när du skapar en autoskalningsformel för din pool. En formel som utvärderar $RunningTasks kan till exempel påverkas dramatiskt av en ökning av aktiviteter per nod. Mer information finns i Skapa en automatisk formel för skalning av beräkningsnoder i en Batch-pool.

Ange aktivitetsdistribution

När du aktiverar samtidiga uppgifter är det viktigt att ange hur du vill att aktiviteterna ska distribueras över noderna i poolen.

Genom att använda egenskapen CloudPool.TaskSchedulingPolicy kan du ange att aktiviteter ska tilldelas jämnt över alla noder i poolen ("spridning"). Eller så kan du ange att så många aktiviteter som möjligt ska tilldelas till varje nod innan aktiviteter tilldelas till en annan nod i poolen ("packning").

Tänk dig till exempel poolen med Standard_D14 noder (i föregående exempel) som har konfigurerats med värdet CloudPool.TaskSlotsPerNode på 16. Om CloudPool.TaskSchedulingPolicy har konfigurerats med en ComputeNodeFillType of Pack, skulle den maximera användningen av alla 16 kärnor av varje nod och tillåta att en automatisk skalningspool tar bort oanvända noder (noder utan tilldelade uppgifter) från poolen. Automatisk skalning minimerar resursanvändningen och kan spara pengar.

Definiera variabelplatser per uppgift

En uppgift kan definieras med egenskapen CloudTask.RequiredSlots , som anger hur många platser som krävs för att köras på en beräkningsnod. Standardvärdet är 1. Du kan ange variabla aktivitetsfack om dina aktiviteter har olika vikter som är associerade med deras resursanvändning på beräkningsnoden. Med varierande aktivitetsfack kan varje beräkningsnod ha ett rimligt antal samtidiga aktiviteter som körs utan att överbelasta systemresurser som CPU eller minne.

För en pool med egenskapen taskSlotsPerNode = 8kan du till exempel skicka processorintensiva uppgifter med flera kärnor med requiredSlots = 8, medan andra uppgifter kan anges till requiredSlots = 1. När den här blandade arbetsbelastningen schemaläggs körs de CPU-intensiva uppgifterna uteslutande på sina beräkningsnoder, medan andra aktiviteter kan köras samtidigt (upp till åtta aktiviteter samtidigt) på andra noder. Den blandade arbetsbelastningen hjälper dig att balansera din arbetsbelastning mellan beräkningsnoder och förbättra resursanvändningens effektivitet.

Se till att du inte anger en uppgifts requiredSlots till att överstiga poolens taskSlotsPerNode, annars körs aldrig uppgiften. Batch-tjänsten verifierar för närvarande inte den här konflikten när du skickar uppgifter. Bekräftar inte konflikten eftersom ett jobb kanske inte har en pool bunden när det skickas in, eller så kan det ändras till en annan pool genom att inaktivera/återaktivera.

Tips/Råd

När du använder varierande aktivitetsfack är det möjligt att stora aktiviteter med fler nödvändiga platser tillfälligt inte kan schemaläggas eftersom det inte finns tillräckligt med platser på någon beräkningsnod, även om det fortfarande finns inaktiva platser på vissa noder. Du kan öka jobbprioriteten för dessa aktiviteter för att öka deras chans att konkurrera om tillgängliga platser på noder.

Batch-tjänsten genererar TaskScheduleFailEvent när den inte schemalägger en aktivitet som ska köras och fortsätter att försöka schemalägga igen tills nödvändiga platser blir tillgängliga. Du kan lyssna på händelsen för att identifiera potentiella problem med schemaläggning av uppgifter och åtgärda detta.

Batch .NET-exempel

Följande Batch .NET API-kodfragment visar hur du skapar en pool med flera aktivitetsfack per nod och hur du skickar en uppgift med nödvändiga platser.

Skapa en pool med flera aktivitetsfack per nod

Det här kodfragmentet visar en begäran om att skapa en pool som innehåller fyra noder, med fyra tillåtna aktivitetsfack per nod. Den anger en princip för aktivitetsschemaläggning som fyller varje nod med aktiviteter innan aktiviteter tilldelas till en annan nod i poolen.

Mer information om hur du lägger till pooler med hjälp av Batch .NET API finns i 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();

Skapa en uppgift med nödvändiga slottar

Det här kodfragmentet skapar en uppgift med nondefault requiredSlots. Den här aktiviteten körs när det finns tillräckligt med lediga platser på en beräkningsnod.

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

Lista beräkningsnoder med antal körande uppgifter och platser

Det här kodfragmentet visar en lista över alla beräkningsnoder i poolen och skriver ut antalet för aktiviteter som körs och aktivitetsfack per nod.

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);

Antal uppgiftslistor för jobbet

Det här kodavsnittet hämtar antal uppgifter för jobbet, vilket omfattar både antal uppgifter och uppgiftsplatser per uppgiftsstatus.

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}");

Ett batch-REST-exempel

Följande Batch REST API-kodfragment visar hur du skapar en pool med flera aktivitetsfack per nod och hur du skickar en uppgift med nödvändiga platser.

Skapa en pool med flera aktivitetsfack per nod

Det här kodfragmentet visar en begäran om att skapa en pool som innehåller två stora noder med högst fyra uppgifter per nod.

Mer information om hur du lägger till pooler med hjälp av REST-API:et finns i Lägga till en pool i ett konto.

{
  "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,
}

Skapa en uppgift med nödvändiga platser

Det här kodfragmentet visar en begäran om att lägga till en uppgift med nondefault requiredSlots. Den här aktiviteten körs bara när det finns tillräckligt med lediga platser på beräkningsnoden.

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

Kodexempel på GitHub

ParallelTasks-projektet på GitHub illustrerar användningen av egenskapen CloudPool.TaskSlotsPerNode.

Det här C#-konsolprogrammet använder Batch .NET-biblioteket för att skapa en pool med en eller flera beräkningsnoder. Den kör ett konfigurerbart antal uppgifter på dessa noder för att simulera en variabel belastning. Utdata från programmet visar vilka noder som körde varje uppgift. Programmet innehåller också en sammanfattning av jobbparametrarna och varaktigheten.

I följande exempel visas sammanfattningsdelen av utdata från två olika körningar av Exempelprogrammet ParallelTasks. Jobbvaraktigheterna som visas här inkluderar inte tiden då poolen skapades, eftersom varje jobb skickades till en tidigare skapad pool vars beräkningsnoder var i inaktivt tillstånd vid sändningstiden.

Den första körningen av exempelprogrammet visar att med en enda nod i poolen och standardinställningen för en aktivitet per nod är jobbvaraktigheten över 30 minuter.

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

Den andra omgången av provet visar en betydande minskning av jobbvaraktigheten. Den här minskningen beror på att poolen har konfigurerats med fyra aktiviteter per nod, vilket möjliggör parallell aktivitetskörning för att slutföra jobbet inom nästan en fjärdedel av tiden.

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

Nästa steg