Freigeben über


Gleichzeitiges Ausführen von Aufgaben zur Maximierung der Nutzung von Batch-Computeknoten

Sie können die Ressourcennutzung für eine kleinere Anzahl von Computeknoten in Ihrem Pool maximieren, indem Sie mehrere Vorgänge gleichzeitig auf jedem Knoten ausführen.

Während einige Szenarien am besten mit allen Ressourcen eines Knotens funktionieren, die einem einzelnen Vorgang zugeordnet sind, sehen bestimmte Workloads möglicherweise kürzere Arbeitszeiten und niedrigere Kosten, wenn mehrere Vorgänge diese Ressourcen gemeinsam nutzen. Betrachten Sie die folgenden Szenarien:

  • Minimieren Sie die Datenübertragung für Aufgaben, die Daten freigeben können. Sie können Datenübertragungsgebühren erheblich reduzieren, indem Sie freigegebene Daten in eine kleinere Anzahl von Knoten kopieren und dann Aufgaben parallel auf jedem Knoten ausführen. Diese Strategie gilt insbesondere, wenn die daten, die in jeden Knoten kopiert werden sollen, zwischen geografischen Regionen übertragen werden müssen.
  • Maximieren Sie die Speicherauslastung für Aufgaben, die eine große Menge Arbeitsspeicher erfordern, aber nur während kurzer Zeiträume und zu variablen Zeiten während der Ausführung. Sie können weniger, aber größere Rechenknoten mit mehr Arbeitsspeicher verwenden, um solche Spitzen effizient zu verarbeiten. Diese Knoten haben mehrere Aufgaben, die parallel auf jedem Knoten ausgeführt werden, aber jede Aufgabe kann den reichlichen Arbeitsspeicher der Knoten zu unterschiedlichen Zeiten nutzen.
  • Verringern Sie die Grenzwerte für Knotennummern , wenn die Kommunikation zwischen Knoten innerhalb eines Pools erforderlich ist. Derzeit sind pools, die für die Kommunikation zwischen Knoten konfiguriert sind, auf 50 Computeknoten beschränkt. Wenn jeder Knoten in einem solchen Pool Aufgaben parallel ausführen kann, kann gleichzeitig eine größere Anzahl von Aufgaben ausgeführt werden.
  • Replizieren Sie einen lokalen Computecluster, z. B. wenn Sie eine Computeumgebung zum ersten Mal in Azure verschieben. Wenn Ihre aktuelle lokale Lösung mehrere Aufgaben pro Computeknoten ausführt, können Sie die maximale Anzahl von Knotenaufgaben erhöhen, um diese Konfiguration genauer zu spiegeln.

Beispielszenario

Stellen Sie sich beispielsweise eine Aufgabenanwendung mit CPU- und Arbeitsspeicheranforderungen vor, sodass Standard_D1 Knoten ausreichend sind. Um den Auftrag jedoch in der erforderlichen Zeit abzuschließen, sind 1.000 dieser Knoten erforderlich.

Statt Standard_D1 Knoten mit einem CPU-Kern zu verwenden, können Sie Standard_D14 Knoten mit jeweils 16 Kernen verwenden und die parallele Aufgabenausführung aktivieren. Sie könnten möglicherweise 16 mal weniger Knoten anstelle von 1.000 Knoten verwenden, es wäre nur 63 erforderlich. Wenn große Anwendungsdateien oder Referenzdaten für jeden Knoten erforderlich sind, werden die Auftragsdauer und effizienz verbessert, da die Daten nur auf 63 Knoten kopiert werden.

Aktivieren der parallelen Aufgabenausführung

Sie konfigurieren Computeknoten für die parallele Aufgabenausführung auf Poolebene. Legen Sie bei der Batch-.NET-Bibliothek die Eigenschaft "CloudPool.TaskSlotsPerNode " fest, wenn Sie einen Pool erstellen. Wenn Sie die Batch-REST-API verwenden, legen Sie das taskSlotsPerNode-Element im Anforderungstext während der Poolerstellung fest.

Hinweis

Sie können das taskSlotsPerNode-Element und die TaskSlotsPerNode-Eigenschaft nur bei der Erstellung des Pools festlegen. Sie können nicht geändert werden, nachdem ein Pool bereits erstellt wurde.

Mit Azure Batch können Sie Aufgabenslots pro Knoten bis zu (4x) der Anzahl der Knotenkerne festlegen. Wenn der Pool beispielsweise mit Knoten der Größe "Groß" (vier Kerne) konfiguriert ist, kann er taskSlotsPerNode auf 16 festgelegt werden. Unabhängig von der Anzahl der Kerne des Knotens können Sie jedoch nicht mehr als 256 Aufgabenplätze pro Knoten haben. Ausführliche Informationen zur Anzahl der Kerne für jede Knotengröße finden Sie unter "Größen für Cloud Services (klassisch)". Weitere Informationen zu Dienstgrenzwerten finden Sie unter Batchdienstkontingente und Grenzwerte.

Tipp

Berücksichtigen Sie beim Erstellen einer taskSlotsPerNode für Den Pool unbedingt den Wert. Beispielsweise könnte eine Formel, die $RunningTasks auswertet, wesentlich von einer Zunahme der Aufgaben pro Knoten beeinflusst werden. Weitere Informationen finden Sie unter Erstellen einer automatischen Formel zum Skalieren von Computeknoten in einem Batchpool.

Angeben der Aufgabenverteilung

Wenn Sie gleichzeitige Aufgaben aktivieren, müssen Sie angeben, wie die Aufgaben über die Knoten im Pool verteilt werden sollen.

Mithilfe der Eigenschaft "CloudPool.TaskSchedulingPolicy " können Sie angeben, dass Vorgänge gleichmäßig über alle Knoten im Pool zugewiesen werden sollen ("Verbreitung"). Oder Sie können angeben, dass jedem Knoten so viele Vorgänge wie möglich zugewiesen werden sollen, bevor Vorgänge einem anderen Knoten im Pool zugewiesen werden ("Packen").

Betrachten Sie beispielsweise den Pool von Standard_D14 Knoten (im vorherigen Beispiel), der mit einem CloudPool.TaskSlotsPerNode-Wert von 16 konfiguriert ist. Wenn die CloudPool.TaskSchedulingPolicy mit einem ComputeNodeFillType of Pack konfiguriert ist, würde dies die Nutzung aller 16 Kerne jedes Knotens maximieren und einem automatischen Skalierungspool erlauben, nicht verwendete Knoten (Knoten ohne zugeordnete Aufgaben) aus dem Pool zu entfernen. Die automatische Skalierung minimiert den Ressourceneinsatz und kann Geld sparen.

Definieren von variablen Slots pro Aufgabe

Eine Aufgabe kann mit der Eigenschaft "CloudTask.RequiredSlots" definiert werden, die angibt, wie viele Slots für die Ausführung auf einem Computeknoten erforderlich sind. Der Standardwert ist 1. Sie können variable Task-Slots festlegen, wenn Ihre Vorgänge unterschiedliche Gewichtungen bei ihrer Ressourcennutzung auf dem Rechenknoten haben. Variable Aufgabenplätze ermöglichen es jedem Computeknoten, eine angemessene Anzahl gleichzeitig ausgeführter Aufgaben zu haben, ohne Systemressourcen wie CPU oder Arbeitsspeicher zu überwältigen.

Beispielsweise können Sie für einen Pool mit der Eigenschaft taskSlotsPerNode = 8 mehrkernige, CPU-intensive Aufgaben mit requiredSlots = 8 übermitteln, während andere Aufgaben auf requiredSlots = 1 festgelegt werden können. Wenn diese gemischte Workload geplant ist, werden die CPU-intensiven Aufgaben ausschließlich auf ihren Computeknoten ausgeführt, während andere Aufgaben gleichzeitig (bis zu acht Aufgaben gleichzeitig) auf anderen Knoten ausgeführt werden können. Die gemischte Arbeitslast hilft Ihnen, Ihre Arbeitsauslastung über Computeknoten hinweg auszugleichen und die Effizienz der Ressourcennutzung zu steigern.

Achten Sie darauf, dass Sie keine Aufgabe requiredSlots angeben, die größer als der Pool taskSlotsPerNodeist oder die Aufgabe nie ausgeführt wird. Der Batchdienst überprüft diesen Konflikt derzeit nicht, wenn Sie Aufgaben übermitteln. Der Konflikt wird nicht validiert, da ein Auftrag zum Zeitpunkt der Übermittlung möglicherweise nicht an einen Pool gebunden ist oder er durch Deaktivierung/Wiederaktivierung in einen anderen Pool geändert werden kann.

Tipp

Wenn Sie variable Aufgabenplätze verwenden, ist es möglich, dass große Vorgänge mit mehr erforderlichen Slots vorübergehend nicht geplant werden können, da nicht genügend Slots auf einem Berechnungsknoten verfügbar sind, auch wenn noch Leerlaufplätze auf einigen Knoten vorhanden sind. Sie können die Auftragspriorität für diese Aufgaben erhöhen, damit diese eine bessere Chance haben, die auf Knoten verfügbaren Slots zu erhalten.

Der Batchdienst gibt den TaskScheduleFailEvent aus, wenn ein Vorgang nicht ausgeführt werden kann, und wiederholt die Planung, bis erforderliche Slots verfügbar sind. Sie können auf dieses Ereignis lauschen, um potenzielle Aufgabenplanungsprobleme zu erkennen und entsprechend abzumildern.

Beispiel für Batch .NET

Die folgenden Codeausschnitte der Batch-.NET-API zeigen, wie Sie einen Pool mit mehreren Aufgabenplätzen pro Knoten erstellen und wie Sie eine Aufgabe mit erforderlichen Slots übermitteln.

Erstellen eines Pools mit mehreren Aufgabenplätzen pro Knoten

Dieser Codeausschnitt zeigt eine Anforderung zum Erstellen eines Pools mit vier Knoten, wobei pro Knoten vier Aufgabenplätze zulässig sind. Sie gibt eine Vorgangsplanungsrichtlinie an, die jeden Knoten mit Aufgaben ausfüllt, bevor Aufgaben einem anderen Knoten im Pool zugewiesen werden.

Weitere Informationen zum Hinzufügen von Pools mithilfe der Batch-.NET-API finden Sie unter 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();

Erstellen einer Aufgabe mit erforderlichen Slots

Dieser Codeausschnitt erstellt eine Aufgabe mit nicht standardmäßigem requiredSlots. Diese Aufgabe wird ausgeführt, wenn genügend freie Slots auf einem Computeknoten verfügbar sind.

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

Auflisten von Computeknoten mit der Anzahl ausgeführter Aufgaben und Slots

Dieser Codeausschnitt listet alle Computeknoten im Pool auf und druckt die Anzahl der ausgeführten Aufgaben und Aufgabenplätze pro Knoten.

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

Aufgabenanzahl für den Auftrag auflisten

Mit diesem Codeausschnitt wird die Anzahl von Aufgaben für den Auftrag abgerufen. Diese Zahl umfasst sowohl Aufgaben als auch Aufgabenslots pro Aufgabenzustand.

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-Beispiel

Die folgenden Codeausschnitte der Batch-REST-API zeigen, wie Sie einen Pool mit mehreren Aufgabenplätzen pro Knoten erstellen und wie Sie eine Aufgabe mit erforderlichen Slots übermitteln.

Erstellen eines Pools mit mehreren Aufgabenplätzen pro Knoten

Dieser Codeausschnitt zeigt eine Anforderung zum Erstellen eines Pools mit zwei großen Knoten mit maximal vier Aufgaben pro Knoten.

Weitere Informationen zum Hinzufügen von Pools mithilfe der REST-API finden Sie unter Hinzufügen eines Pools zu einem 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,
}

Erstellen einer Aufgabe mit erforderlichen Slots

Dieser Codeausschnitt zeigt eine Anforderung zum Hinzufügen einer Aufgabe mit einem nicht standardmäßigen requiredSlots-Wert. Diese Aufgabe wird nur ausgeführt, wenn genügend freie Slots auf dem Computeknoten verfügbar sind.

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

Codebeispiel auf GitHub

Das ParallelTasks-Projekt auf GitHub veranschaulicht die Verwendung der Eigenschaft "CloudPool.TaskSlotsPerNode" .

Diese C#-Konsolenanwendung verwendet die Batch-.NET-Bibliothek , um einen Pool mit mindestens einem Computeknoten zu erstellen. Sie führt eine konfigurierbare Anzahl von Aufgaben auf diesen Knoten aus, um eine variable Last zu simulieren. Die Ausgabe der Anwendung zeigt an, welche Knoten die einzelnen Aufgaben ausgeführt haben. Die Anwendung enthält außerdem eine Zusammenfassung der Auftragsparameter und der Dauer.

Das folgende Beispiel zeigt den Zusammenfassungsteil der Ausgabe aus zwei verschiedenen Läufen der ParallelTasks-Beispielanwendung. Auftragsdauern, die hier gezeigt werden, enthalten keine Poolerstellungszeit, da jeder Auftrag an einen zuvor erstellten Pool übermittelt wurde, dessen Computeknoten zur Übermittlungszeit im Leerlaufzustand lagen.

Die erste Ausführung der Beispielanwendung zeigt, dass bei einem einzelnen Knoten im Pool und der Standardeinstellung einer Aufgabe pro Knoten die Auftragsdauer über 30 Minuten beträgt.

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

Die zweite Ausführung des Beispiels zeigt eine signifikante Abnahme der Auftragsdauer. Diese Reduzierung liegt daran, dass der Pool mit vier Vorgängen pro Knoten konfiguriert wurde, sodass die parallele Aufgabenausführung in fast einem Viertel der Zeit abgeschlossen werden kann.

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

Nächste Schritte