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 $PendingTasks
gezä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 |
$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 |
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:
- CloudPool.AutoScaleEvaluationInterval (Batch .NET)
- autoScaleEvaluationInterval (REST-API)
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:
- Erstellen Sie den Pool mit BatchClient.PoolOperations.CreatePool.
- Legen Sie die Eigenschaft CloudPool.AutoScaleEnabled auf true fest.
- Legen Sie die CloudPool.AutoScaleFormula-Eigenschaft mit Ihrer Formel für die automatische Skalierung fest.
- (Optional) Legen Sie die CloudPool.AutoScaleEvaluationInterval-Eigenschaft fest (Standardeinstellung ist 15 Minuten).
- 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:
- Erstellen Sie einen Pool, und geben Sie die Konfiguration an.
- Fügen Sie den Pool dem Dienstclient hinzu.
- 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:
- BatchClient.PoolOperations.EnableAutoScaleAsync (Batch .NET)
- Aktivieren des automatischen Skalierens für einen Pool (REST-API)
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:
BatchClient.PoolOperations.EvaluateAutoScale oder EvaluateAutoScaleAsync
Für diese Batch .NET-Methoden sind die ID eines vorhandenen Pools und eine Zeichenfolge mit der auszuwertenden autoscale-Formel erforderlich.
Auswerten einer Formel für die automatische Skalierung
Geben Sie in dieser REST-API-Anforderung die Pool-ID im URI und die autoscale-Formel im autoScaleFormula-Element des Anforderungstexts an. Die bei der Anfrage generierte Antwort enthält Fehlerinformationen, die in Zusammenhang mit der Formel stehen können.
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
- Erfahren Sie, wie Sie mehrere Tasks gleichzeitig auf den Computeknoten in Ihrem Pool ausführen. Zusammen mit automatischer Skalierung können Sie mit diesem Feature die Auftragsdauer für einige Workloads verringern und so Geld sparen.
- Erfahren Sie, wie Sie den Azure Batch-Dienst effizient abfragen.