Skapa en automatisk formel för skalning av beräkningsnoder i en Batch-pool

Azure Batch kan automatiskt skala pooler baserat på parametrar som du definierar, vilket sparar tid och pengar. Med automatisk skalning lägger Batch dynamiskt till noder i en pool när uppgiftsbehovet ökar och tar bort beräkningsnoder när uppgiftsbehoven minskar.

Om du vill aktivera automatisk skalning i en pool med beräkningsnoder associerar du poolen med en autoskalningsformel som du definierar. Batch-tjänsten använder autoskalningsformeln för att avgöra hur många noder som behövs för att köra din arbetsbelastning. Dessa noder kan vara dedikerade noder eller Azure Spot-noder. Batch granskar sedan regelbundet tjänstmåttdata och använder dem för att justera antalet noder i poolen baserat på din formel och med ett intervall som du definierar.

Du kan aktivera automatisk skalning när du skapar en pool eller tillämpa den på en befintlig pool. Med Batch kan du utvärdera dina formler innan du tilldelar dem till pooler och övervakar statusen för automatiska skalningskörningar. När du har konfigurerat en pool med automatisk skalning kan du göra ändringar i formeln senare.

Viktigt

När du skapar ett Batch-konto kan du ange poolallokeringsläget, som avgör om pooler allokeras i en Batch-tjänstprenumeration (standard) eller i din användarprenumeration. Om du har skapat batchkontot med standardkonfigurationen för Batch-tjänsten är ditt konto begränsat till ett maximalt antal kärnor som kan användas för bearbetning. Batch-tjänsten skalar endast beräkningsnoder upp till den kärngränsen. Därför kanske Batch-tjänsten inte når det målantal beräkningsnoder som anges av en autoskalningsformel. Se Kvoter och gränser för Azure Batch-tjänsten för information om hur du visar och ökar dina kontokvoter.

Om du har skapat ditt konto med användarprenumerationsläge delar ditt konto i kärnkvoten för prenumerationen. Mer information finns i Virtual Machines limits (Gränser för virtuella datorer) i Azure subscription and service limits, quotas, and constraints (Prenumerations- och tjänstgränser, kvoter och begränsningar i Azure).

Autoskalningsformler

En autoskalningsformel är ett strängvärde som du definierar som innehåller en eller flera -instruktioner. Autoskalningsformeln tilldelas till en pools autoScaleFormula-element (Batch REST) eller egenskapen CloudPool.AutoScaleFormula (Batch .NET). Batch-tjänsten använder din formel för att fastställa målantalet beräkningsnoder i poolen för nästa bearbetningsintervall. Formelsträngen får inte överstiga 8 kB, kan innehålla upp till 100 instruktioner som är avgränsade med semikolon och kan innehålla radbrytningar och kommentarer.

Du kan tänka på automatiska skalningsformler som ett "språk" för automatisk skalning i Batch. Formelinstruktioner är fritt utformade uttryck som kan innehålla både tjänstdefinierade variabler (definieras av Batch-tjänsten) och användardefinierade variabler. Formler kan utföra olika åtgärder på dessa värden med hjälp av inbyggda typer, operatorer och funktioner. En instruktion kan till exempel ha följande format:

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

Formler innehåller vanligtvis flera instruktioner som utför åtgärder på värden som hämtas i tidigare instruktioner. Först hämtar vi till exempel ett värde för variable1och skickar det sedan till en funktion för att fylla i variable2:

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

Inkludera dessa instruktioner i autoskalningsformeln för att komma fram till ett målantal beräkningsnoder. Dedikerade noder och Noder för oanvänd kapacitet har sina egna målinställningar. En autoskalningsformel kan innehålla ett målvärde för dedikerade noder, ett målvärde för Spot-noder eller båda.

Målantalet noder kan vara högre, lägre eller samma som det aktuella antalet noder av den typen i poolen. Batch utvärderar en pools autoskalningsformel med ett specifikt automatiskt skalningsintervall. Batch justerar målnumret för varje typ av nod i poolen till det tal som autoskalningsformeln anger vid tidpunkten för utvärderingen.

Exempel på autoskalningsformler

Nedan visas exempel på två autoskalningsformler, som kan justeras för att fungera i de flesta scenarier. Variablerna startingNumberOfVMs och maxNumberofVMs i exempelformlerna kan justeras efter dina behov.

Väntande aktiviteter

Med den här autoskalningsformeln skapas poolen ursprungligen med en enda virtuell dator. Måttet $PendingTasks definierar antalet aktiviteter som körs eller placeras i kö. Formeln hittar det genomsnittliga antalet väntande aktiviteter under de senaste 180 sekunderna och anger variabeln $TargetDedicatedNodes därefter. Formeln säkerställer att målantalet dedikerade noder aldrig överskrider 25 virtuella datorer. När nya aktiviteter skickas växer poolen automatiskt. När aktiviteterna slutförs blir de virtuella datorerna kostnadsfria och formeln för automatisk skalning krymper poolen.

Den här formeln skalar dedikerade noder, men kan ändras så att de även gäller skalningsnoder för oanvänd kapacitet.

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;

Förinstallerade noder

I det här exemplet skapas en pool som börjar med 25 noder för oanvänd kapacitet. Varje gång en nod för oanvänd kapacitet förinstalleras ersätts den med en dedikerad nod. Precis som i det första exemplet förhindrar variabeln maxNumberofVMs att poolen överskrider 25 virtuella datorer. Det här exemplet är användbart för att dra nytta av virtuella datorer med oanvänd kapacitet samtidigt som du ser till att endast ett fast antal preemptioner sker under poolens livslängd.

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

Du lär dig mer om hur du skapar autoskalningsformler och se ytterligare exempel på autoskalningsformler senare i det här avsnittet.

Variabler

Du kan använda både tjänstdefinierade och användardefinierade variabler i dina autoskalningsformler.

De tjänstdefinierade variablerna är inbyggda i Batch-tjänsten. Vissa tjänstdefinierade variabler är skrivskyddade och vissa är skrivskyddade.

Användardefinierade variabler är variabler som du definierar. I exempelformeln som visas ovan $TargetDedicatedNodes och $PendingTasks är tjänstdefinierade variabler, medan startingNumberOfVMs och maxNumberofVMs är användardefinierade variabler.

Anteckning

Tjänstdefinierade variabler föregås alltid av ett dollartecken ($). För användardefinierade variabler är dollartecknet valfritt.

I följande tabeller visas de skrivskyddade och skrivskyddade variabler som definieras av Batch-tjänsten.

Tjänstdefinierade variabler för läsning och skrivning

Du kan hämta och ange värdena för dessa tjänstdefinierade variabler för att hantera antalet beräkningsnoder i en pool.

Variabel Beskrivning
$TargetDedicatedNodes Målantalet dedikerade beräkningsnoder för poolen. Detta anges som ett mål eftersom en pool kanske inte alltid uppnår önskat antal noder. Om till exempel målantalet dedikerade noder ändras av en autoskalningsutvärdering innan poolen har nått det ursprungliga målet kanske poolen inte når målet.

En pool i ett konto som skapats i Batch-tjänstläge kanske inte uppnår sitt mål om målet överskrider en Batch-kontonod eller kärnkvot. En pool i ett konto som skapats i användarprenumerationsläge kanske inte uppnår sitt mål om målet överskrider prenumerationens delade kärnkvot.
$TargetLowPriorityNodes Målantalet beräkningsnoder för vm med oanvänd kapacitet för poolen. Detta anges som ett mål eftersom en pool kanske inte alltid uppnår önskat antal noder. Om till exempel målantalet noder för oanvänd kapacitet ändras av en autoskalningsutvärdering innan poolen har nått det ursprungliga målet kanske poolen inte når målet. En pool kanske inte heller uppnår sitt mål om målet överskrider en Batch-kontonod eller kärnkvot.

Mer information om beräkningsnoder för oanvänd kapacitet finns i Använda virtuella datorer för oanvänd kapacitet med Batch.
$NodeDeallocationOption Den åtgärd som inträffar när beräkningsnoder tas bort från en pool. Möjliga värden:
  • requeue: Standardvärdet. Avslutar aktiviteter omedelbart och placerar dem i jobbkön igen så att de schemaläggs om. Den här åtgärden säkerställer att målantalet noder nås så snabbt som möjligt. Det kan dock vara mindre effektivt eftersom alla aktiviteter som körs avbryts och sedan måste startas om helt.
  • avsluta: Avslutar aktiviteter omedelbart och tar bort dem från jobbkön.
  • taskcompletion: Väntar på att aktiviteter som körs ska slutföras och tar sedan bort noden från poolen. Använd det här alternativet för att undvika att aktiviteter avbryts och placeras i kö igen, vilket slösar bort allt arbete som uppgiften har gjort.
  • retaineddata: Väntar på att alla lokala uppgiftsbehållna data på noden ska rensas innan noden tas bort från poolen.

Anteckning

Variabeln $TargetDedicatedNodes kan också anges med aliaset $TargetDedicated. På samma sätt kan variabeln $TargetLowPriorityNodes anges med hjälp av aliaset $TargetLowPriority. Om både den fullständigt namngivna variabeln och dess alias anges av formeln har värdet som tilldelats den fullständigt namngivna variabeln företräde.

Skrivskyddade tjänstdefinierade variabler

Du kan hämta värdet för dessa tjänstdefinierade variabler för att göra justeringar som baseras på mått från Batch-tjänsten.

Viktigt

Jobbpubliceringen ingår för närvarande inte i variabler som innehåller uppgiftsantal, till exempel $ActiveTasks och $PendingTasks. Beroende på din autoskalningsformel kan detta resultera i att noder tas bort utan noder tillgängliga för att köra jobbpubliceringen.

Tips

Dessa skrivskyddade tjänstdefinierade variabler är objekt som tillhandahåller olika metoder för åtkomst till data som är associerade med var och en. Mer information finns i Hämta exempeldata senare i den här artikeln.

Variabel Beskrivning
$CPUPercent Den genomsnittliga procentandelen cpu-användning.
$WallClockSeconds Antalet förbrukade sekunder.
$MemoryBytes Det genomsnittliga antalet megabyte som används.
$DiskBytes Det genomsnittliga antalet gigabyte som används på de lokala diskarna.
$DiskReadBytes Antal lästa byte.
$DiskWriteBytes Antalet skrivna byte.
$DiskReadOps Antalet utförda läsdiskåtgärder.
$DiskWriteOps Antalet utförda skrivdiskåtgärder.
$NetworkInBytes Antalet inkommande byte.
$NetworkOutBytes Antalet utgående byte.
$SampleNodeCount Antalet beräkningsnoder.
$ActiveTasks Antalet uppgifter som är redo att köras men som ännu inte körs. Detta omfattar alla aktiviteter som är i aktivt tillstånd och vars beroenden har uppfyllts. Alla aktiviteter som är i aktivt tillstånd men vars beroenden inte har uppfyllts undantas från antalet $ActiveTasks. För en aktivitet med flera instanser innehåller $ActiveTasks antalet instanser som angetts för aktiviteten.
$RunningTasks Antalet aktiviteter i ett körningstillstånd.
$PendingTasks Summan av $ActiveTasks och $RunningTasks.
$SucceededTasks Antalet aktiviteter som har slutförts.
$FailedTasks Antalet aktiviteter som misslyckades.
$TaskSlotsPerNode Antalet aktivitetsfack som kan användas för att köra samtidiga aktiviteter på en enda beräkningsnod i poolen.
$CurrentDedicatedNodes Det aktuella antalet dedikerade beräkningsnoder.
$CurrentLowPriorityNodes Det aktuella antalet skalningsnoder för oanvänd kapacitet, inklusive eventuella noder som har föregåtts.
$PreemptedNodeCount Antalet noder i poolen som är i ett förutbestämt tillstånd.

Varning

$PreemptedNodeCount är för närvarande inte tillgängligt och returnerar 0 värdedata.

Anteckning

Använd $RunningTasks vid skalning baserat på antalet aktiviteter som körs vid en tidpunkt och $ActiveTasks vid skalning baserat på antalet aktiviteter som är i kö för att köras.

Typer

Autoskalningsformler stöder följande typer:

  • double
  • doubleVec
  • doubleVecList
  • sträng
  • tidsstämpel – en sammansatt struktur som innehåller följande medlemmar:
    • år
    • månad (1-12)
    • dag (1-31)
    • veckodag (i talformat, till exempel 1 för måndag)
    • timme (i 24-timmarsnummerformat, till exempel 13 betyder 1 PM)
    • minut (00-59)
    • second (00-59)
  • timeinterval
    • TimeInterval_Zero
    • TimeInterval_100ns
    • TimeInterval_Microsecond
    • TimeInterval_Millisecond
    • TimeInterval_Second
    • TimeInterval_Minute
    • TimeInterval_Hour
    • TimeInterval_Day
    • TimeInterval_Week
    • TimeInterval_Year

Operations

Dessa åtgärder tillåts för de typer som anges i föregående avsnitt.

Åtgärd Operatorer som stöds Resultattyp
dubbeloperator dubbel +, -, *, / double
timeinterval för dubbeloperator * timeinterval
doubleVec operator double +, -, *, / doubleVec
doubleVec operator doubleVec +, -, *, / doubleVec
timeinterval operator double *, / timeinterval
timeinterval operator timeinterval +, - timeinterval
tidsinterval operator tidsstämpel + timestamp
tidsstämpeloperatortidinterval + timestamp
tidsstämpeloperatorns tidsstämpel - timeinterval
operator dubbel -, ! double
operatortidinterval - timeinterval
dubbeloperator dubbel <, <=, ==, >=, >, != double
strängoperatorsträng <, <=, ==, >=, >, != double
timestamp operator timestamp <, <=, ==, >=, >, != double
timeinterval operator timeinterval <, <=, ==, >=, >, != double
double operator double &&, || double

När du testar en dubbel med en ternary-operator (double ? statement1 : statement2) är nonzero sant och noll är falskt.

Functions

Du kan använda dessa fördefinierade funktioner när du definierar en autoskalningsformel.

Funktion Returtyp Description
avg(doubleVecList) double Returnerar det genomsnittliga värdet för alla värden i doubleVecList.
ceil(double) double Returnerar det minsta heltalsvärdet inte mindre än det dubbla.
ceil(doubleVecList) doubleVec Returnerar komponentvis ceil för doubleVecList.
floor(double) double Returnerar det största heltalsvärdet som inte är större än det dubbla.
floor(doubleVecList) doubleVec Returns the component-wise floor of the doubleVecList.
len(doubleVecList) double Returnerar längden på den vektor som skapas från doubleVecList.
lg(double) double Returnerar loggbas 2 av dubbel.
lg(doubleVecList) doubleVec Returns the component-wise lg of the doubleVecList.
ln(double) double Returnerar den naturliga loggen för dubbel.
ln(doubleVecList) doubleVec Returns the component-wise ln of the doubleVecList.
log(double) double Returnerar loggbasen 10 av dubbel.
log(doubleVecList) doubleVec Returns the component-wise log of the doubleVecList.
max(doubleVecList) double Returnerar det maximala värdet i doubleVecList.
min(doubleVecList) double Returnerar minimivärdet i doubleVecList.
norm(doubleVecList) double Returnerar tvånormen för vektorn som skapas från doubleVecList.
percentile(doubleVec v, double p) double Returnerar percentilelementet i vektorn v.
rand() double Returnerar ett slumpmässigt värde mellan 0,0 och 1,0.
range(doubleVecList) double Returnerar skillnaden mellan värdena min och max i doubleVecList.
round(double) double Returnerar närmaste heltalsvärde till det dubbla (i flyttalformat) och avrundar halvvägsfall bort från noll.
round(doubleVecList) doubleVec Returns the component-wise round of the doubleVecList.
std(doubleVecList) double Returnerar standardavvikelsen för exemplet på värdena i doubleVecList.
stop() Stoppar utvärderingen av autoskalningsuttrycket.
sum(doubleVecList) double Returnerar summan av alla komponenter i doubleVecList.
time(string dateTime="") timestamp Returnerar tidsstämpeln för den aktuella tiden om inga parametrar skickas, eller tidsstämpeln för dateTime-strängen om den skickas. DateTime-format som stöds är W3C-DTF och RFC 1123.
val(doubleVec v, double i) double Returnerar värdet för elementet som finns på plats i i vektor v, med ett startindex på noll.

Vissa av funktionerna som beskrivs i föregående tabell kan acceptera en lista som ett argument. Den kommaavgränsade listan är valfri kombination av double och doubleVec. Exempel:

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

DoubleVecList-värdet konverteras till en enda doubleVec före utvärdering. Om till exempel v = [1,2,3]är anropet avg(v) likvärdigt med att anropa avg(1,2,3). Anrop avg(v, 7) motsvarar att anropa avg(1,2,3,7).

Mått

Du kan använda både resurs- och aktivitetsmått när du definierar en formel. Du justerar målantalet dedikerade noder i poolen baserat på de måttdata som du hämtar och utvärderar. Mer information om varje mått finns i avsnittet Variabler ovan.

Metric Beskrivning
Resurs

Resursmått baseras på PROCESSOR, bandbredd, minnesanvändning för beräkningsnoder och antalet noder.

Dessa tjänstdefinierade variabler är användbara för att göra justeringar baserat på antalet noder:

  • $TargetDedicatedNodes
  • $TargetLowPriorityNodes
  • $CurrentDedicatedNodes
  • $CurrentLowPriorityNodes
  • $PreemptedNodeCount
  • $SampleNodeCount

Dessa tjänstdefinierade variabler är användbara för att göra justeringar baserat på nodresursanvändning:

  • $CPUPercent
  • $WallClockSeconds
  • $MemoryBytes
  • $DiskBytes
  • $DiskReadBytes
  • $DiskWriteBytes
  • $DiskReadOps
  • $DiskWriteOps
  • $NetworkInBytes
  • $NetworkOutBytes

Uppgift

Aktivitetsmått baseras på status för aktiviteter, till exempel Aktiva, Väntande och Slutförda. Följande tjänstdefinierade variabler är användbara för att göra justeringar i poolstorlek baserat på aktivitetsmått:

  • $ActiveTasks
  • $RunningTasks
  • $PendingTasks
  • $SucceededTasks
  • $FailedTasks

Hämta exempeldata

Kärnåtgärden för en autoskalningsformel är att hämta aktivitets- och resursmåttdata (exempel) och sedan justera poolstorleken baserat på dessa data. Därför är det viktigt att ha en tydlig förståelse för hur autoskalningsformler interagerar med exempel.

Metoder

Autoskalningsformler fungerar på exempel på måttdata som tillhandahålls av Batch-tjänsten. En formel växer eller krymper poolstorleken baserat på de värden som den hämtar. Tjänstdefinierade variabler är objekt som tillhandahåller metoder för att komma åt data som är associerade med objektet. Följande uttryck visar till exempel en begäran om att få de senaste fem minuternas CPU-användning:

$CPUPercent.GetSample(TimeInterval_Minute * 5)

Följande metoder kan användas för att hämta exempeldata om tjänstdefinierade variabler.

Metod Beskrivning
GetSample() Metoden GetSample() returnerar en vektor med dataexempel.

Ett exempel är måttdata för 30 sekunder. Med andra ord hämtas prover var 30:e sekund. Men som anges nedan finns det en fördröjning mellan när ett exempel samlas in och när det är tillgängligt för en formel. Därför kan inte alla prover under en viss tidsperiod vara tillgängliga för utvärdering med hjälp av en formel.
  • doubleVec GetSample(double count): Anger hur många prover som ska hämtas från de senaste exemplen som samlats in. GetSample(1) returnerar det senaste tillgängliga exemplet. För mått som $CPUPercentbör dock GetSample(1) inte användas, eftersom det är omöjligt att veta när exemplet samlades in. Det kan vara nyligen, eller på grund av systemproblem kan det vara mycket äldre. I sådana fall är det bättre att använda ett tidsintervall enligt nedan.
  • doubleVec GetSample((timestamp or timeinterval) startTime [, double samplePercent]): Anger en tidsram för insamling av exempeldata. Du kan också ange procentandelen av exemplen som måste vara tillgängliga inom den begärda tidsramen. Till exempel $CPUPercent.GetSample(TimeInterval_Minute * 10) skulle returnera 20 exempel om alla exempel under de senaste 10 minuterna finns i historiken CPUPercent . Om den sista minuten av historiken inte var tillgänglig returneras endast 18 exempel. I det här fallet $CPUPercent.GetSample(TimeInterval_Minute * 10, 95) skulle misslyckas eftersom endast 90 procent av exemplen är tillgängliga, men $CPUPercent.GetSample(TimeInterval_Minute * 10, 80) skulle lyckas.
  • doubleVec GetSample((timestamp or timeinterval) startTime, (timestamp or timeinterval) endTime [, double samplePercent]): Anger en tidsram för att samla in data, med både en starttid och en sluttid. Som nämnts ovan finns det en fördröjning mellan när ett prov samlas in och när det blir tillgängligt för en formel. Tänk på den här fördröjningen när du använder GetSample metoden . Se GetSamplePercent nedan.
GetSamplePeriod() Returnerar perioden med prover som tagits i en historisk urvalsdatauppsättning.
Count() Returnerar det totala antalet exempel i måtthistoriken.
HistoryBeginTime() Returnerar tidsstämpeln för det äldsta tillgängliga dataexemplet för måttet.
GetSamplePercent() Returnerar procentandelen prover som är tillgängliga för ett angivet tidsintervall. Till exempel doubleVec GetSamplePercent( (timestamp or timeinterval) startTime [, (timestamp or timeinterval) endTime] ). GetSample Eftersom metoden misslyckas om procentandelen av de returnerade exemplen är mindre än den samplePercent angivna kan du använda GetSamplePercent metoden för att kontrollera först. Sedan kan du utföra en alternativ åtgärd om det inte finns tillräckligt med exempel, utan att stoppa den automatiska skalningsutvärderingen.

Exempel

Batch-tjänsten tar regelbundet exempel på aktivitets- och resursmått och gör dem tillgängliga för dina autoskalningsformler. De här exemplen registreras var 30:e sekund av Batch-tjänsten. Det finns dock vanligtvis en fördröjning mellan när exemplen registrerades och när de görs tillgängliga för (och kan läsas av) dina autoskalningsformler. Dessutom kan det hända att exempel inte registreras under ett visst intervall på grund av faktorer som nätverk eller andra infrastrukturproblem.

Procentexempel

När samplePercent skickas till GetSample() metoden eller GetSamplePercent() metoden anropas refererar procent till en jämförelse mellan det totala möjliga antalet prover som registreras av Batch-tjänsten och antalet exempel som är tillgängliga för din autoskalningsformel.

Låt oss titta på ett tidsintervall på 10 minuter som exempel. Eftersom proverna registreras var 30:e sekund inom det tidsintervallet på 10 minuter skulle det maximala totala antalet prover som registrerats av Batch vara 20 prov (2 per minut). Men på grund av den inneboende svarstiden för rapporteringsmekanismen och andra problem i Azure kan det bara finnas 15 exempel som är tillgängliga för din autoskalningsformel för läsning. För den 10-minutersperioden kan till exempel endast 75 % av det totala antalet registrerade prov vara tillgängligt för formeln.

GetSample() och exempelintervall

Dina autoskalningsformler växer och krymper dina pooler genom att lägga till eller ta bort noder. Eftersom noder kostar pengar bör du se till att dina formler använder en intelligent analysmetod som baseras på tillräckliga data. Vi rekommenderar att du använder en trendanalys i formler. Den här typen växer och krymper dina pooler baserat på ett antal insamlade exempel.

Det gör du genom att använda GetSample(interval look-back start, interval look-back end) för att returnera en vektor med exempel:

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

När ovanstående rad utvärderas av Batch returneras ett urvalsintervall som en vektor med värden. Exempel:

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

När du har samlat in vektorn med exempel kan du sedan använda funktioner som min(), max()och avg() för att härleda meningsfulla värden från det insamlade intervallet.

För ytterligare säkerhet kan du tvinga en formelutvärdering att misslyckas om mindre än en viss exempelprocent är tillgänglig under en viss tidsperiod. När du tvingar en formelutvärdering att misslyckas instruerar du Batch att upphöra med ytterligare utvärdering av formeln om den angivna procentandelen av exemplen inte är tillgänglig. I det här fallet görs ingen ändring av poolstorleken. Om du vill ange en obligatorisk procentandel av exemplen för att utvärderingen ska lyckas anger du den som den tredje parametern till GetSample(). Här anges ett krav på 75 procent av exemplen:

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

Eftersom det kan uppstå en fördröjning i exempeltillgängligheten bör du alltid ange ett tidsintervall med en starttid som är äldre än en minut. Det tar ungefär en minut innan prover sprids genom systemet, så exempel i intervallet (0 * TimeInterval_Second, 60 * TimeInterval_Second) kanske inte är tillgängliga. Återigen kan du använda procentparametern GetSample() för för att framtvinga ett visst procentuellt urvalskrav.

Viktigt

Vi rekommenderar starkt att du undviker att bara förlita dig på GetSample(1) i dina autoskalningsformler. Detta beror på GetSample(1) att i princip säger till Batch-tjänsten, "Ge mig det sista exemplet du har, oavsett hur länge sedan du hämtade det." Eftersom det bara är ett enda exempel, och det kan vara ett äldre exempel, kanske det inte är representativt för den större bilden av den senaste uppgiften eller resurstillståndet. Om du använder GetSample(1)kontrollerar du att det är en del av en större instruktion och inte den enda datapunkt som din formel förlitar sig på.

Skriva en autoskalningsformel

Du skapar en autoskalningsformel genom att skapa instruktioner som använder ovanstående komponenter och sedan kombinera dessa instruktioner till en fullständig formel. I det här avsnittet skapar vi ett exempel på en autoskalningsformel som kan utföra verkliga skalningsbeslut och göra justeringar.

Först ska vi definiera kraven för vår nya autoskalningsformel. Formeln bör:

  • Öka målantalet dedikerade beräkningsnoder i en pool om CPU-användningen är hög.
  • Minska målantalet dedikerade beräkningsnoder i en pool när processoranvändningen är låg.
  • Begränsa alltid det maximala antalet dedikerade noder till 400.
  • När du minskar antalet noder ska du inte ta bort noder som kör aktiviteter. Om det behövs väntar du tills aktiviteterna har slutförts innan du tar bort noder.

Den första instruktionen i vår formel ökar antalet noder vid hög CPU-användning. Vi definierar en instruktion som fyller i en användardefinierad variabel ($totalDedicatedNodes) med ett värde som är 110 procent av det aktuella målantalet dedikerade noder, men bara om den minsta genomsnittliga CPU-användningen under de senaste 10 minuterna var över 70 procent. Annars används värdet för det aktuella antalet dedikerade noder.

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

För att minska antalet dedikerade noder under låg CPU-användning anger nästa instruktion i vår formel samma $totalDedicatedNodes variabel till 90 procent av det aktuella målantalet dedikerade noder, om den genomsnittliga CPU-användningen under de senaste 60 minuterna var under 20 procent. Annars använder den det aktuella värdet $totalDedicatedNodes för som vi fyllde i i -instruktionen ovan.

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

Nu begränsar vi målantalet dedikerade beräkningsnoder till högst 400.

$TargetDedicatedNodes = min(400, $totalDedicatedNodes)

Slutligen ser vi till att noderna inte tas bort förrän deras uppgifter har slutförts.

$NodeDeallocationOption = taskcompletion;

Här är den fullständiga formeln:

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

Anteckning

Om du väljer kan du inkludera både kommentarer och radbrytningar i formelsträngar. Tänk också på att semikolon som saknas kan leda till utvärderingsfel.

Intervall för automatisk skalning

Som standard justerar Batch-tjänsten en pools storlek enligt dess autoskalningsformel var 15:e minut. Det här intervallet kan konfigureras med hjälp av följande poolegenskaper:

Det minsta intervallet är fem minuter och det maximala är 168 timmar. Om ett intervall utanför det här intervallet anges returnerar Batch-tjänsten ett fel med felaktig begäran (400).

Anteckning

Autoskalning är för närvarande inte avsett att svara på ändringar på mindre än en minut, utan är snarare avsett att justera storleken på poolen gradvis när du kör en arbetsbelastning.

Skapa en automatiskt skalningsaktiverad pool med Batch-SDK:er

Automatisk skalning av pooler kan konfigureras med någon av Batch SDK:er, Batch REST APIBatch PowerShell-cmdletar och Batch CLI. I det här avsnittet kan du se exempel för både .NET och Python.

.NET

Följ dessa steg för att skapa en pool med automatisk skalning aktiverat i .NET:

  1. Skapa poolen med BatchClient.PoolOperations.CreatePool.
  2. Ange egenskapen CloudPool.AutoScaleEnabled till true.
  3. Ange egenskapen CloudPool.AutoScaleFormula med din autoskalningsformel.
  4. (Valfritt) Ange egenskapen CloudPool.AutoScaleEvaluationInterval (standardvärdet är 15 minuter).
  5. Checka in poolen med CloudPool.Commit eller CommitAsync.

I följande exempel skapas en automatiskt skalningsaktiverad pool i .NET. Poolens autoskalningsformel anger målantalet dedikerade noder till 5 på måndagar och till 1 varannan dag i veckan. Det automatiska skalningsintervallet är inställt på 30 minuter. I det här och de andra C#-kodfragmenten i den här artikeln myBatchClient är en korrekt initierad instans av klassen 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();

Viktigt

När du skapar en automatiskt skalningsaktiverad pool ska du inte ange parametern targetDedicatedNodes eller parametern targetLowPriorityNodes i anropet till CreatePool. Ange i stället egenskaperna AutoScaleEnabled och AutoScaleFormula i poolen. Värdena för dessa egenskaper avgör målnumret för varje typ av nod.

Om du vill ändra storlek på en autoskalningsaktiverad pool manuellt (till exempel med BatchClient.PoolOperations.ResizePoolAsync) måste du först inaktivera automatisk skalning i poolen och sedan ändra storlek på den.

Python

Så här skapar du en automatiskt skalningsaktiverad pool med Python SDK:

  1. Skapa en pool och ange dess konfiguration.
  2. Lägg till poolen i tjänstklienten.
  3. Aktivera autoskalning i poolen med en formel som du skriver.

I följande exempel visas de här stegen.

# 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="18.04-LTS",
          version="latest"
            ),
        node_agent_sku_id="batch.node.ubuntu 18.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)

Tips

Fler exempel på hur du använder Python SDK finns i Snabbstartslagringsplatsen för Batch Python på GitHub.

Aktivera automatisk skalning i en befintlig pool

Varje Batch SDK är ett sätt att aktivera automatisk skalning. Exempel:

Tänk på följande när du aktiverar automatisk skalning i en befintlig pool:

  • Om autoskalning för närvarande är inaktiverat i poolen måste du ange en giltig autoskalningsformel när du utfärdar begäran. Du kan också ange ett automatiskt skalningsintervall. Om du inte anger ett intervall används standardvärdet 15 minuter.
  • Om autoskalning för närvarande är aktiverat i poolen kan du ange en ny formel, ett nytt intervall eller båda. Du måste ange minst en av dessa egenskaper.
    • Om du anger ett nytt automatiskt skalningsintervall stoppas det befintliga schemat och ett nytt schema startas. Starttiden för det nya schemat är den tidpunkt då begäran om att aktivera automatisk skalning utfärdades.
    • Om du utelämnar antingen autoskalningsformeln eller intervallet fortsätter Batch-tjänsten att använda det aktuella värdet för den inställningen.

Anteckning

Om du angav värden för parametrarna targetDedicatedNodes eller targetLowPriorityNodes för CreatePool-metoden när du skapade poolen i .NET, eller för jämförbara parametrar på ett annat språk, ignoreras dessa värden när autoskalningsformeln utvärderas.

I det här C#-exemplet används Batch .NET-biblioteket för att aktivera automatisk skalning i en befintlig pool.

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

Uppdatera en autoskalningsformel

Om du vill uppdatera formeln i en befintlig automatiskt skalningsaktiverad pool anropar du åtgärden för att aktivera automatisk skalning igen med den nya formeln. Om autoskalning till exempel redan är aktiverat myexistingpool när följande .NET-kod körs ersätts dess autoskalningsformel med innehållet i myNewFormula.

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

Uppdatera autoskalningsintervallet

Om du vill uppdatera utvärderingsintervallet för automatisk skalning för en befintlig automatiskt skalningsaktiverad pool anropar du åtgärden för att aktivera automatisk skalning igen med det nya intervallet. Om du till exempel vill ange utvärderingsintervallet för autoskalning till 60 minuter för en pool som redan är autoskalningsaktiverad i .NET:

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

Utvärdera en autoskalningsformel

Du kan utvärdera en formel innan du tillämpar den på en pool. På så sätt kan du testa formelns resultat innan du placerar den i produktion.

Innan du kan utvärdera en autoskalningsformel måste du först aktivera automatisk skalning i poolen med en giltig formel, till exempel enradsformeln $TargetDedicatedNodes = 0. Använd sedan något av följande för att utvärdera formeln som du vill testa:

Det här Batch .NET-exemplet utvärderar en autoskalningsformel. Om poolen inte redan använder automatisk skalning aktiverar vi den först.

// 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)
{
    // We 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 we want to apply our new autoscale formula below if it
    // evaluates successfully, and we *just* enabled autoscaling on
    // this pool, we pause here to ensure we 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();
}

// We 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);
    }
}

En lyckad utvärdering av formeln som visas i det här kodfragmentet ger resultat som liknar:

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

Hämta information om autoskalningskörningar

För att säkerställa att formeln fungerar som förväntat rekommenderar vi att du regelbundet kontrollerar resultatet av de autoskalningskörningar som Batch utför i poolen. Det gör du genom att hämta (eller uppdatera) en referens till poolen och sedan undersöka egenskaperna för den senaste autoskalningskörningen.

I Batch .NET har egenskapen CloudPool.AutoScaleRun flera egenskaper som ger information om den senaste automatiska skalningskörningen som utförs på poolen:

I REST-API:et returnerar Hämta information om en poolbegäran information om poolen, som innehåller den senaste automatiska skalningskörningsinformationen i egenskapen autoScaleRun .

I följande C#-exempel används Batch .NET-biblioteket för att skriva ut information om den senaste autoskalningen som kördes på pool myPool.

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

Exempel på utdata från föregående exempel:

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:

Hämta körningshistorik för automatisk skalning med hjälp av pool autoskalningshändelser

Du kan också kontrollera den automatiska skalningshistoriken genom att fråga PoolAutoScaleEvent. Den här händelsen genereras av Batch Service för att registrera varje förekomst av utvärdering och körning av autoskalningsformler, vilket kan vara användbart för att felsöka potentiella problem.

Exempelhändelse 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": []
    }
}

Exempel på autoskalningsformler

Låt oss titta på några formler som visar olika sätt att justera mängden beräkningsresurser i en pool.

Exempel 1: Tidsbaserad justering

Anta att du vill justera poolstorleken baserat på veckodag och tid på dagen. Det här exemplet visar hur du ökar eller minskar antalet noder i poolen i enlighet med detta.

Formeln hämtar först den aktuella tiden. Om det är en veckodag (1–5) och inom arbetstid (08:00 till 18:00) är målpoolens storlek inställd på 20 noder. Annars är den inställd på 10 noder.

$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 kan justeras för att återspegla din lokala tidszon genom att lägga time() till produkten av TimeZoneInterval_Hour och UTC-förskjutningen. Använd till exempel $curTime = time() + (-6 * TimeInterval_Hour); för Mountain Daylight Time (MDT). Tänk på att förskjutningen måste justeras i början och slutet av sommartiden (om tillämpligt).

Exempel 2: Aktivitetsbaserad justering

I det här C#-exemplet justeras poolstorleken baserat på antalet uppgifter i kön. Vi har inkluderat både kommentarer och radbrytningar i formelsträngarna.

// Get pending tasks for the past 15 minutes.
$samples = $PendingTasks.GetSamplePercent(TimeInterval_Minute * 15);
// If we have fewer than 70 percent data points, we use the last sample point,
// otherwise we 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;

Exempel 3: Redovisning för parallella uppgifter

Det här C#-exemplet justerar poolstorleken baserat på antalet aktiviteter. Den här formeln tar också hänsyn till värdet TaskSlotsPerNode som har angetts för poolen. Den här metoden är användbar i situationer där parallell aktivitetskörning har aktiverats i poolen.

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

Exempel 4: Ange en ursprunglig poolstorlek

Det här exemplet visar ett C#-exempel med en autoskalningsformel som anger poolstorleken till ett angivet antal noder under en inledande tidsperiod. Därefter justeras poolstorleken baserat på antalet aktiva aktiviteter som körs.

Mer specifikt gör den här formeln följande:

  • Anger den ursprungliga poolstorleken till fyra noder.
  • Justerar inte poolstorleken inom de första 10 minuterna av poolens livscykel.
  • Efter 10 minuter får du det maximala värdet för antalet aktiva aktiviteter som körs under de senaste 60 minuterna.
    • Om båda värdena är 0 (vilket indikerar att inga aktiviteter kördes eller var aktiva under de senaste 60 minuterna) är poolstorleken inställd på 0.
    • Om något av värdena är större än noll görs ingen ändring.
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ästa steg