Skapa en formel för att automatiskt skala beräkningsnoder i en batchpool

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 uppgiftskraven ökar och tar bort beräkningsnoder när uppgiftsbehoven minskar.

Om du vill aktivera automatisk skalning på 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 arbetsbelastningen. Dessa noder kan vara dedikerade noder eller Azure Spot-noder. Batch granskar 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 ditt Batch-konto 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 i en autoskalningsformel. Information om hur du visar och ökar dina kontokvoter finns i Kvoter och gränser för Azure Batch-tjänsten.

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 dig automatiska skalningsformler som ett batch-autoskalningsspråk. Formelinstruktioner är friformade uttryck som kan innehålla både tjänstdefinierade variabler, som 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 formulär:

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

Formler innehåller vanligtvis flera instruktioner som utför åtgärder på värden som hämtas i tidigare instruktioner. Du kan till exempel först hämta ett värde för variable1och sedan skicka det 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 spotnoder har varsin målinställning. En autoskalningsformel kan innehålla ett målvärde för dedikerade noder, ett målvärde för dekornoder 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 specifika automatiska skalningsintervall. Batch justerar målnumret för varje typ av nod i poolen till det antal som autoskalningsformeln anger vid tidpunkten för utvärderingen.

Exempel på autoskalningsformler

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

Väntande uppgifter

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 uppgifter skickas växer poolen automatiskt. När uppgifterna har slutförts blir virtuella datorer kostnadsfria och formeln för automatisk skalning krymper poolen.

Den här formeln skalar dedikerade noder, men kan ändras för att även gälla skalning av 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;

Viktigt!

Batch-tjänsten har för närvarande begränsningar med matchningen av väntande uppgifter. När en uppgift läggs till i jobbet läggs den också till i en intern kö som används av Batch-tjänsten för schemaläggning. Om aktiviteten tas bort innan den kan schemaläggas kan aktiviteten finnas kvar i kön, vilket gör att den fortfarande räknas i $PendingTasks. Den här borttagna uppgiften rensas så småningom från kön när Batch får chansen att hämta uppgifter från kön för att schemalägga med inaktiva noder i Batch-poolen.

Fördefinierade noder

Det här exemplet skapar en pool som börjar med 25 dekornoder. Varje gång en dekornod föregrips 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 inträffar 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 ser fler exempel på autoskalningsformler senare i den här artikeln.

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 föregående exempel är $TargetDedicatedNodes och $PendingTasks tjänstdefinierade variabler, medan startingNumberOfVMs och maxNumberofVMs är användardefinierade variabler.

Kommentar

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 definierats av Batch-tjänsten.

Skrivskyddade tjänstdefinierade variabler

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

Olika beskrivning
$TargetDedicatedNodes Målantalet dedikerade beräkningsnoder för poolen. 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 kvoten för delad kärna för prenumerationen.
$TargetLowPriorityNodes Målantalet beräkningsnoder för oanvänd kapacitet för poolen. Anges som ett mål eftersom en pool kanske inte alltid uppnår önskat antal noder. Om till exempel målantalet Spot-noder ä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 med 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 är:
- requeue: Standardvärdet. Avslutar aktiviteterna 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.
- 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 skickas på nytt, vilket slösar bort allt arbete som uppgiften har utfört.
- retaineddata: Väntar på att alla lokala uppgiftsbehållna data på noden ska rensas innan noden tas bort från poolen.

Kommentar

Variabeln $TargetDedicatedNodes kan också anges med hjälp av 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!

Uppgifter för jobbutgivning ingår för närvarande inte i variabler som anger antal aktiviteter, till exempel $ActiveTasks och $PendingTasks. Beroende på din autoskalningsformel kan detta resultera i att noder tas bort utan noder som är tillgängliga för att köra uppgifter för jobbpubliceringen.

Dricks

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.

Olika beskrivning
$CPUPercent Den genomsnittliga procentandelen cpu-användning.
$WallClockSeconds Antal sekunder som förbrukas. Går i pension efter 2024-Mar-31.
$MemoryBytes Det genomsnittliga antalet megabyte som används. Går i pension efter 2024-Mar-31.
$DiskBytes Det genomsnittliga antalet gigabyte som används på de lokala diskarna. Går i pension efter 2024-Mar-31.
$DiskReadBytes Antal lästa byte. Går i pension efter 2024-Mar-31.
$DiskWriteBytes Antalet skrivna byte. Går i pension efter 2024-Mar-31.
$DiskReadOps Antalet utförda läsdiskåtgärder. Går i pension efter 2024-Mar-31.
$DiskWriteOps Antalet skrivdiskåtgärder som utförts. Går i pension efter 2024-Mar-31.
$NetworkInBytes Antalet inkommande byte. Går i pension efter 2024-Mar-31.
$NetworkOutBytes Antalet utgående byte. Går i pension efter 2024-Mar-31.
$SampleNodeCount Antalet beräkningsnoder. Går i pension efter 2024-Mar-31.
$ActiveTasks Antalet uppgifter som är redo att köras men som ännu inte körs. Detta omfattar alla uppgifter 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 $ActiveTasks antalet. För en aktivitet $ActiveTasks med flera instanser inkluderar antalet instanser som angetts för aktiviteten.
$RunningTasks Antalet aktiviteter i ett körningstillstånd.
$PendingTasks Summan av $ActiveTasks och $RunningTasks.
$SucceededTasks Antalet uppgifter som har slutförts.
$FailedTasks Antalet aktiviteter som misslyckades.
$TaskSlotsPerNode Antalet aktivitetsfack som kan användas för att köra samtidiga uppgifter på en enda beräkningsnod i poolen.
$CurrentDedicatedNodes Det aktuella antalet dedikerade beräkningsnoder.
$CurrentLowPriorityNodes Det aktuella antalet beräkningsnoder för oanvänd kapacitet, inklusive eventuella noder som har förinställts.
$UsableNodeCount Antalet användbara beräkningsnoder.
$PreemptedNodeCount Antalet noder i poolen som är i förinställt tillstånd.

Varning

Välj tjänstdefinierade variabler dras tillbaka efter den 31 mars 2024 enligt beskrivningen i tabellen ovan. Efter slutdatumet fylls dessa tjänstdefinierade variabler inte längre i med exempeldata. Avbryt användningen av dessa variabler före detta datum.

Kommentar

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

Typer

Autoskalningsformler stöder följande typer:

  • dubbel
  • doubleVec
  • doubleVecList
  • sträng
  • timestamp – 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 +, -, *, / dubbel
timeinterval för dubbeloperator * timeinterval
doubleVec operator double +, -, *, / doubleVec
doubleVec operator doubleVec +, -, *, / doubleVec
timeinterval-operatorn dubbel *, / timeinterval
timeinterval-operatorn timeinterval +, - timeinterval
tidsstämpel för timeinterval-operator + timestamp
tidsstämpeloperatortidinterval + timestamp
tidsstämpel för tidsstämpel för operatorn - timeinterval
operator dubbel -, ! dubbel
operator timeinterval - timeinterval
dubbeloperator dubbel <, <=, ==, >=, >, != dubbel
strängoperatorsträng <, <=, ==, >=, >, != dubbel
tidsstämpel för tidsstämpel för operatorn <, <=, ==, >=, >, != dubbel
timeinterval-operatorn timeinterval <, <=, ==, >=, >, != dubbel
dubbeloperator dubbel &&, || dubbel

Att testa en dubbel med en ternary-operator (double ? statement1 : statement2), resulterar i icke-zero som sant och noll som falskt.

Functions

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

Funktion Returtyp beskrivning
avg(doubleVecList) dubbel Returnerar det genomsnittliga värdet för alla värden i doubleVecList.
ceil(double) dubbel Returnerar det minsta heltalsvärdet inte mindre än det dubbla.
ceil(doubleVecList) doubleVec Returnerar komponenten för ceil doubleVecList.
floor(double) dubbel Returnerar det största heltalsvärdet som inte är större än det dubbla.
floor(doubleVecList) doubleVec Returnerar komponenten för floor doubleVecList.
len(doubleVecList) dubbel Returnerar längden på den vektor som skapas från doubleVecList.
lg(double) dubbel Returnerar loggbas 2 av dubbel.
lg(doubleVecList) doubleVec Returnerar komponenten för lg doubleVecList.
ln(double) dubbel Returnerar dubbelns naturliga logg.
ln(doubleVecList) doubleVec Returnerar komponenten för ln doubleVecList.
log(double) dubbel Returnerar loggbasen 10 av dubbel.
log(doubleVecList) doubleVec Returnerar komponenten för log doubleVecList.
max(doubleVecList) dubbel Returnerar det maximala värdet i doubleVecList.
min(doubleVecList) dubbel Returnerar minimivärdet i doubleVecList.
norm(doubleVecList) dubbel Returnerar tvånormen för vektorn som skapas från doubleVecList.
percentile(doubleVec v, double p) dubbel Returnerar percentilelementet i vektorn v.
rand() dubbel Returnerar ett slumpmässigt värde mellan 0,0 och 1,0.
range(doubleVecList) dubbel Returnerar skillnaden mellan värdena min och max i doubleVecList.
round(double) dubbel Returnerar det närmaste heltalsvärdet till det dubbla (i flyttalformat) och avrundar halvvägs från noll.
round(doubleVecList) doubleVec Returnerar komponenten för round doubleVecList.
std(doubleVecList) dubbel Returnerar standardavvikelsen för exempelvärdena i doubleVecList.
stop() Stoppar utvärderingen av autoskalningsuttrycket.
sum(doubleVecList) dubbel 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) dubbel Returnerar värdet för elementet som finns på plats i i vektor v, med ett startindex på noll.

Vissa av de funktioner som beskrivs i föregående tabell kan acceptera en lista som ett argument. Kommaavgränsad lista är en kombination av dubbel och doubleVec. Till 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). Samtal 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 .

Mätvärde 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
- $UsableNodeCount

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 Aktiv, Väntar och Slutförd. 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

Erhåll exempeldata

Kärnåtgärden för en autoskalningsformel är att hämta uppgifts- 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 poolberäkningsnoderna baserat på de värden som den hämtar. Tjänstdefinierade variabler är objekt som tillhandahåller metoder för åtkomst till 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 erhålls 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 exempel under en viss tidsperiod vara tillgängliga för utvärdering med hjälp av en formel.

- doubleVec GetSample(double count): Anger antalet exempel som ska hämtas från de senaste exemplen som har 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 som visas nedan.

- doubleVec GetSample((timestamp or timeinterval) startTime [, double samplePercent]): Anger en tidsram för insamling av exempeldata. Du kan också ange procentandelen exempel 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 insamling av data, med både starttid och sluttid. Som nämnts ovan finns det en fördröjning mellan när ett exempel 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 exempel som har 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 exempel som är tillgängliga för ett visst tidsintervall. 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. Dessa exempel registreras var 30:e sekund av Batch-tjänsten. Det finns dock vanligtvis en fördröjning mellan när dessa exempel registrerades och när de görs tillgängliga för (och läss av) dina autoskalningsformler. Dessutom kanske exempel inte registreras för ett visst intervall på grund av faktorer som nätverk eller andra infrastrukturproblem.

Exempelprocent

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 registrerats 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 prover registreras var 30:e sekund inom det tidsintervallet på 10 minuter skulle det maximala totala antalet prover som registrerats av Batch vara 20 prover (2 per minut). På grund av den inneboende svarstiden för rapporteringsmekanismen och andra problem i Azure kan det dock bara finnas 15 exempel som är tillgängliga för din autoskalningsformel för läsning. För den 10 minuter långa perioden kan endast 75 procent av det totala antalet registrerade prover vara tillgängliga 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 måste 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 Batch utvärderar ovanstående rad returneras ett intervall med exempel som en värdevektor. Till exempel:

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

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

Om du vill vara extra försiktig kan du framtvinga att en formelutvärdering 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 i 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 för exempel att spridas 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 GetSample(1) i dina autoskalningsformler. Detta beror i GetSample(1) huvudsak säger till Batch-tjänsten, "Ge mig det sista exemplet du hade, oavsett hur länge sedan du hämtade den." 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 formeln 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 du ett exempel på en autoskalningsformel som kan fatta verkliga skalningsbeslut och göra justeringar.

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

  • Öka målantalet för 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 formeln ökar antalet noder under hög CPU-användning. Du 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;

Om du vill minska antalet dedikerade noder under låg CPU-användning anger nästa instruktion i formeln 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änds det aktuella värdet $totalDedicatedNodes för ifyllt i -instruktionen ovan.

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

Begränsa nu målantalet för dedikerade beräkningsnoder till högst 400.

$TargetDedicatedNodes = min(400, $totalDedicatedNodes);

Se slutligen 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;

Kommentar

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

Kommentar

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:erna, 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 den 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 autoskalningsaktiverad pool ska du inte ange parametern targetDedicatedNodes eller parametern targetLowPriorityNodes i anropet till CreatePool. Ange AutoScaleEnabled i stället egenskaperna 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.

Dricks

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

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="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)

Dricks

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. Till exempel:

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

  • Om automatisk skalning 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 automatisk skalning 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.

Kommentar

Om du angav värden för parametrarna CreatePool targetDedicatedNodes eller targetLowPriorityNodes för 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 autoskalningsaktiverad 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 autoskalning för en befintlig autoskalningsaktiverad 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:

Följande Batch .NET-exempel utvärderar en autoskalningsformel. Om poolen inte redan använder automatisk skalning aktiverar du 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)
{
    // 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);
    }
}

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

Vi rekommenderar att du regelbundet kontrollerar Batch-tjänstens utvärdering av autoskalningsformeln. 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 i poolen:

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

I följande C#-exempel används Batch .NET-biblioteket för att skriva ut information om den senaste autoskalningskörningen i poolen 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);

Exempelutdata 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 autoskalning med hjälp av pool autoskalningshändelser

Du kan också kontrollera den automatiska skalningshistoriken genom att fråga PoolAutoScaleEvent. Batch genererar den här händelsen 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

Nu ska vi 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 din UTC-förskjutning. 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 sommartid, om tillämpligt.

Exempel 2: Aktivitetsbaserad justering

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

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

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 under de första 10 minuterna av poolens livscykel.
  • Efter 10 minuter hämtar du det maximala värdet för antalet aktiva aktiviteter som körs och 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