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. Beakta följande scenarier:
- Minimera dataöverföringen för uppgifter som kan dela data. Du kan avsevärt minska dataöverföringsavgifterna 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 din aktuella lokala lösning kör flera uppgifter per beräkningsnod kan du öka det maximala antalet nodaktiviteter för att bättre spegla den konfigurationen.
Exempel på ett scenario
Tänk dig till exempel ett aktivitetsprogram med processor- och minneskrav så att Standard_D1 noder är tillräckliga. 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 CPU-kä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 kopieras till endast 63 noder.
Aktivera parallell aktivitetskö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.
Anteckning
Du kan bara ange taskSlotsPerNode
egenskapen element och TaskSlotsPerNode när poolen skapas. De kan inte ändras när en pool redan har skapats.
Azure Batch kan du ange aktivitetsfack per nod upp till (4 x) antalet nodkärnor. Om poolen till exempel har konfigurerats med noder med storleken "Large" (fyra kärnor) kan den taskSlotsPerNode
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 Cloud Services (klassisk). Mer information om tjänstbegränsningar finns i Batch-tjänstkvoter och -gränser.
Tips
Tänk på att ta hänsyn taskSlotsPerNode
till värdet när du skapar en autoskalningsformel för din pool. En formel som utvärderas $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 aktiviteter är det viktigt att ange hur du vill att aktiviteterna ska distribueras över noderna i poolen.
Med egenskapen CloudPool.TaskSchedulingPolicy kan du ange att aktiviteter ska tilldelas jämnt över alla noder i poolen ("sprida"). 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 av Pack skulle den maximera användningen av alla 16 kärnor i varje nod och tillåta att en pool för automatisk skalning tar bort oanvända noder (noder utan tilldelade uppgifter) från poolen. Automatisk skalning minimerar resursanvändningen och kan spara pengar.
Definiera variabelfack per aktivitet
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 variabla 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 = 8
kan 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 exklusivt 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 att en aktivitet ska requiredSlots
vara större än poolens taskSlotsPerNode
eller att aktiviteten aldrig körs. Batch-tjänsten verifierar för närvarande inte den här konflikten när du skickar uppgifter. Den validerar inte konflikten eftersom ett jobb kanske inte har en pool som är bunden vid sändningstidpunkt, eller så kan den ändras till en annan pool genom att inaktivera/återaktivera.
Tips
När du använder variabla 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 höja 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 det inte går att schemalägga en aktivitet att 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 aktivitetsschemaläggningsprincip 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 platser
Det här kodfragmentet skapar en uppgift med nondefault requiredSlots
. Den här uppgiften 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 för aktiviteter och platser som körs
Det här kodfragmentet visar alla beräkningsnoder i poolen och skriver ut antalet för aktiviteter och aktivitetsfack som körs 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);
Lista uppgiftsantal för jobbet
Det här kodfragmentet hämtar uppgiftsantal för jobbet, som innehåller både uppgifter och antal aktivitetsfack per aktivitetstillstånd.
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}");
Batch REST-exempel
Följande kodfragment för Batch REST API 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 uppgiften 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. Jobbvaraktigheter som visas här inkluderar inte tiden för att skapa poolen, 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 körningen av exemplet visar en betydande minskning av jobbvaraktigheten. Den här minskningen beror på att poolen har konfigurerats med fyra aktiviteter per nod, vilket gör att parallell aktivitetskörning kan 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