Erstellen einer Formel für die automatische Skalierung von Serverknoten in einem Batch-Pool

Azure Batch kann Pools basierend auf von Ihnen definierten Parametern automatisch skalieren und Ihnen somit Zeit und Geld sparen. Bei der automatischen Skalierung fügt Batch einem Pool Knoten dynamisch hinzu, wenn der Taskbedarf steigt, und entfernt Computeknoten bei einem Rückgang des Taskbedarfs.

Um die automatische Skalierung für einen Pool von Computeknoten zu aktivieren, ordnen Sie den Pool einer von Ihnen definierten Formel für die automatische Skalierung zu. Anhand der Formel für die automatische Skalierung ermittelt der Batch-Dienst die Anzahl von Knoten, die zum Ausführen Ihrer Workload erforderlich sind. Diese Knoten können dedizierte Knoten oder Azure Spot-Knoten sein. Batch überprüft dann regelmäßig Dienstmetrikdaten und verwendet diese, um die Anzahl der Knoten im Pool basierend auf Ihrer Formel in einem von Ihnen definierten Intervall anzupassen.

Sie können automatische Skalierung beim Erstellen eines Pools aktivieren oder später auf einen vorhandenen Pool anwenden. In Batch können Sie Ihre Formeln vor dem Zuweisen zu Pools auswerten und den Status von Ausführungen der automatischen Skalierung überwachen. Nachdem Sie einen Pool mit automatischer Skalierung konfiguriert haben, können Sie später Änderungen an der Formel vornehmen.

Wichtig

Wenn Sie ein Batch-Konto erstellen, können Sie den Poolzuordnungsmodus angeben, der bestimmt, ob Pools in einem Batch-Dienstabonnement (Standardeinstellung) oder in Ihrem Benutzerabonnement zugeordnet werden. Wenn Sie Ihr Batch-Konto mit der Batch-Standarddienstkonfiguration erstellt haben, ist Ihr Konto auf eine maximale Anzahl von Kernen beschränkt, die für die Verarbeitung verwendet werden können. Der Batch-Dienst skaliert Computeknoten nur bis zu diesem Kernspeichergrenzwert. Aus diesem Grund erreicht der Batch-Dienst möglicherweise nicht die Zielanzahl der von einer Formel für die Autoskalierung angegebenen Serverknoten. Informationen dazu, wie Sie Ihre Kontokontingente anzeigen und erhöhen, finden Sie unter Kontingente und Limits für den Azure Batch-Dienst.

Wenn Sie Ihr Konto im Benutzerabonnementmodus erstellt haben, teilt Ihr Konto das Kernkontingent für das Abonnement. Weitere Informationen finden Sie unter Virtual Machines-Grenzwerte in Grenzwerte für Azure-Abonnements, -Dienste und -Kontingente sowie allgemeine Beschränkungen.

Formeln für automatische Skalierung

Eine Formel für automatische Skalierung ist ein von Ihnen definierter Zeichenfolgenwert, der mindestens eine Anweisung enthält. Die Formel für die Autoskalierung wird dem Element autoScaleFormula (Batch REST) oder der Eigenschaft CloudPool.AutoScaleFormula (Batch .NET) eines Pools zugewiesen. Der Batch-Dienst verwendet Ihre Formel, um für das nächste Verarbeitungsintervall die Zielanzahl der Computeknoten im Pool zu ermitteln. Die Formelzeichenfolge darf 8 KB nicht überschreiten und kann bis zu 100 durch Semikolons getrennte Anweisungen sowie Zeilenumbrüche und Kommentare enthalten.

Sie können sich Formeln für die automatische Skalierung als „Sprache“ für die Batch-Autoskalierung vorstellen. Formelanweisungen sind Freiformausdrücke, die sowohl vom Dienst definierte Variablen (vom Batch-Dienst definiert) als auch benutzerdefinierte Variablen enthalten können. Mithilfe von integrierten Typen, Operatoren und Funktionen können Formeln für diese Werte eine Vielzahl von Operationen ausführen. Eine Anweisung kann beispielsweise wie folgt aussehen:

$myNewVariable = function($ServiceDefinedVariable, $myCustomVariable);

Formeln enthalten im Allgemeinen mehrere Anweisungen, die Operationen für Werte durchführen, die in vorherigen Anweisungen abgerufen wurden. Ein Beispiel: Sie rufen zuerst einen Wert für variable1 ab und übergeben ihn dann an eine Funktion, um variable2 aufzufüllen:

$variable1 = function1($ServiceDefinedVariable);
$variable2 = function2($OtherServiceDefinedVariable, $variable1);

Fügen Sie diese Anweisungen zu Ihrer Formel für die automatische Skalierung hinzu, um eine Zielanzahl von Computeknoten zu erreichen. Dedizierte Knoten und Spot-Knoten verfügen jeweils über eigene Zieleinstellungen. Eine Formel für die automatische Skalierung kann einen Zielwert für dedizierte Knoten, einen Zielwert für Spot-Knoten oder beides enthalten.

Die Zielanzahl der Knoten kann höher oder niedriger als die aktuelle Anzahl von Knoten dieses Typs im Pool oder gleich der Anzahl der Knoten sein. Batch wertet die Autoskalierungsformel des Pools in bestimmten Intervallen für die automatische Skalierung aus. Batch passt die Zielanzahl von den einzelnen Knotentypen im Pool an die Anzahl an, die durch die Formel für die automatische Skalierung zum Zeitpunkt der Auswertung angegeben wird.

Beispielformeln für die automatische Skalierung

Die folgenden Beispiele zeigen zwei Autoskalierungsformeln, die für die meisten Szenarien angepasst werden können. Die Variablen startingNumberOfVMs und maxNumberofVMs in den Beispielformeln können Ihren Anforderungen angepasst werden.

Ausstehende Aufgaben

Mit dieser Formel für die automatische Skalierung wird der Pool zunächst mit einem einzigen virtuellen Computer erstellt. Die Metrik $PendingTasks definiert die Anzahl der Aufgaben, die ausgeführt werden oder sich in einer Warteschlange befinden. Die Formel sucht nach der durchschnittlichen Anzahl ausstehender Aufgaben in den letzten 180 Sekunden und legt die Variable $TargetDedicatedNodes entsprechend fest. Die Formel stellt sicher, dass die Zielanzahl der dedizierten Knoten niemals 25 virtuelle Computer überschreitet. Wenn neue Aufgaben gesendet werden, wächst der Pool automatisch an. Wenn Tasks abgeschlossen werden, werden VMs freigegeben, und der Pool wird durch die Formel für automatische Skalierung verkleinert.

Diese Formel skaliert dedizierte Knoten, kann jedoch so geändert werden, dass sie auch für die Skalierung von Spot-Knoten gilt.

startingNumberOfVMs = 1;
maxNumberofVMs = 25;
pendingTaskSamplePercent = $PendingTasks.GetSamplePercent(180 * TimeInterval_Second);
pendingTaskSamples = pendingTaskSamplePercent < 70 ? startingNumberOfVMs : avg($PendingTasks.GetSample(180 * TimeInterval_Second));
$TargetDedicatedNodes=min(maxNumberofVMs, pendingTaskSamples);
$NodeDeallocationOption = taskcompletion;

Wichtig

Derzeit gelten im Batch-Dienst Begrenzungen bei der Auflösung ausstehender Aufgaben. Wenn dem Auftrag eine Aufgabe hinzugefügt wird, wird sie auch einer internen Warteschlange hinzugefügt, die vom Batch-Dienst zur Planung verwendet wird. Wenn die Aufgabe gelöscht wird, bevor sie geplant werden kann, kann sie in der Warteschlange beibehalten werden, sodass sie weiterhin in $PendingTasksgezählt wird. Diese gelöschte Aufgabe wird schließlich aus der Warteschlange gelöscht, wenn Batch die Möglichkeit erhält, Aufgaben aus der Warteschlange zu pullen, um im Leerlaufknoten im Batch-Pool zu planen.

Vorzeitig entfernte Knoten

In diesem Beispiel wird ein Pool erstellt, der mit 25 Spot-Knoten beginnt. Jedes Mal, wenn ein Spot-Knoten vorzeitig entfernt wird, wird er durch einen dedizierten Knoten ersetzt. Wie im ersten Beispiel verhindert die maxNumberofVMs-Variable, dass der Pool 25 VMs überschreitet. Dieses Beispiel ist nützlich, um Spot-VMs zu nutzen und gleichzeitig sicherzustellen, dass während der Lebensdauer des Pools nur eine festgelegte Anzahl von vorzeitigen Entfernungen auftritt.

maxNumberofVMs = 25;
$TargetDedicatedNodes = min(maxNumberofVMs, $PreemptedNodeCount.GetSample(180 * TimeInterval_Second));
$TargetLowPriorityNodes = min(maxNumberofVMs , maxNumberofVMs - $TargetDedicatedNodes);
$NodeDeallocationOption = taskcompletion;

Weitere Informationen zum Erstellen von Formeln für die Autoskalierung sowie weitere Beispielformeln für die Autoskalierung finden Sie weiter unten in diesem Artikel.

Variables

Sie können in Ihrer Formel für die automatische Skalierung sowohl dienstdefinierte als auch benutzerdefinierte Variablen verwenden.

Vom Dienst definierte Variablen sind in den Batch-Dienst integriert. Einige der vom Dienst definierten Variablen verfügen über Lese-/Schreibzugriff, und einige sind schreibgeschützt.

Benutzerdefinierte Variablen sind Variablen, die Sie definieren. Im obigen Beispiel sind $TargetDedicatedNodes und $PendingTasks vom Dienst definierte Variablen, startingNumberOfVMs und maxNumberofVMs dagegen sind benutzerdefinierte Variablen.

Hinweis

Vom Dienst definierten Variablen wird immer ein Dollarzeichen ($) vorangestellt. Für benutzerdefinierte Variablen ist das Dollarzeichen optional.

Die folgenden Tabellen enthalten sowohl die Variablen mit Lese-/Schreibzugriff als auch schreibgeschützte Variablen, die vom Batch-Dienst definiert werden.

Vom Dienst definierte Variablen mit Lese-/Schreibzugriff

Sie können diese vom Dienst definierten Variablen abrufen und festlegen, um die Anzahl der Computeknoten in einem Pool zu verwalten.

Variable BESCHREIBUNG
$TargetDedicatedNodes Die Zielanzahl dedizierter Computeknoten für den Pool. Diese wird als Ziel angegeben, da ein Pool möglicherweise nicht immer die gewünschte Anzahl von Knoten erreicht. Wenn beispielsweise die Zielanzahl dedizierter Knoten durch eine Auswertung der Autoskalierung geändert wird, bevor der Pool das ursprüngliche Ziel erreicht hat, erreicht der Pool die Zielanzahl möglicherweise nicht.

Ein Pool in einem Konto, das im Batch-Dienstmodus erstellt wurde, erreicht möglicherweise nicht sein Ziel, wenn das Ziel ein Batch-Kontoknoten- oder -Kernkontingent überschreitet. Ein Pool in einem Konto, das im Benutzerabonnementmodus erstellt wurde, erreicht möglicherweise nicht sein Ziel, wenn das Ziel das freigegebene Kernkontingent für das Abonnement überschreitet.
$TargetLowPriorityNodes Die Zielanzahl von Spot-Computeknoten für den Pool. Diese wird als Ziel angegeben, da ein Pool möglicherweise nicht immer die gewünschte Anzahl von Knoten erreicht. Wenn beispielsweise die Zielanzahl von Spot-Knoten durch eine Auswertung der Autoskalierung geändert wird, bevor der Pool das ursprüngliche Ziel erreicht hat, erreicht der Pool das Ziel möglicherweise nicht. Ein Pool kann sein Ziel möglicherweise auch dann nicht erreichen, wenn das Ziel ein Batch-Kontoknoten- oder -Kernkontingent überschreitet.

Weitere Informationen zu Spot-Computeknoten finden Sie unter Verwenden von Spot-VMs mit Batch.
$NodeDeallocationOption Dieser Vorgang wird ausgeführt, wenn Computeknoten aus einem Pool entfernt werden. Mögliche Werte:
- requeue: Der Standardwert. Aufgaben werden sofort beendet und wieder in die Auftragswarteschlange eingereiht, damit sie neu geplant werden können. Dadurch wird sichergestellt, dass die Zielanzahl der Knoten so schnell wie möglich erreicht wird. Dies kann jedoch weniger effizient sein, da alle ausgeführten Aufgaben unterbrochen werden und dann neu gestartet werden müssen.
- terminate: Beendet Aufgaben sofort und entfernt sie aus der Auftragswarteschlange.
- taskcompletion: Wartet auf derzeit ausgeführte Aufgaben und entfernt den Knoten dann aus dem Pool. Verwenden Sie diese Option, um zu verhindern, dass Aufgaben unterbrochen und nochmals der Warteschlange hinzugefügt werden, wodurch bereits durchgeführte Aufgabenschritte umsonst erfolgt wären.
- retaineddata: Wartet, bis alle für die Aufgabe lokal vorgehaltenen Daten des Pools bereinigt wurden, bevor der Knoten aus dem Pool entfernt wird.

Hinweis

Die Variable $TargetDedicatedNodes kann auch mit dem Alias $TargetDedicated angegeben werden. Entsprechend kann die Variable $TargetLowPriorityNodes mit dem Alias $TargetLowPriority angegeben werden. Wenn sowohl die vollständig benannte Variable als auch ihr Alias durch die Formel festgelegt werden, hat der Wert Vorrang, der der vollständig benannten Variablen zugewiesen ist.

Vom Dienst definierte schreibgeschützte Variablen

Sie können den Wert dieser vom Dienst definierten Variablen abrufen, um Anpassungen basierend auf den Metriken des Batch-Diensts vorzunehmen.

Wichtig

Aufgaben zur Auftragsfreigabe sind derzeit nicht in den Variablen enthalten, die die Aufgabenanzahl angeben, z. B. $ActiveTasks und $PendingTasks. Je nach verwendeter Formel für automatische Skalierung kann dies dazu führen, dass Knoten entfernt werden und keine Knoten mehr verfügbar sind, um die Tasks zur Auftragsfreigabe auszuführen.

Tipp

Die vom Dienst definierten schreibgeschützten Variablen sind Objekte, die verschiedene Methoden für den Zugriff auf die zum jeweiligen Objekt gehörigen Daten bereitstellen. Weitere Informationen finden Sie weiter unten in diesem Artikel unter Abrufen von Beispieldaten.

Variable BESCHREIBUNG
$CPUPercent Die durchschnittliche prozentuale CPU-Auslastung
$WallClockSeconds Die Anzahl der verbrauchten Sekunden Wird nach dem 31. März 2024 eingestellt.
$MemoryBytes Die durchschnittliche Anzahl genutzter Megabyte Wird nach dem 31. März 2024 eingestellt.
$DiskBytes Die durchschnittliche Anzahl der auf den lokalen Datenträgern genutzten Gigabyte Wird nach dem 31. März 2024 eingestellt.
$DiskReadBytes Die Anzahl der gelesenen Bytes. Wird nach dem 31. März 2024 eingestellt.
$DiskWriteBytes Die Anzahl der geschriebenen Byte Wird nach dem 31. März 2024 eingestellt.
$DiskReadOps Die Anzahl der ausgeführten Datenträger-Lesevorgänge Wird nach dem 31. März 2024 eingestellt.
$DiskWriteOps Die Anzahl der ausgeführten Datenträger-Schreibvorgänge Wird nach dem 31. März 2024 eingestellt.
$NetworkInBytes Die Anzahl der eingehenden Byte Wird nach dem 31. März 2024 eingestellt.
$NetworkOutBytes Die Anzahl der ausgehenden Byte Wird nach dem 31. März 2024 eingestellt.
$SampleNodeCount Die Anzahl der Computeknoten Wird nach dem 31. März 2024 eingestellt.
$ActiveTasks Die Anzahl der Aufgaben, die zur Ausführung bereit sind, aber noch nicht ausgeführt werden. Dies umfasst alle Tasks, die sich im aktiven Zustand befinden und deren Abhängigkeiten erfüllt wurden. Alle Aufgaben, die aktiv sind, deren Abhängigkeiten aber nicht erfüllt wurden, werden aus der Anzahl $ActiveTasks ausgeschlossen. Bei einer Aufgabe mit mehreren Instanzen umfasst $ActiveTasks die Anzahl der für die Aufgabe festgelegten Instanzen.
$RunningTasks Die Anzahl der Aufgaben, die sich in einem Ausführungszustand befinden
$PendingTasks Die Summe von $ActiveTasks und $RunningTasks.
$SucceededTasks Die Anzahl der Aufgaben, die erfolgreich abgeschlossen wurden
$FailedTasks Die Anzahl der Aufgaben, bei denen Fehler aufgetreten sind
$TaskSlotsPerNode Die Anzahl von Taskslots, die verwendet werden können, um gleichzeitige Tasks auf einem einzelnen Computeknoten im Pool auszuführen.
$CurrentDedicatedNodes Die aktuelle Anzahl der zugewiesenen Computeknoten
$CurrentLowPriorityNodes Die aktuelle Anzahl von Spot-Computeknoten, einschließlich aller vorzeitigen Knoten.
$UsableNodeCount Die Anzahl der verwendbaren Serverknoten.
$PreemptedNodeCount Die Anzahl der Knoten im Pool, die sich im Zustand „Vorzeitig entfernt“ befinden.

Warnung

Ausgewählte dienstdefinierte Variablen werden nach dem 31. März 2024 eingestellt, wie in der obigen Tabelle angegeben. Nach dem Einstellungsdatum werden diese vom Dienst definierten Variablen nicht mehr mit Beispieldaten aufgefüllt. Bitte stellen Sie die Verwendung dieser Variablen vor diesem Datum ein.

Hinweis

Verwenden Sie $RunningTasks, wenn die Skalierung auf der Anzahl der zu einem Zeitpunkt aktiven Tasks basiert, und $ActiveTasks, wenn die Skalierung auf der Anzahl der Tasks basiert, die in die Warteschlange gestellt werden.

Typen

Formeln für automatische Skalierung unterstützen die folgenden Typen:

  • double
  • doubleVec
  • doubleVecList
  • Zeichenfolge
  • timestamp: eine Verbundstruktur, die die folgenden Member enthält:
    • year
    • Monat (1-12)
    • Tag (1-31)
    • Wochentag (im Zahlenformat; Beispiel: 1 für Montag)
    • Stunde (im 24-Stunden-Zahlenformat; Beispiel: 13 steht für 13 Uhr)
    • Minute (00-59)
    • Sekunde (00-59)
  • timeInterval
    • TimeInterval_Zero
    • TimeInterval_100ns
    • TimeInterval_Microsecond
    • TimeInterval_Millisecond
    • TimeInterval_Second
    • TimeInterval_Minute
    • TimeInterval_Hour
    • TimeInterval_Day
    • TimeInterval_Week
    • TimeInterval_Year

Operationen (Operations)

Für die im vorherigen Abschnitt aufgeführten Typen sind folgende Vorgänge zulässig.

Vorgang Unterstützte Operatoren Ergebnistyp
double Operator double +, -, *, / double
double Operator timeinterval * timeInterval
doubleVec Operator double +, -, *, / doubleVec
doubleVec Operator doubleVec +, -, *, / doubleVec
timeinterval Operator double *, / timeInterval
timeinterval Operator timeinterval +, - timeInterval
timeinterval Operator timestamp + timestamp
timestamp Operator timeinterval + timestamp
timestamp Operator timestamp - timeInterval
Operator double -, ! double
Operator timeinterval - timeInterval
double Operator double <, <=, ==, >=, >, != double
string Operator string <, <=, ==, >=, >, != double
timestamp Operator timestamp <, <=, ==, >=, >, != double
timeinterval Operator timeinterval <, <=, ==, >=, >, != double
double Operator double &&, || double

Das Testen eines Double mit einem ternären Operator (double ? statement1 : statement2) führt dazu, dass „ungleich null” als true und „null” als false angezeigt werden.

Functions

Sie können diese vordefinierten Funktionen verwenden, wenn Sie eine Formel für automatische Skalierung definieren.

Funktion Rückgabetyp BESCHREIBUNG
avg(doubleVecList) double Der Durchschnittswert aller Werte in der doubleVecList wird zurückgegeben.
ceil(double) double Gibt den kleinsten Integerwert zurück, der nicht kleiner als der double-Wert ist.
ceil(doubleVecList) doubleVec Gibt den komponentenbezogenen ceil-Wert von doubleVecList zurück.
floor(double) double Gibt den größten Integerwert zurück, der nicht größer als der double-Wert ist.
floor(doubleVecList) doubleVec Gibt den komponentenbezogenen floor-Wert von doubleVecList zurück.
len(doubleVecList) double Die Länge des Vektors, der aus der doubleVecList erstellt wurde, wird zurückgegeben.
lg(double) double Gibt für den double-Wert den Logarithmus zur Basis 2 zurück.
lg(doubleVecList) doubleVec Gibt den komponentenbezogenen lg-Wert von doubleVecList zurück.
ln(double) double Gibt für den double-Wert den natürlichen Logarithmus zurück.
ln(doubleVecList) doubleVec Gibt den komponentenbezogenen ln-Wert von doubleVecList zurück.
log(double) double Gibt für den double-Wert den Logarithmus zur Basis 10 zurück.
log(doubleVecList) doubleVec Gibt den komponentenbezogenen log-Wert von doubleVecList zurück.
max(doubleVecList) double Der maximale Wert in der doubleVecList wird zurückgegeben.
min(doubleVecList) double Der minimale Wert in der doubleVecList wird zurückgegeben.
norm(doubleVecList) double Die Zweiernorm des Vektors, der aus der doubleVecList erstellt wurde, wird zurückgegeben.
percentile(doubleVec v, double p) double Das Perzentil-Element des Vektors v wird zurückgegeben.
rand() double Ein Zufallswert zwischen 0,0 und 1,0 wird zurückgegeben.
range(doubleVecList) double Der Unterschied zwischen dem Minimal- und Maximalwert in doubleVecList wird zurückgegeben.
round(double) double Gibt den dem double-Wert am nächsten liegenden Integerwert (im Gleitkommaformat) zurück und rundet dabei halbe Werte auf.
round(doubleVecList) doubleVec Gibt den komponentenbezogenen round-Wert von doubleVecList zurück.
std(doubleVecList) double Die Stichproben-Standardabweichung der Werte in der doubleVecList wird zurückgegeben.
stop() Beendet die Auswertung des Ausdrucks für die automatische Skalierung.
sum(doubleVecList) double Die Summe aller Komponenten von doubleVecList wird zurückgegeben.
time(string dateTime="") timestamp Es werden entweder der Zeitstempel der aktuellen Zeit zurückgegeben, wenn keine Parameter übergeben werden, oder andernfalls der Zeitstempel der dateTime-Zeichenfolge, wenn diese übergeben wird. Unterstützte DateTime-Formate sind W3C-DTF und RFC 1123.
val(doubleVec v, double i) double Der Wert des Elements an Position i im Vektor v mit einem Anfangsindex von 0 wird zurückgegeben.

Einige der in der vorherigen Tabelle beschriebenen Funktionen akzeptieren eine Liste als Argument. Bei der durch Trennzeichen getrennten Liste handelt es sich um eine beliebige Kombination aus double und doubleVec. Beispiel:

doubleVecList := ( (double | doubleVec)+(, (double | doubleVec) )* )?

Der doubleVecList-Wert wird vor der Auswertung in einen einzelnen doubleVec konvertiert. Zum Beispiel hat bei v = [1,2,3] das Aufrufen von avg(v) den gleichen Effekt wie das Aufrufen von avg(1,2,3). Das Aufrufen von avg(v, 7) entspricht dem Aufrufen von avg(1,2,3,7).

Metriken

Beim Definieren einer Formel können Sie sowohl Ressourcenmetriken als auch Aufgabenmetriken verwenden. Sie passen die vorgegebene Anzahl dedizierter Knoten im Pool basierend auf den Metrikdaten an, die Sie abrufen und auswerten. Weitere Informationen zu den einzelnen Metriken finden Sie im Abschnitt Variablen.

Metrik BESCHREIBUNG
Resource Ressourcenmetriken basieren auf der CPU-Auslastung, der Bandbreite und Speicherauslastung der Computeknoten sowie auf der Anzahl der Knoten.

Folgende vom Dienst definierte Variablen eignen sich für Anpassungen auf der Grundlage der Knotenanzahl:
- $TargetDedicatedNodes
- $TargetLowPriorityNodes
- $CurrentDedicatedNodes
- $CurrentLowPriorityNodes
- $PreemptedNodeCount
- $UsableNodeCount

Folgende vom Dienst definierte Variablen eignen sich für Anpassungen auf der Grundlage der Ressourcenverwendung von Knoten:
- $CPUPercent
- $WallClockSeconds
- $MemoryBytes
- $DiskBytes
- $DiskReadBytes
- $DiskWriteBytes
- $DiskReadOps
- $DiskWriteOps
- $NetworkInBytes
- $NetworkOutBytes
Aufgabe Aufgabenmetriken basieren auf dem Aufgabenstatus (z.B. „Aktiv“, „Ausstehend“ oder „Abgeschlossen“). Folgende vom Dienst definierte Variablen eignen sich für Poolgrößenanpassungen auf der Grundlage von Aufgabenmetriken:
- $ActiveTasks
- $RunningTasks
- $PendingTasks
- $SucceededTasks
- $FailedTasks

Abrufen von Beispieldaten

Die wichtigste Funktion einer Autoskalierungsformel ist das Abrufen von Metrikdaten zu Aufgaben und Ressourcen (Stichproben) sowie das anschließende Anpassen der Poolgröße basierend auf diesen Daten. Daher ist es wichtig, sich damit vertraut zu machen, wie Formeln für automatische Skalierung mit Stichproben interagieren.

Methoden

Die Formeln für automatische Skalierung greifen auf Stichproben von Metrikdaten zurück, die vom Batch-Dienst bereitgestellt werden. Eine Formel vergrößert oder verkleinert den Pool der Serverknoten basierend auf den Werten, die sie vom Dienst erhält. Vom Dienst definierte Variablen sind Objekte, die Methoden für den Zugriff auf die zum jeweiligen Objekt gehörigen Daten bereitstellen. Der folgende Ausdruck zeigt z. B. eine Anforderung zum Abrufen der letzten fünf Minuten der CPU-Auslastung:

$CPUPercent.GetSample(TimeInterval_Minute * 5)

Die folgenden Methoden können zum Abrufen von Stichprobendaten zu vom Dienst definierten Variablen verwendet werden.

Methode BESCHREIBUNG
GetSample() Die GetSample()-Methode gibt einen Vektor aus Stichprobenwerten zurück.

Eine Stichprobe enthält Metrikdaten, die innerhalb von 30 Sekunden erfasst wurden. Dies bedeutet, dass alle 30 Sekunden eine Stichprobe genommen wird. Wie nachstehend erwähnt, gibt es eine Verzögerung zwischen dem Zeitpunkt der Erfassung der Stichprobe und ihrer Verfügbarkeit für eine Formel. Daher stehen möglicherweise nicht alle Stichproben für einen bestimmten Zeitraum für die Bewertung durch eine Formel zur Verfügung.

- doubleVec GetSample(double count): Gibt die Anzahl von Stichproben an, die aus den letzten erfassten Stichproben abgerufen werden sollen. GetSample(1) gibt die neueste verfügbare Stichprobe zurück. Für Metriken wie $CPUPercent sollte GetSample(1) allerdings nicht verwendet werden, da unmöglich feststellbar ist, wann die Stichprobe erfasst wurde. Sie kann aktuell oder aufgrund von Systemproblemen auch wesentlich älter sein. In solchen Fällen ist es besser, wie unten gezeigt ein Zeitintervall zu verwenden.

- doubleVec GetSample((timestamp or timeinterval) startTime [, double samplePercent]): Gibt einen Zeitrahmen für die Erfassung von Stichprobendaten an. Optional gibt diese Methode auch den Prozentsatz der Stichproben an, die im angeforderten Zeitraum verfügbar sein müssen. Beispielsweise gibt $CPUPercent.GetSample(TimeInterval_Minute * 10) 20 Stichproben zurück, wenn alle Stichproben der letzten 10 Minuten im CPUPercent-Verlauf vorhanden sind. Wenn die letzte Minute des Verlaufs nicht verfügbar ist, werden nur 18 Stichproben zurückgegeben. In diesem Fall tritt für $CPUPercent.GetSample(TimeInterval_Minute * 10, 95) ein Fehler auf, da nur 90 Prozent der Stichproben verfügbar sind, $CPUPercent.GetSample(TimeInterval_Minute * 10, 80) wäre jedoch erfolgreich.

- doubleVec GetSample((timestamp or timeinterval) startTime, (timestamp or timeinterval) endTime [, double samplePercent]): Gibt einen Zeitrahmen für die Datenerfassung mit einer Start- und einer Endzeit an. Wie bereits erwähnt, gibt es eine Verzögerung zwischen dem Zeitpunkt der Erfassung der Stichprobe und ihrer Verfügbarkeit für eine Formel. Berücksichtigen Sie diese Verzögerung, wenn Sie die Methode GetSample verwenden. Weitere Informationen finden Sie bei GetSamplePercent weiter unten.
GetSamplePeriod() Gibt den Zeitraum zurück, in dem die Stichproben aus einem alten Stichproben-Dataset gesammelt wurden.
Count() Gibt die Gesamtzahl von Stichproben im Metrikverlauf zurück.
HistoryBeginTime() Gibt den Zeitstempel des ältesten verfügbaren Stichprobenwerts für die Metrik zurück.
GetSamplePercent() Gibt den Prozentsatz an Stichprobenwerten zurück, die für ein bestimmtes Intervall verfügbar sind. Beispiel: doubleVec GetSamplePercent( (timestamp or timeinterval) startTime [, (timestamp or timeinterval) endTime] ). Da die GetSample-Methode einen Fehler erzeugt, wenn der Prozentsatz der zurückgegebenen Stichproben kleiner als der angegebene samplePercent-Wert ist, können Sie vorab mithilfe der GetSamplePercent-Methode eine Prüfung vornehmen. Wenn nicht genügend Beispiele vorhanden sind, können Sie anschließend eine andere Aktion ausführen, , ohne die Auswertung der automatischen Skalierung zu unterbrechen.

Beispiele

Der Batch-Dienst nimmt regelmäßig Stichproben von Task- und Ressourcenmetriken und stellt sie Ihren Formeln für die automatische Skalierung zur Verfügung. Diese Stichproben werden alle 30 Sekunden vom Batch-Dienst aufgezeichnet. Allerdings kommt es meist zu einer Verzögerung zwischen dem Zeitpunkt der Erfassung der Stichproben und dem Zeitpunkt, zu dem sie den Formeln für die automatische Skalierung zur Verfügung gestellt (und von diesen gelesen) werden können. Darüber hinaus können Stichproben aufgrund von Faktoren wie Netzwerk- oder anderen Infrastrukturproblemen für ein bestimmtes Intervall möglicherweise nicht aufgezeichnet werden.

Prozentsatz für die Stichprobe

Beim Übergeben eines samplePercent-Werts an die GetSample()-Methode oder Aufrufen der GetSamplePercent()-Methode bezieht sich Percent auf einen Vergleich zwischen der möglichen Gesamtzahl der vom Batch-Dienst erfassten Stichproben und der Anzahl von Stichproben, die für Ihre Formel für die Autoskalierung verfügbar sind.

Sehen wir uns als Beispiel eine Zeitspanne von 10 Minuten an. Da Stichproben innerhalb dieser Zeitspanne von 10 Minuten alle 30 Sekunden erfasst werden, werden maximal 20 Stichproben von Batch erfasst (2 pro Minute). Aufgrund der inhärenten Latenz des Berichterstellungsmechanismus und anderer Probleme in Azure stehen Ihrer Autoskalierungsformel jedoch möglicherweise nur 15 Stichproben zur Verfügung. Das bedeutet, dass in diesem 10-Minuten-Zeitraum möglicherweise nur 75 % aller erfassten Stichproben für Ihre Formel verfügbar sind.

GetSample() und Stichprobenbereiche

Ihre Autoskalierungsformeln vergrößern und verkleinern Ihre Pools durch Hinzufügen oder Entfernen von Knoten. Da Knoten Geld kosten, müssen Sie sicherstellen, dass Ihre Formeln eine sinnvolle Analysemethode verwenden, die auf einer ausreichenden Menge von Daten basiert. Es empfiehlt sich, in Ihren Formeln eine Form von Trendanalyse zu verwenden. Dieser Typ vergrößert oder verkleinert Ihre Pools basierend auf einem Bereich gesammelter Stichproben.

Verwenden Sie hierzu GetSample(interval look-back start, interval look-back end), um einen Vektor von Stichproben zurückzugeben:

$runningTasksSample = $RunningTasks.GetSample(1 * TimeInterval_Minute, 6 * TimeInterval_Minute);

Wenn die obige Zeile von Batch ausgewertet wird, wird ein Bereich von Stichproben als Vektor von Werten zurückgegeben. Beispiel:

$runningTasksSample=[1,1,1,1,1,1,1,1,1,1];

Nachdem Sie den Stichprobenvektor erfasst haben, können Sie Funktionen wie min(), max() und avg() verwenden, um aussagekräftige Werte aus dem erfassten Bereich abzuleiten.

Zur Erhöhung der Sicherheit können Sie einen Fehler bei der Formelauswertung erzwingen, wenn für einen bestimmten Zeitraum weniger als ein festgelegter Prozentsatz von Stichproben verfügbar ist. Mit dem Erzwingen eines Fehlers bei der Formelauswertung weisen Sie Batch an, die weitere Auswertung der Formel zu beenden, sofern der angegebene Prozentsatz von Stichproben nicht zur Verfügung steht. An der Größe des Pools erfolgt dann keinerlei Änderung. Wenn Sie einen erforderlichen Prozentsatz von Stichproben angeben möchten, damit die Auswertung Erfolg hat, geben Sie diesen in GetSample() als dritten Parameter an. Hier wird ein Mindestprozentsatz von 75 % angegeben:

$runningTasksSample = $RunningTasks.GetSample(60 * TimeInterval_Second, 120 * TimeInterval_Second, 75);

Da Stichproben möglicherweise nur verzögert verfügbar sind, sollten Sie stets einen Zeitbereich mit einer Startzeit angeben, die mehr als eine Minute zurückliegt. Es dauert ca. eine Minute, bis Stichproben das System durchlaufen haben, daher sind Stichproben im Bereich (0 * TimeInterval_Second, 60 * TimeInterval_Second) möglicherweise nicht verfügbar. In diesem Fall können Sie den Prozentsatzparameter GetSample() angeben, um einen bestimmten Prozentsatz von Stichproben zu erzwingen.

Wichtig

Es wird dringend empfohlen, sich in den Formeln für die automatische Skalierung nicht ausschließlich auf GetSample(1) zu verlassen. Der Grund ist, dass GetSample(1) im Wesentlichen den Batch-Dienst anweist, die letzte vorhandene Stichprobe unabhängig vom Zeitpunkt ihrer Erfassung bereitzustellen. Da es sich nur um ein Stichprobe handelt, die ggf. schon älter ist, ist diese möglicherweise nicht für den aktuellen Aufgaben- oder Ressourcenstatus repräsentativ. Stellen Sie bei Verwendung von GetSample(1) sicher, dass dieser Wert zu einer längeren Anweisung gehört und nicht der einzige Datenpunkt ist, auf dem Ihre Formel basiert.

Schreiben einer Formel für die automatische Skalierung

Sie können eine Formel für die automatische Skalierung erstellen, indem Sie mithilfe der oben aufgeführten Komponenten Anweisungen formulieren und diese dann zu einer vollständigen Formel kombinieren. In diesem Abschnitt erstellen Sie eine Beispielformel für die Autoskalierung, mit der sich praxistaugliche Skalierungsentscheidungen treffen und Anpassungen vornehmen lassen.

Zuerst definieren wir die Anforderungen für die neue Formel für die automatische Skalierung. Mit der Formel soll Folgendes erreicht werden:

  • Die dedizierte Anzahl von Computeknoten in einem Pool soll erhöht werden, wenn die CPU-Auslastung hoch ist.
  • Die dedizierte Anzahl von Computeknoten in einem Pool soll reduziert werden, wenn die CPU-Auslastung gering ist.
  • Die maximale Anzahl dedizierter Knoten muss immer auf 400 beschränkt sein.
  • Wenn Sie die Anzahl der Knoten reduzieren, entfernen Sie keine Knoten, die Tasks ausführen. Warten Sie ggf., bis die Tasks abgeschlossen sind, bevor Sie Knoten entfernen.

Die erste Anweisung in der Formel erhöht die Anzahl der Knoten bei hoher CPU-Auslastung. Sie definieren eine Anweisung, die eine benutzerdefinierte Variable ($totalDedicatedNodes) mit einem Wert auffüllt, der 110 Prozent der aktuellen Zielanzahl dedizierter Knoten darstellt. Dies gilt aber nur, wenn die durchschnittliche CPU-Mindestauslastung in den letzten 10 Minuten über 70 Prozent lag. Andernfalls wird der Wert für die aktuelle Anzahl dedizierter Knoten verwendet.

$totalDedicatedNodes =
    (min($CPUPercent.GetSample(TimeInterval_Minute * 10)) > 0.7) ?
    ($CurrentDedicatedNodes * 1.1) : $CurrentDedicatedNodes;

Um die Anzahl dedizierter Knoten bei geringer CPU-Auslastung zu reduzieren, legt die nächste Anweisung in der Formel dieselbe Variable $totalDedicatedNodes auf 90 Prozent der aktuellen Zielanzahl dedizierter Knoten fest, wenn die durchschnittliche CPU-Auslastung in den letzten 60 Minuten unter 20 Prozent lag. Andernfalls wird der aktuelle Wert von $totalDedicatedNodes verwendet, der oben in der Anweisung aufgefüllt wurde.

$totalDedicatedNodes =
    (avg($CPUPercent.GetSample(TimeInterval_Minute * 60)) < 0.2) ?
    ($CurrentDedicatedNodes * 0.9) : $totalDedicatedNodes;

Begrenzen Sie jetzt die Zielanzahl dedizierter Serverknoten auf maximal 400.

$TargetDedicatedNodes = min(400, $totalDedicatedNodes);

Schließlich stellen Sie sicher, dass Knoten erst entfernt werden, wenn ihre Aufgaben abgeschlossen sind.

$NodeDeallocationOption = taskcompletion;

Die vollständige Formel lautet:

$totalDedicatedNodes =
    (min($CPUPercent.GetSample(TimeInterval_Minute * 10)) > 0.7) ?
    ($CurrentDedicatedNodes * 1.1) : $CurrentDedicatedNodes;
$totalDedicatedNodes =
    (avg($CPUPercent.GetSample(TimeInterval_Minute * 60)) < 0.2) ?
    ($CurrentDedicatedNodes * 0.9) : $totalDedicatedNodes;
$TargetDedicatedNodes = min(400, $totalDedicatedNodes);
$NodeDeallocationOption = taskcompletion;

Hinweis

Wenn Sie möchten, können Sie in Formelzeichenfolgen sowohl Kommentare als auch Zeilenumbrüche verwenden. Beachten Sie auch, dass fehlende Semikolons zu Auswertungsfehlern führen können.

Intervall für die automatische Skalierung

Standardmäßig passt der Batch-Dienst alle 15 Minuten die Poolgröße gemäß seiner Formel für die automatische Skalierung an. Dieses Intervall kann mithilfe der folgenden Pooleigenschaften konfiguriert werden:

Das kürzeste Intervall ist fünf Minuten, das längste 168 Stunden. Wenn ein Intervall außerhalb dieses Bereichs angegeben wird, gibt der Batch-Dienst einen Fehler des Typs „Unzulässige Anforderung (400)“ zurück.

Hinweis

Die automatische Skalierung ist derzeit nicht als Reaktion im Zeitraum unter einer Minute auf Änderungen vorgesehen, sondern dient eher zum allmählichen Anpassen der Größe Ihres Pools während der Ausführung Ihres Workloads.

Erstellen eines Pools mit aktivierter Autoskalierung mit Batch SDKs

Die automatische Skalierung für Pools kann mit einem der Batch SDKs, den Batch-PowerShell-Cmdlets der Batch REST-API und der Batch-CLI konfiguriert werden. In diesem Abschnitt sehen Sie Beispiele sowohl für .NET als auch für Python.

.NET

Gehen Sie wie folgt vor, um einen Pool mit automatischer Skalierung in .NET zu erstellen:

  1. Erstellen Sie den Pool mit BatchClient.PoolOperations.CreatePool.
  2. Legen Sie die Eigenschaft CloudPool.AutoScaleEnabled auf true fest.
  3. Legen Sie die CloudPool.AutoScaleFormula-Eigenschaft mit Ihrer Formel für die automatische Skalierung fest.
  4. (Optional) Legen Sie die CloudPool.AutoScaleEvaluationInterval-Eigenschaft fest (Standardeinstellung ist 15 Minuten).
  5. Führen Sie für den Pool mit CloudPool.Commit oder CommitAsync einen Commit durch.

Mit dem folgenden Beispiel wird ein Pool mit aktivierter automatischer Skalierung in .NET erstellt. Die Formel für automatische Skalierung des Pools legt die vorgegebene Anzahl dedizierter Knoten auf 5 am Montag und auf 1 an allen anderen Wochentagen fest. Das Intervall für die automatische Skalierung wird auf 30 Minuten festgelegt. In diesem und anderen C#-Codeausschnitten in diesem Artikel ist myBatchClient eine ordnungsgemäß initialisierte Instanz der Klasse BatchClient.

CloudPool pool = myBatchClient.PoolOperations.CreatePool(
                    poolId: "mypool",
                    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.AutoScaleEnabled = true;
pool.AutoScaleFormula = "$TargetDedicatedNodes = (time().weekday == 1 ? 5:1);";
pool.AutoScaleEvaluationInterval = TimeSpan.FromMinutes(30);
await pool.CommitAsync();

Wichtig

Wenn Sie einen Pool mit aktivierter automatischer Skalierung erstellen, geben Sie beim Aufruf von CreatePool nicht den Parameter targetDedicatedNodes oder den Parameter targetLowPriorityNodes an. Geben Sie stattdessen die Eigenschaften AutoScaleEnabled und AutoScaleFormula im Pool an. Die Werte für diese Eigenschaften bestimmen die Zielanzahl der einzelnen Knotentypen.

Sie müssen zur manuellen Anpassung der Größe eines Pools mit aktivierter automatischer Skalierung (etwa mit BatchClient.PoolOperations.ResizePool) zunächst die automatische Skalierung im Pool deaktivieren, um anschließend die Größe des Pools ändern zu können.

Tipp

Weitere Beispiele für die Verwendung des .NET SDK finden Sie im Repository zur Batch-.NET-Schnellstartanleitung in GitHub.

Python

So erstellen Sie einen Pool mit aktivierter Autoskalierung mit dem Python SDK:

  1. Erstellen Sie einen Pool, und geben Sie die Konfiguration an.
  2. Fügen Sie den Pool dem Dienstclient hinzu.
  3. Aktivieren Sie die Autoskalierung im Pool mit einer von Ihnen erstellten Formel.

Diese Schritte werden im folgenden Beispiel veranschaulicht.

# Create a pool; specify configuration
new_pool = batch.models.PoolAddParameter(
    id="autoscale-enabled-pool",
    virtual_machine_configuration=batchmodels.VirtualMachineConfiguration(
        image_reference=batchmodels.ImageReference(
          publisher="Canonical",
          offer="UbuntuServer",
          sku="20.04-LTS",
          version="latest"
            ),
        node_agent_sku_id="batch.node.ubuntu 20.04"),
    vm_size="STANDARD_D1_v2",
    target_dedicated_nodes=0,
    target_low_priority_nodes=0
)
batch_service_client.pool.add(new_pool) # Add the pool to the service client

formula = """$curTime = time();
             $workHours = $curTime.hour >= 8 && $curTime.hour < 18;
             $isWeekday = $curTime.weekday >= 1 && $curTime.weekday <= 5;
             $isWorkingWeekdayHour = $workHours && $isWeekday;
             $TargetDedicated = $isWorkingWeekdayHour ? 20:10;""";

# Enable autoscale; specify the formula
response = batch_service_client.pool.enable_auto_scale(pool_id, auto_scale_formula=formula,
                                            auto_scale_evaluation_interval=datetime.timedelta(minutes=10),
                                            pool_enable_auto_scale_options=None,
                                            custom_headers=None, raw=False)

Tipp

Weitere Beispiele für die Verwendung des Python SDK finden Sie im Repository zur Batch-Python-Schnellstartanleitung in GitHub.

Aktivieren der automatischen Skalierung für einen vorhandenen Pool

Jedes Batch-SDK bietet eine Möglichkeit für die Aktivierung der automatischen Skalierung. Beispiel:

Beachten Sie Folgendes, wenn Sie automatische Skalierung für einen vorhandenen Pool aktivieren:

  • Falls automatische Skalierung für den Pool derzeit deaktiviert ist, müssen Sie eine gültige Formel für automatische Skalierung angeben, wenn Sie die Anforderung ausgeben. Sie können optional ein Intervall für automatische Skalierung angeben. Wenn Sie kein Intervall angeben, wird der Standardwert von 15 Minuten verwendet.
  • Wenn automatische Skalierung für den Pool derzeit aktiviert ist, können Sie eine neue Formel, ein neues Intervall oder beides angeben. Sie müssen mindestens eine dieser Eigenschaften angeben.
    • Wenn Sie ein neues Intervall für automatische Skalierung angeben, wird der vorhandene Zeitplan beendet und ein neuer Zeitplan gestartet. Die Startzeit des neuen Zeitplans ist der Zeitpunkt, zu dem die Anforderung zur Aktivierung der automatischen Skalierung ausgegeben wurde.
    • Wenn Sie die Formel oder das Intervall für die Autoskalierung auslassen, nutzt der Batch-Dienst weiterhin den aktuellen Wert dieser Einstellung.

Hinweis

Wenn Sie bei der Erstellung des Pools in .NET oder für vergleichbare Parameter in einer anderen Sprache Werte für den Parameter targetDedicatedNodes oder targetLowPriorityNodes der CreatePool-Methode angegeben haben, werden diese Werte bei der Auswertung der Formel für automatische Skalierung ignoriert.

In diesem C#-Beispiel wird die Batch .NET-Bibliothek verwendet, um automatische Skalierung in einem vorhandenen Pool zu aktivieren.

// Define the autoscaling formula. This formula sets the target number of nodes
// to 5 on Mondays, and 1 on every other day of the week
string myAutoScaleFormula = "$TargetDedicatedNodes = (time().weekday == 1 ? 5:1);";

// Set the autoscale formula on the existing pool
await myBatchClient.PoolOperations.EnableAutoScaleAsync(
    "myexistingpool",
    autoscaleFormula: myAutoScaleFormula);

Aktualisieren einer Formel für die automatische Skalierung

Zur Aktualisierung der Formel für einen vorhandenen Pool mit aktivierter automatischer Skalierung müssen Sie den Vorgang zur Aktivierung der automatischen Skalierung mit der neuen Formel erneut aufrufen. Wenn die automatische Skalierung für myexistingpool beispielsweise bereits aktiviert ist, wird die Formel für die automatische Skalierung beim Ausführen des folgenden .NET-Codes durch den Inhalt von myNewFormula ersetzt.

await myBatchClient.PoolOperations.EnableAutoScaleAsync(
    "myexistingpool",
    autoscaleFormula: myNewFormula);

Aktualisieren des Intervalls für die automatische Skalierung

Zur Aktualisierung des Auswertungsintervalls der automatischen Skalierung für einen vorhandenen Pool mit aktivierter automatischer Skalierung müssen Sie den Vorgang zur Aktivierung der automatischen Skalierung mit dem neuen Intervall erneut aufrufen. Gehen Sie beispielsweise wie folgt vor, um das Auswertungsintervall für die automatische Skalierung für einen Pool, der in .NET bereits entsprechend aktiviert wurde, auf 60 Minuten festzulegen:

await myBatchClient.PoolOperations.EnableAutoScaleAsync(
    "myexistingpool",
    autoscaleEvaluationInterval: TimeSpan.FromMinutes(60));

Erstellen einer autoscale-Formel

Sie können eine Formel auswerten, bevor Sie sie auf einen Pool anwenden. Auf diese Weise können Sie die Ergebnisse der Formel testen, bevor Sie sie in der Produktion einsetzen.

Bevor Sie eine Formel für automatische Skalierung auswerten können, müssen Sie zunächst automatische Skalierung für den Pool mit einer gültigen Formel aktivieren, z. B. mit der einzeiligen Formel $TargetDedicatedNodes = 0. Verwenden Sie anschließend eines der folgenden Verfahren, um die zu testende Formel auszuwerten:

Das folgende Batch .NET-Beispiel wertet eine Formel für die Autoskalierung aus. Wenn der Pool die Autoskalierung noch nicht verwendet, aktivieren Sie diese zuerst.

// First obtain a reference to an existing pool
CloudPool pool = await batchClient.PoolOperations.GetPoolAsync("myExistingPool");

// If autoscaling isn't already enabled on the pool, enable it.
// You can't evaluate an autoscale formula on a non-autoscale-enabled pool.
if (pool.AutoScaleEnabled == false)
{
    // You need a valid autoscale formula to enable autoscaling on the
    // pool. This formula is valid, but won't resize the pool:
    await pool.EnableAutoScaleAsync(
        autoscaleFormula: "$TargetDedicatedNodes = $CurrentDedicatedNodes;",
        autoscaleEvaluationInterval: TimeSpan.FromMinutes(5));

    // Batch limits EnableAutoScaleAsync calls to once every 30 seconds.
    // Because you want to apply our new autoscale formula below if it
    // evaluates successfully, and you *just* enabled autoscaling on
    // this pool, pause here to ensure you pass that threshold.
    Thread.Sleep(TimeSpan.FromSeconds(31));

    // Refresh the properties of the pool so that we've got the
    // latest value for AutoScaleEnabled
    await pool.RefreshAsync();
}

// You must ensure that autoscaling is enabled on the pool prior to
// evaluating a formula
if (pool.AutoScaleEnabled == true)
{
    // The formula to evaluate - adjusts target number of nodes based on
    // day of week and time of day
    string myFormula = @"
        $curTime = time();
        $workHours = $curTime.hour >= 8 && $curTime.hour < 18;
        $isWeekday = $curTime.weekday >= 1 && $curTime.weekday <= 5;
        $isWorkingWeekdayHour = $workHours && $isWeekday;
        $TargetDedicatedNodes = $isWorkingWeekdayHour ? 20:10;
    ";

    // Perform the autoscale formula evaluation. Note that this code does not
    // actually apply the formula to the pool.
    AutoScaleRun eval =
        await batchClient.PoolOperations.EvaluateAutoScaleAsync(pool.Id, myFormula);

    if (eval.Error == null)
    {
        // Evaluation success - print the results of the AutoScaleRun.
        // This will display the values of each variable as evaluated by the
        // autoscale formula.
        Console.WriteLine("AutoScaleRun.Results: " +
            eval.Results.Replace("$", "\n    $"));

        // Apply the formula to the pool since it evaluated successfully
        await batchClient.PoolOperations.EnableAutoScaleAsync(pool.Id, myFormula);
    }
    else
    {
        // Evaluation failed, output the message associated with the error
        Console.WriteLine("AutoScaleRun.Error.Message: " +
            eval.Error.Message);
    }
}

Eine erfolgreiche Auswertung der Formel, die in diesem Codeausschnitt angezeigt wird, führt zu Ergebnissen, die etwa wie folgt aussehen:

AutoScaleRun.Results:
    $TargetDedicatedNodes=10;
    $NodeDeallocationOption=requeue;
    $curTime=2016-10-13T19:18:47.805Z;
    $isWeekday=1;
    $isWorkingWeekdayHour=0;
    $workHours=0

Abrufen von Informationen zu Ausführungen der automatischen Skalierung

Es wird empfohlen, die Auswertung Ihrer Formel für die Autoskalierung durch den Batch-Dienst in regelmäßigen Abständen zu überprüfen. Rufen Sie hierzu einen Verweis auf den Pool auf (oder aktualisieren Sie ihn), und untersuchen Sie dann die Eigenschaften der letzten Ausführung der automatischen Skalierung.

In Batch .NET verfügt die Eigenschaft CloudPool.AutoScaleRun über mehrere Eigenschaften, die Informationen zur letzten Ausführung der automatischen Skalierung für den Pool liefern:

In der REST-API gibt die Anforderung zum Abrufen von Informationen zu einem Pool Informationen zum Pool zurück, z. B. Informationen zur letzten Ausführung der Autoskalierung in der Eigenschaft autoScaleRun.

Im folgenden C#-Beispiel wird die Batch .NET-Bibliothek verwendet, um Informationen zur letzten Ausführung der automatischen Skalierung für den Pool myPool auszugeben.

await Cloud pool = myBatchClient.PoolOperations.GetPoolAsync("myPool");
Console.WriteLine("Last execution: " + pool.AutoScaleRun.Timestamp);
Console.WriteLine("Result:" + pool.AutoScaleRun.Results.Replace("$", "\n  $"));
Console.WriteLine("Error: " + pool.AutoScaleRun.Error);

Die Beispielausgabe aus dem vorherigen Beispiel lautet wie folgt:

Last execution: 10/14/2016 18:36:43
Result:
  $TargetDedicatedNodes=10;
  $NodeDeallocationOption=requeue;
  $curTime=2016-10-14T18:36:43.282Z;
  $isWeekday=1;
  $isWorkingWeekdayHour=0;
  $workHours=0
Error:

Abrufen des Ausführungsverlaufs für die Autoskalierung mithilfe von Ereignissen für die Poolautoskalierung

Sie können den Verlauf für die automatische Skalierung auch abrufen, indem Sie PoolAutoScaleEvent abfragen. Dieses Ereignis wird vom Batch-Dienst ausgegeben, um alle Auswertungen und Ausführungen der Formel für die Autoskalierung aufzuzeichnen. Dies kann bei der Behebung potenzieller Probleme hilfreich sein.

Beispielereignis für PoolAutoScaleEvent:

{
    "id": "poolId",
    "timestamp": "2020-09-21T23:41:36.750Z",
    "formula": "...",
    "results": "$TargetDedicatedNodes=10;$NodeDeallocationOption=requeue;$curTime=2016-10-14T18:36:43.282Z;$isWeekday=1;$isWorkingWeekdayHour=0;$workHours=0",
    "error": {
        "code": "",
        "message": "",
        "values": []
    }
}

Beispiele für autoscale-Formeln

Hier sind einige Formeln angegeben, die verschiedene Möglichkeiten zum Anpassen der Anzahl von Computeressourcen in einem Pool darstellen.

Beispiel 1: Zeitbasierte Anpassung

Angenommen Sie möchten die Poolgröße basierend auf dem Wochentag und der Tageszeit anpassen. Dieses Beispiel zeigt, wie Sie die Knotenanzahl im Pool entsprechend Anzahl zum erhöhen oder verringern.

Die Formel ruft zunächst die aktuelle Uhrzeit ab. Wenn es sich um einen Werktag (1 bis 5) handelt und der Wert innerhalb der Geschäftszeiten (8:00 Uhr bis 18:00 Uhr) liegt, wird die Zielgröße des Pools auf 20 Knoten festgelegt. Andernfalls wird der Wert auf 10 Knoten festgelegt.

$curTime = time();
$workHours = $curTime.hour >= 8 && $curTime.hour < 18;
$isWeekday = $curTime.weekday >= 1 && $curTime.weekday <= 5;
$isWorkingWeekdayHour = $workHours && $isWeekday;
$TargetDedicatedNodes = $isWorkingWeekdayHour ? 20:10;
$NodeDeallocationOption = taskcompletion;

$curTime kann angepasst werden, um Ihre lokale Zeitzone widerzuspiegeln, indem time() zum Produkt aus TimeZoneInterval_Hour und Ihrer UTC-Abweichung hinzugefügt wird. Verwenden Sie z. B. $curTime = time() + (-6 * TimeInterval_Hour); für Mountain Daylight Time (MDT). Denken Sie daran, dass die Abweichung zu Beginn und Ende der Sommerzeit (falls zutreffend) angepasst werden muss.

Beispiel 2: Aufgabenbasierte Anpassung

In diesem C#-Beispiel wird die Größe des Pools basierend auf der Anzahl der Tasks in der Warteschlange angepasst. Die Formelzeichenfolgen enthalten sowohl Kommentare als auch Zeilenumbrüche.

// Get pending tasks for the past 15 minutes.
$samples = $PendingTasks.GetSamplePercent(TimeInterval_Minute * 15);
// If you have fewer than 70 percent data points, use the last sample point,
// otherwise use the maximum of last sample point and the history average.
$tasks = $samples < 70 ? max(0,$PendingTasks.GetSample(1)) : max( $PendingTasks.GetSample(1), avg($PendingTasks.GetSample(TimeInterval_Minute * 15)));
// If number of pending tasks is not 0, set targetVM to pending tasks, otherwise
// half of current dedicated.
$targetVMs = $tasks > 0? $tasks:max(0, $TargetDedicatedNodes/2);
// The pool size is capped at 20, if target VM value is more than that, set it
// to 20. This value should be adjusted according to your use case.
$TargetDedicatedNodes = max(0, min($targetVMs, 20));
// Set node deallocation mode - let running tasks finish before removing a node
$NodeDeallocationOption = taskcompletion;

Beispiel 3: Berücksichtigung paralleler Aufgaben

In diesem C#-Beispiel wird die Poolgröße basierend auf der Anzahl von Tasks angepasst. Diese Formel berücksichtigt auch den für den Pool festgelegten Wert TaskSlotsPerNode. Dieser Ansatz ist besonders hilfreich, wenn in Ihrem Pool die parallele Aufgabenausführung aktiviert wurde.

// Determine whether 70 percent of the samples have been recorded in the past
// 15 minutes; if not, use last sample
$samples = $ActiveTasks.GetSamplePercent(TimeInterval_Minute * 15);
$tasks = $samples < 70 ? max(0,$ActiveTasks.GetSample(1)) : max( $ActiveTasks.GetSample(1),avg($ActiveTasks.GetSample(TimeInterval_Minute * 15)));
// Set the number of nodes to add to one-fourth the number of active tasks
// (the TaskSlotsPerNode property on this pool is set to 4, adjust
// this number for your use case)
$cores = $TargetDedicatedNodes * 4;
$extraVMs = (($tasks - $cores) + 3) / 4;
$targetVMs = ($TargetDedicatedNodes + $extraVMs);
// Attempt to grow the number of compute nodes to match the number of active
// tasks, with a maximum of 3
$TargetDedicatedNodes = max(0,min($targetVMs,3));
// Keep the nodes active until the tasks finish
$NodeDeallocationOption = taskcompletion;

Beispiel 4: Festlegen einer anfänglichen Poolgröße

Dieses Beispiel zeigt einen C#-Beispiel mit einer Formel für automatische Skalierung, welche die Größe des Pools für einen anfänglichen Zeitraum auf eine angegebene Anzahl von Knoten festlegt. Danach wird die Poolgröße auf der Grundlage der Anzahl der aktuell ausgeführten und aktiven Tasks angepasst.

Diese Formel führt die folgenden Aufgaben aus:

  • Die anfängliche Poolgröße wird auf 4 Knoten festgelegt.
  • Die Größe des Pools wird innerhalb der ersten 10 Minuten des Lebenszyklus des Pools nicht angepasst.
  • Nach 10 Minuten wird die maximale Anzahl ausgeführter und aktiver Aufgaben in den letzten 60 Minuten abgerufen.
    • Falls beide Werte 0 sind – was darauf hinweist, dass in den letzten 60 Minuten keine Aufgaben ausgeführt wurden oder aktiv waren –, wird die Poolgröße auf 0 festgelegt.
    • Wenn einer der Werte größer als null ist, erfolgt keine Änderung.
string now = DateTime.UtcNow.ToString("r");
string formula = string.Format(@"
    $TargetDedicatedNodes = {1};
    lifespan         = time() - time(""{0}"");
    span             = TimeInterval_Minute * 60;
    startup          = TimeInterval_Minute * 10;
    ratio            = 50;

    $TargetDedicatedNodes = (lifespan > startup ? (max($RunningTasks.GetSample(span, ratio), $ActiveTasks.GetSample(span, ratio)) == 0 ? 0 : $TargetDedicatedNodes) : {1});
    ", now, 4);

Nächste Schritte