Partilhar via


Criar uma fórmula para dimensionar automaticamente nós de computação em um pool de lotes

O Lote do Azure pode dimensionar pools automaticamente com base nos parâmetros que você definir, economizando tempo e dinheiro. Com o dimensionamento automático, o Batch adiciona dinamicamente nós a um pool à medida que as demandas de tarefas aumentam e remove nós de computação à medida que as demandas de tarefas diminuem.

Para habilitar o dimensionamento automático em um pool de nós de computação, associe o pool a uma fórmula de dimensionamento automático que você define. O serviço Batch usa a fórmula de dimensionamento automático para determinar quantos nós são necessários para executar sua carga de trabalho. Esses nós podem ser nós dedicados ou nós do Azure Spot. O Batch revisa periodicamente os dados de métricas de serviço e os usa para ajustar o número de nós no pool com base em sua fórmula e em um intervalo que você definir.

Você pode habilitar o dimensionamento automático ao criar um pool ou aplicá-lo a um pool existente. O Batch permite avaliar suas fórmulas antes de atribuí-las a pools e monitorar o status de execuções de dimensionamento automático. Depois de configurar um pool com dimensionamento automático, você pode fazer alterações na fórmula mais tarde.

Importante

Ao criar uma conta de lote, você pode especificar o modo de alocação de pool, que determina se os pools são alocados em uma assinatura de serviço de lote (o padrão) ou em sua assinatura de usuário. Se você criou sua conta de lote com a configuração padrão do serviço de lote, sua conta será limitada a um número máximo de núcleos que podem ser usados para processamento. O serviço Batch dimensiona nós de computação somente até esse limite principal. Por esse motivo, o serviço Batch pode não atingir o número de destino de nós de computação especificado por uma fórmula de dimensionamento automático. Para saber como exibir e aumentar suas cotas de conta, consulte Cotas e limites para o serviço Lote do Azure.

Se você criou sua conta com o modo de assinatura de usuário, sua conta compartilha a cota principal da assinatura. Para obter mais informações, veja Virtual Machines limits (Limites das Máquinas Virtuais), em Azure subscription and service limits, quotas, and constraints (Limites, quotas e limitações das subscrições e serviços do Azure).

Dimensionar fórmulas automaticamente

Uma fórmula de dimensionamento automático é um valor de cadeia de caracteres que você define que contém uma ou mais instruções. A fórmula de dimensionamento automático é atribuída ao elemento autoScaleFormula de um pool (Batch REST) ou à propriedade CloudPool.AutoScaleFormula (Batch .NET). O serviço Batch usa sua fórmula para determinar o número de destino de nós de computação no pool para o próximo intervalo de processamento. A cadeia de caracteres da fórmula não pode exceder 8 KB, pode incluir até 100 instruções separadas por ponto-e-vírgula e pode incluir quebras de linha e comentários.

Você pode pensar em fórmulas de dimensionamento automático como uma "linguagem" de dimensionamento automático em lote. As instruções de fórmula são expressões de formação livre que podem incluir variáveis definidas pelo serviço, que são definidas pelo serviço Batch, e variáveis definidas pelo usuário. As fórmulas podem executar várias operações nesses valores usando tipos, operadores e funções internos. Por exemplo, uma instrução pode assumir a seguinte forma:

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

As fórmulas geralmente contêm várias instruções que executam operações em valores obtidos em instruções anteriores. Por exemplo, primeiro você obtém um valor para variable1e, em seguida, passa-o para uma função para preencher variable2:

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

Inclua essas instruções em sua fórmula de dimensionamento automático para chegar a um número de destino de nós de computação. Os nós dedicados e os nós spot têm suas próprias configurações de destino. Uma fórmula de dimensionamento automático pode incluir um valor de destino para nós dedicados, um valor de destino para nós spot ou ambos.

O número de nós de destino pode ser maior, menor ou igual ao número atual de nós desse tipo no pool. O Batch avalia a fórmula de dimensionamento automático de um pool em intervalos de dimensionamento automático específicos. O lote ajusta o número de destino de cada tipo de nó no pool para o número que sua fórmula de dimensionamento automático especifica no momento da avaliação.

Fórmulas de dimensionamento automático de amostra

Os exemplos a seguir mostram duas fórmulas de escala automática, que podem ser ajustadas para funcionar na maioria dos cenários. As variáveis startingNumberOfVMs e maxNumberofVMs as fórmulas de exemplo podem ser ajustadas às suas necessidades.

Tarefas pendentes

Com essa fórmula de dimensionamento automático, o pool é inicialmente criado com uma única VM. A $PendingTasks métrica define o número de tarefas em execução ou enfileiradas. A fórmula localiza o número médio de tarefas pendentes nos últimos 180 segundos e define a $TargetDedicatedNodes variável de acordo. A fórmula garante que o número de destino de nós dedicados nunca exceda 25 VMs. À medida que novas tarefas são enviadas, o pool cresce automaticamente. À medida que as tarefas são concluídas, as VMs ficam livres e a fórmula de dimensionamento automático reduz o pool.

Esta fórmula dimensiona nós dedicados, mas pode ser modificada para ser aplicada também a nós spot de escala.

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;

Importante

Atualmente, o Batch Service tem limitações com a resolução das tarefas pendentes. Quando uma tarefa é adicionada ao trabalho, ela também é adicionada a uma fila interna usada pelo serviço em lote para agendamento. Se a tarefa for excluída antes de poder ser agendada, ela poderá persistir dentro da fila, fazendo com que ela ainda seja contada no $PendingTasks. Essa tarefa excluída acabará sendo eliminada da fila quando o Lote tiver a chance de extrair tarefas da fila para agendar com nós ociosos no pool de lotes.

Nós antecipados

Este exemplo cria um pool que começa com 25 nós Spot. Toda vez que um nó Spot é antecipado, ele é substituído por um nó dedicado. Como no primeiro exemplo, a maxNumberofVMs variável impede que o pool exceda 25 VMs. Este exemplo é útil para aproveitar as VMs spot e, ao mesmo tempo, garantir que apenas um número fixo de preempções ocorra durante o tempo de vida do pool.

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

Você aprenderá mais sobre como criar fórmulas de dimensionamento automático e verá mais exemplos de fórmulas de dimensionamento automático mais adiante neste artigo.

Variáveis

Você pode usar variáveis definidas pelo serviço e definidas pelo usuário em suas fórmulas de dimensionamento automático.

As variáveis definidas pelo serviço são incorporadas ao serviço em lote. Algumas variáveis definidas pelo serviço são leitura-gravação e outras são somente leitura.

As variáveis definidas pelo usuário são variáveis que você define. No exemplo anterior, $TargetDedicatedNodes e $PendingTasks são variáveis definidas pelo serviço, enquanto startingNumberOfVMs e maxNumberofVMs são variáveis definidas pelo usuário.

Nota

As variáveis definidas pelo serviço são sempre precedidas por um cifrão ($). Para variáveis definidas pelo usuário, o cifrão é opcional.

As tabelas a seguir mostram as variáveis leitura-gravação e somente leitura definidas pelo serviço Batch.

Variáveis definidas pelo serviço de leitura/gravação

Você pode obter e definir os valores dessas variáveis definidas pelo serviço para gerenciar o número de nós de computação em um pool.

Variável Description
$TargetDedicatedNodes O número de destino de nós de computação dedicados para o pool. Especificado como um destino porque um pool nem sempre pode atingir o número desejado de nós. Por exemplo, se o número de destino de nós dedicados for modificado por uma avaliação de escala automática antes que o pool atinja o destino inicial, o pool pode não atingir o destino.

Um pool em uma conta criada no modo de serviço em lote pode não atingir seu destino se o destino exceder um nó de conta de lote ou cota principal. Um pool em uma conta criada no modo de assinatura de usuário pode não atingir seu destino se o destino exceder a cota principal compartilhada para a assinatura.
$TargetLowPriorityNodes O número de destino dos nós de computação spot para o pool. Especificado como um destino porque um pool nem sempre pode atingir o número desejado de nós. Por exemplo, se o número de destino dos nós Spot for modificado por uma avaliação de escala automática antes que o pool atinja o destino inicial, o pool pode não atingir o destino. Um pool também pode não atingir sua meta se o destino exceder um nó de conta de lote ou cota principal.

Para obter mais informações sobre nós de computação spot, consulte Usar VMs spot com lote.
$NodeDeallocationOption A ação que ocorre quando nós de computação são removidos de um pool. Os valores possíveis são:
- requeue: O valor padrão. Encerra as tarefas imediatamente e as coloca de volta na fila de trabalhos para que sejam reagendadas. Essa ação garante que o número de nós de destino seja atingido o mais rápido possível. No entanto, pode ser menos eficiente, porque todas as tarefas em execução são interrompidas e, em seguida, devem ser reiniciadas.
- encerrar: encerra tarefas imediatamente e as remove da fila de trabalhos.
- taskcompletion: Aguarda a conclusão das tarefas em execução no momento e, em seguida, remove o nó do pool. Use esta opção para evitar que as tarefas sejam interrompidas e colocadas novamente na fila, desperdiçando qualquer trabalho que a tarefa tenha feito.
- retaineddata: Aguarda que todos os dados locais retidos na tarefa no nó sejam limpos antes de remover o nó do pool.

Nota

A $TargetDedicatedNodes variável também pode ser especificada usando o alias $TargetDedicated. Da mesma forma, a $TargetLowPriorityNodes variável pode ser especificada usando o alias $TargetLowPriority. Se a variável totalmente nomeada e seu alias forem definidos pela fórmula, o valor atribuído à variável totalmente nomeada terá precedência.

Variáveis definidas pelo serviço somente leitura

Você pode obter o valor dessas variáveis definidas pelo serviço para fazer ajustes baseados em métricas do serviço em lote.

Importante

Atualmente, as tarefas de liberação de trabalho não estão incluídas em variáveis que fornecem contagens de tarefas, como $ActiveTasks e $PendingTasks. Dependendo da sua fórmula de dimensionamento automático, isso pode resultar na remoção de nós sem nós disponíveis para executar tarefas de liberação de trabalho.

Gorjeta

Essas variáveis definidas pelo serviço somente leitura são objetos que fornecem vários métodos para acessar dados associados a cada um. Para obter mais informações, consulte Obter dados de exemplo mais adiante neste artigo.

Variável Description
$CPUPercent A porcentagem média de uso da CPU.
$ActiveTasks O número de tarefas que estão prontas para serem executadas, mas ainda não estão em execução. Isso inclui todas as tarefas que estão no estado ativo e cujas dependências foram satisfeitas. Todas as tarefas que estão no estado ativo, mas cujas dependências não foram satisfeitas, são excluídas da $ActiveTasks contagem. Para uma tarefa de várias instâncias, $ActiveTasks inclui o número de instâncias definidas na tarefa.
$RunningTasks O número de tarefas em um estado de execução.
$PendingTasks A soma de $ActiveTasks e $RunningTasks.
$SucceededTasks O número de tarefas concluídas com êxito.
$FailedTasks O número de tarefas que falharam.
$TaskSlotsPerNode O número de slots de tarefas que podem ser usados para executar tarefas simultâneas em um único nó de computação no pool.
$CurrentDedicatedNodes O número atual de nós de computação dedicados.
$CurrentLowPriorityNodes O número atual de nós de computação spot, incluindo quaisquer nós que tenham sido antecipados.
$UsableNodeCount O número de nós de computação utilizáveis.
$PreemptedNodeCount O número de nós no pool que estão em um estado antecipado.

Nota

Use $RunningTasks ao dimensionar com base no número de tarefas em execução em um determinado momento e $ActiveTasks ao dimensionar com base no número de tarefas que estão enfileiradas para serem executadas.

Tipos

As fórmulas de dimensionamento automático suportam os seguintes tipos:

  • duplo
  • doubleVec
  • doubleVecList
  • string
  • carimbo de data/hora - uma estrutura composta que contém os seguintes membros:
    • ano
    • Mês (1-12)
    • Dia (1-31)
    • dia da semana (no formato de número; por exemplo, 1 para segunda-feira)
    • hora (no formato de número de 24 horas; por exemplo, 13 significa 13h)
    • minuto (00-59)
    • segundo (00-59)
  • intervalo de tempo
    • TimeInterval_Zero
    • TimeInterval_100ns
    • TimeInterval_Microsecond
    • TimeInterval_Millisecond
    • TimeInterval_Second
    • TimeInterval_Minute
    • TimeInterval_Hour
    • TimeInterval_Day
    • TimeInterval_Week
    • TimeInterval_Year

Operações

Essas operações são permitidas nos tipos listados na seção anterior.

Operação Operadores suportados Tipo de resultado
duplo operador duplo +, -, *, / duplo
intervalo de tempo duplo do operador * intervalo de tempo
operador doubleVec duplo +, -, *, / doubleVec
operador doubleVec doubleVec +, -, *, / doubleVec
operador de intervalo de tempo duplo *, / intervalo de tempo
operador timeinterval timeinterval +, - intervalo de tempo
timeStamp de data/hora do operador TimeInterval + carimbo de data/hora
timestamp operador timeinterval + carimbo de data/hora
carimbo de data/hora do operador de carimbo de data/hora - intervalo de tempo
operador duplo -, ! duplo
intervalo de tempo do operador - intervalo de tempo
duplo operador duplo <, <=, ==, >=, >, != duplo
string operador string <, <=, ==, >=, >, != duplo
carimbo de data/hora do operador de carimbo de data/hora <, <=, ==, >=, >, != duplo
operador timeinterval timeinterval <, <=, ==, >=, >, != duplo
duplo operador duplo &&, || duplo

O teste de um duplo com um operador ternário (double ? statement1 : statement2), resulta em diferente de zero como verdadeiro e zero como falso.

Funções

Você pode usar essas funções predefinidas ao definir uma fórmula de escala automática.

Function Tipo de retorno Description
avg(doubleVecList) duplo Retorna o valor médio para todos os valores no doubleVecList.
ceil (duplo) duplo Devolve o menor valor inteiro não inferior ao dobro.
ceil(doubleVecList) doubleVec Retorna o component-wise ceil do doubleVecList.
andar (duplo) duplo Devolve o maior valor inteiro não superior ao duplo.
andar (doubleVecList) doubleVec Retorna o component-wise floor do doubleVecList.
len(doubleVecList) duplo Retorna o comprimento do vetor que é criado a partir do doubleVecList.
lg (duplo) duplo Retorna a base de log 2 do duplo.
lg(doubleVecList) doubleVec Retorna o component-wise lg do doubleVecList.
ln (duplo) duplo Devolve o registo natural do duplo.
ln(doubleVecList) doubleVec Retorna o component-wise ln do doubleVecList.
log (duplo) duplo Retorna a base de log 10 do duplo.
log(doubleVecList) doubleVec Retorna o component-wise log do doubleVecList.
max(doubleVecList) duplo Retorna o valor máximo no doubleVecList.
min (doubleVecList) duplo Retorna o valor mínimo no doubleVecList.
norma (doubleVecList) duplo Retorna as duas normas do vetor que é criado a partir do doubleVecList.
percentil (doubleVec v, double p) duplo Devolve o elemento percentil do vetor v.
rand() duplo Devolve um valor aleatório entre 0,0 e 1,0.
intervalo(doubleVecList) duplo Devolve a diferença entre os valores min e max no doubleVecList.
rodada (dupla) duplo Retorna o valor inteiro mais próximo para o duplo (no formato de ponto flutuante), arredondando maiúsculas e minúsculas para longe de zero.
rodada (doubleVecList) doubleVec Retorna o component-wise round do doubleVecList.
std(doubleVecList) duplo Retorna o desvio padrão de amostra dos valores no doubleVecList.
parar() Interrompe a avaliação da expressão de dimensionamento automático.
soma(doubleVecList) duplo Retorna a soma de todos os componentes do doubleVecList.
time(string dateTime="") carimbo de data/hora Retorna o carimbo de data/hora da hora atual se nenhum parâmetro for passado, ou o carimbo de data/hora da cadeia de caracteres dateTime, se isso for passado. Os formatos dateTime suportados são W3C-DTF e RFC 1123.
val (doubleVec v, duplo i) duplo Retorna o valor do elemento que está no local i no vetor v, com um índice inicial de zero.

Algumas das funções descritas na tabela anterior podem aceitar uma lista como argumento. A lista separada por vírgulas é qualquer combinação de double e doubleVec. Por exemplo:

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

O valor doubleVecList é convertido em um único doubleVec antes da avaliação. Por exemplo, se v = [1,2,3], então chamar avg(v) é equivalente a chamar avg(1,2,3). Ligar avg(v, 7) é equivalente a chamar avg(1,2,3,7).

Métricas

Você pode usar métricas de recursos e tarefas ao definir uma fórmula. Você ajusta o número de destino de nós dedicados no pool com base nos dados de métricas obtidos e avaliados. Para obter mais informações sobre cada métrica, consulte a seção Variáveis .

Métrico Description
Recurso As métricas de recursos são baseadas na CPU, na largura de banda, no uso de memória dos nós de computação e no número de nós.

Essas variáveis definidas pelo serviço são úteis para fazer ajustes com base na contagem de nós:
- $TargetDedicatedNodes
- $TargetLowPriorityNodes
- $CurrentDedicatedNodes
- $CurrentLowPriorityNodes
- $PreemptedNodeCount
- $UsableNodeCount

Essas variáveis definidas pelo serviço são úteis para fazer ajustes com base no uso de recursos do nó:
- $CPUPercent
Task As métricas de tarefas são baseadas no status de tarefas, como Ativas, Pendentes e Concluídas. As seguintes variáveis definidas pelo serviço são úteis para fazer ajustes no tamanho do pool com base nas métricas da tarefa:
- $ActiveTasks
- $RunningTasks
- $PendingTasks
- $SucceededTasks
- $FailedTasks

Obter dados de exemplo

A operação principal de uma fórmula de dimensionamento automático é obter dados de métricas de tarefas e recursos (amostras) e, em seguida, ajustar o tamanho do pool com base nesses dados. Como tal, é importante ter uma compreensão clara de como as fórmulas de escala automática interagem com as amostras.

Métodos

As fórmulas de dimensionamento automático atuam em amostras de dados métricos fornecidos pelo serviço Batch. Uma fórmula aumenta ou reduz os nós de computação do pool com base nos valores que obtém. As variáveis definidas pelo serviço são objetos que fornecem métodos para acessar dados associados a esse objeto. Por exemplo, a expressão a seguir mostra uma solicitação para obter os últimos cinco minutos de uso da CPU:

$CPUPercent.GetSample(TimeInterval_Minute * 5)

Os métodos a seguir podem ser usados para obter dados de exemplo sobre variáveis definidas pelo serviço.

Método Description
GetSample() O GetSample() método retorna um vetor de amostras de dados.

Uma amostra equivale a 30 segundos de dados de métricas. Ou seja, as amostras são obtidas a cada 30 segundos. Mas, como observado abaixo, há um atraso entre quando uma amostra é coletada e quando está disponível para uma fórmula. Como tal, nem todas as amostras de um determinado período de tempo podem estar disponíveis para avaliação através de uma fórmula.

- doubleVec GetSample(double count): Especifica o número de amostras a obter das amostras mais recentes que foram coletadas. GetSample(1) Devolve a última amostra disponível. Para métricas como $CPUPercent, no entanto, GetSample(1) não deve ser usado, porque é impossível saber quando a amostra foi coletada. Pode ser recente ou, devido a problemas do sistema, pode ser muito mais antigo. Nesses casos, é melhor usar um intervalo de tempo, como mostrado abaixo.

- doubleVec GetSample((timestamp or timeinterval) startTime [, double samplePercent]): Especifica um período de tempo para a coleta de dados de exemplo. Opcionalmente, ele também especifica a porcentagem de amostras que devem estar disponíveis no período solicitado. Por exemplo, $CPUPercent.GetSample(TimeInterval_Minute * 10) retornaria 20 amostras se todas as amostras dos últimos 10 minutos estiverem presentes no CPUPercent histórico. Se o último minuto do histórico não estivesse disponível, apenas 18 amostras seriam devolvidas. Neste caso $CPUPercent.GetSample(TimeInterval_Minute * 10, 95) , falharia porque apenas 90% das amostras estão disponíveis, mas $CPUPercent.GetSample(TimeInterval_Minute * 10, 80) teria sucesso.

- doubleVec GetSample((timestamp or timeinterval) startTime, (timestamp or timeinterval) endTime [, double samplePercent]): Especifica um período de tempo para a coleta de dados, com uma hora de início e uma hora de término. Como mencionado acima, há um atraso entre quando uma amostra é coletada e quando ela fica disponível para uma fórmula. Considere esse atraso ao usar o GetSample método. Veja GetSamplePercent abaixo.
GetSamplePeriod() Devolve o período de amostras que foram colhidas num conjunto de dados de amostra histórico.
Contagem() Devolve o número total de amostras no histórico de métricas.
HistóriaBeginTime() Retorna o carimbo de data/hora da amostra de dados mais antiga disponível para a métrica.
GetSamplePercent() Devolve a percentagem de amostras disponíveis para um determinado intervalo de tempo. Por exemplo, doubleVec GetSamplePercent( (timestamp or timeinterval) startTime [, (timestamp or timeinterval) endTime] ). Como o GetSample método falhará se a porcentagem de amostras retornadas for menor do que a samplePercent especificada, você pode usar o GetSamplePercent método para verificar primeiro. Em seguida, você pode executar uma ação alternativa se amostras insuficientes estiverem presentes, sem interromper a avaliação automática de dimensionamento.

Exemplos

O serviço Lote coleta periodicamente amostras de métricas de tarefas e recursos e as disponibiliza para suas fórmulas de dimensionamento automático. Essas amostras são registradas a cada 30 segundos pelo serviço Batch. No entanto, normalmente há um atraso entre quando essas amostras foram gravadas e quando elas são disponibilizadas (e lidas por) suas fórmulas de escala automática. Além disso, as amostras podem não ser gravadas para um intervalo específico devido a fatores como problemas de rede ou outros problemas de infraestrutura.

Percentagem da amostra

Quando samplePercent é passado para o GetSample() método ou o GetSamplePercent() método é chamado, porcentagem refere-se a uma comparação entre o número total possível de amostras registradas pelo serviço de lote e o número de amostras que estão disponíveis para sua fórmula de escala automática.

Vejamos um período de tempo de 10 minutos como exemplo. Como as amostras são registradas a cada 30 segundos dentro desse período de tempo de 10 minutos, o número total máximo de amostras registradas pelo Batch seria de 20 amostras (2 por minuto). No entanto, devido à latência inerente do mecanismo de relatório e outros problemas no Azure, pode haver apenas 15 exemplos disponíveis para sua fórmula de dimensionamento automático para leitura. Assim, por exemplo, para esse período de 10 minutos, apenas 75% do número total de amostras registadas pode estar disponível para a sua fórmula.

GetSample() e intervalos de amostras

Suas fórmulas de dimensionamento automático crescem e diminuem seus pools adicionando ou removendo nós. Como os nós custam dinheiro, certifique-se de que suas fórmulas usem um método inteligente de análise baseado em dados suficientes. É recomendável usar uma análise de tipo de tendência em suas fórmulas. Este tipo cresce e encolhe suas piscinas com base em uma variedade de amostras coletadas.

Para fazer isso, use GetSample(interval look-back start, interval look-back end) para retornar um vetor de amostras:

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

Quando Batch avalia a linha acima, ele retorna um intervalo de amostras como um vetor de valores. Por exemplo:

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

Depois de coletar o vetor de amostras, você pode usar funções como min(), max()e avg() para derivar valores significativos do intervalo coletado.

Para ter cuidado extra, você pode forçar uma avaliação de fórmula a falhar se menos de uma determinada porcentagem de amostra estiver disponível para um determinado período de tempo. Quando você força uma avaliação de fórmula a falhar, instrui o Batch a interromper a avaliação adicional da fórmula se a porcentagem especificada de amostras não estiver disponível. Neste caso, nenhuma alteração é feita no tamanho da piscina. Para especificar uma percentagem necessária de amostras para que a avaliação seja bem-sucedida, especifique-a como o terceiro parâmetro para GetSample(). Aqui, um requisito de 75% das amostras é especificado:

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

Como pode haver um atraso na disponibilidade da amostra, você deve sempre especificar um intervalo de tempo com uma hora de início de retrospetiva com mais de um minuto. As amostras demoram aproximadamente um minuto a propagar-se através do sistema, pelo que as amostras no intervalo (0 * TimeInterval_Second, 60 * TimeInterval_Second) podem não estar disponíveis. Novamente, você pode usar o parâmetro de porcentagem de para forçar um requisito de porcentagem de GetSample() amostra específico.

Importante

É altamente recomendável que você evite confiar apenas em GetSample(1) suas fórmulas de escala automática. Isso ocorre porque GetSample(1) essencialmente diz ao serviço Batch: "Dê-me a última amostra que você tinha, não importa há quanto tempo você a recuperou." Como é apenas uma amostra única, e pode ser uma amostra mais antiga, pode não ser representativa da imagem maior do estado recente da tarefa ou do recurso. Se você usar GetSample(1)o , certifique-se de que ele faz parte de uma instrução maior e não é o único ponto de dados no qual sua fórmula se baseia.

Escrever uma fórmula de dimensionamento automático

Você cria uma fórmula de escala automática formando instruções que usam os componentes acima e, em seguida, combina essas instruções em uma fórmula completa. Nesta seção, você cria um exemplo de fórmula de dimensionamento automático que pode executar decisões de dimensionamento do mundo real e fazer ajustes.

Primeiro, vamos definir os requisitos para nossa nova fórmula de escala automática. A fórmula deve:

  • Aumente o número de destino de nós de computação dedicados em um pool se o uso da CPU for alto.
  • Diminua o número de destino de nós de computação dedicados em um pool quando o uso da CPU for baixo.
  • Sempre restrinja o número máximo de nós dedicados a 400.
  • Ao reduzir o número de nós, não remova os nós que estão executando tarefas; Se necessário, aguarde até que as tarefas tenham terminado antes de remover nós.

A primeira instrução na fórmula aumenta o número de nós durante o alto uso da CPU. Você define uma instrução que preenche uma variável definida pelo usuário ($totalDedicatedNodes) com um valor que é 110% do número de destino atual de nós dedicados, mas somente se o uso médio mínimo da CPU durante os últimos 10 minutos estiver acima de 70%. Caso contrário, ele usa o valor para o número atual de nós dedicados.

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

Para diminuir o número de nós dedicados durante o baixo uso da CPU, a próxima instrução na fórmula define a mesma $totalDedicatedNodes variável para 90% do número de destino atual de nós dedicados, se o uso médio da CPU nos últimos 60 minutos foi inferior a 20%. Caso contrário, ele usa o valor atual de preenchido $totalDedicatedNodes na instrução acima.

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

Agora, limite o número de destino de nós de computação dedicados a um máximo de 400.

$TargetDedicatedNodes = min(400, $totalDedicatedNodes);

Por fim, certifique-se de que os nós não sejam removidos até que suas tarefas sejam concluídas.

$NodeDeallocationOption = taskcompletion;

Eis a fórmula completa:

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

Nota

Se desejar, você pode incluir comentários e quebras de linha em cadeias de caracteres de fórmula. Também esteja ciente de que a falta de ponto-e-vírgula pode resultar em erros de avaliação.

Intervalo de dimensionamento automático

Por padrão, o serviço Lote ajusta o tamanho de um pool de acordo com sua fórmula de dimensionamento automático a cada 15 minutos. Esse intervalo é configurável usando as seguintes propriedades do pool:

O intervalo mínimo é de cinco minutos e o máximo de 168 horas. Se um intervalo fora desse intervalo for especificado, o serviço em lote retornará um erro de solicitação incorreta (400).

Nota

Atualmente, o dimensionamento automático não se destina a responder a alterações em menos de um minuto, mas sim a ajustar o tamanho do pool gradualmente à medida que você executa uma carga de trabalho.

Criar um pool habilitado para dimensionamento automático com SDKs de lote

O dimensionamento automático do pool pode ser configurado usando qualquer um dos SDKs de lote, os cmdlets do PowerShell em lote da API REST em lote e a CLI de lote. Nesta seção, você pode ver exemplos para .NET e Python.

.NET

Para criar um pool com o dimensionamento automático habilitado no .NET, siga estas etapas:

  1. Crie o pool com BatchClient.PoolOperations.CreatePool.
  2. Defina a propriedade CloudPool.AutoScaleEnabled como true.
  3. Defina a propriedade CloudPool.AutoScaleFormula com sua fórmula de dimensionamento automático.
  4. (Opcional) Defina a propriedade CloudPool.AutoScaleEvaluationInterval (o padrão é 15 minutos).
  5. Confirme o pool com CloudPool.Commit ou CommitAsync.

O exemplo a seguir cria um pool habilitado para dimensionamento automático no .NET. A fórmula de dimensionamento automático do pool define o número alvo de nós dedicados para 5 às segundas-feiras e para 1 em todos os outros dias da semana. O intervalo de dimensionamento automático é definido como 30 minutos. Neste e nos outros trechos de C# neste artigo, myBatchClient é uma instância inicializada corretamente da classe 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();

Importante

Ao criar um pool habilitado para dimensionamento automático, não especifique o parâmetro targetDedicatedNodes ou o parâmetro targetLowPriorityNodes na chamada para CreatePool. Em vez disso, especifique as AutoScaleEnabled propriedades e AutoScaleFormula no pool. Os valores para essas propriedades determinam o número de destino de cada tipo de nó.

Para redimensionar manualmente um pool habilitado para dimensionamento automático (por exemplo, com BatchClient.PoolOperations.ResizePoolAsync), você deve primeiro desabilitar o dimensionamento automático no pool e, em seguida, redimensioná-lo.

Gorjeta

Para obter mais exemplos de uso do SDK do .NET, consulte o repositório de início rápido do Batch .NET no GitHub.

Python

Para criar um pool habilitado para dimensionamento automático com o SDK do Python:

  1. Crie um pool e especifique sua configuração.
  2. Adicione o pool ao cliente de serviço.
  3. Habilite o dimensionamento automático no pool com uma fórmula que você escreve.

O exemplo a seguir ilustra essas etapas.

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

Gorjeta

Para obter mais exemplos de uso do Python SDK, consulte o repositório Batch Python Quickstart no GitHub.

Habilitar o dimensionamento automático em um pool existente

Cada SDK de lote fornece uma maneira de habilitar o dimensionamento automático. Por exemplo:

Ao habilitar o dimensionamento automático em um pool existente, lembre-se:

  • Se o dimensionamento automático estiver desabilitado no momento no pool, você deverá especificar uma fórmula de dimensionamento automático válida ao emitir a solicitação. Opcionalmente, você pode especificar um intervalo de dimensionamento automático. Se você não especificar um intervalo, o valor padrão de 15 minutos será usado.
  • Se o dimensionamento automático estiver habilitado no pool no momento, você poderá especificar uma nova fórmula, um novo intervalo ou ambos. Você deve especificar pelo menos uma dessas propriedades.
    • Se você especificar um novo intervalo de dimensionamento automático, o agendamento existente será interrompido e um novo agendamento será iniciado. A hora de início da nova agenda é a hora em que a solicitação para habilitar o dimensionamento automático foi emitida.
    • Se você omitir a fórmula ou o intervalo de dimensionamento automático, o serviço Lote continuará a usar o valor atual dessa configuração.

Nota

Se você especificou valores para os parâmetros targetDedicatedNodes ou targetLowPriorityNodes do CreatePool método quando criou o pool no .NET, ou para os parâmetros comparáveis em outro idioma, esses valores serão ignorados quando a fórmula de dimensionamento automático for avaliada.

Este exemplo de C# usa a biblioteca .NET em lote para habilitar o dimensionamento automático em um pool existente.

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

Atualizar uma fórmula de dimensionamento automático

Para atualizar a fórmula em um pool existente habilitado para dimensionamento automático, chame a operação para habilitar o dimensionamento automático novamente com a nova fórmula. Por exemplo, se o dimensionamento automático já estiver habilitado quando myexistingpool o seguinte código .NET for executado, sua fórmula de dimensionamento automático será substituída pelo conteúdo do myNewFormula.

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

Atualizar o intervalo de escala automática

Para atualizar o intervalo de avaliação de escala automática de um pool habilitado para dimensionamento automático existente, chame a operação para habilitar o dimensionamento automático novamente com o novo intervalo. Por exemplo, para definir o intervalo de avaliação de escala automática para 60 minutos para um pool que já está habilitado para dimensionamento automático no .NET:

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

Avaliar uma fórmula de escala automática

Você pode avaliar uma fórmula antes de aplicá-la a um pool. Isso permite que você teste os resultados da fórmula antes de colocá-la em produção.

Antes de avaliar uma fórmula de escala automática, você deve primeiro habilitar o dimensionamento automático no pool com uma fórmula válida, como a fórmula $TargetDedicatedNodes = 0de uma linha. Em seguida, utilize uma das seguintes opções para avaliar a fórmula que pretende testar:

O exemplo .NET de lote a seguir avalia uma fórmula de escala automática. Se o pool ainda não usar o dimensionamento automático, ative-o primeiro.

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

A avaliação bem-sucedida da fórmula mostrada neste trecho de código produz resultados semelhantes a:

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

Obter informações sobre execuções em escala automática

Recomenda-se verificar periodicamente a avaliação do serviço Batch da sua fórmula de escala automática. Para fazer isso, obtenha (ou atualize) uma referência ao pool e, em seguida, examine as propriedades de sua última execução de escala automática.

No Batch .NET, a propriedade CloudPool.AutoScaleRun tem várias propriedades que fornecem informações sobre a execução de dimensionamento automático mais recente executada no pool:

Na API REST, as informações sobre um pool incluem as informações de execução de dimensionamento automático mais recentes na propriedade autoScaleRun .

O exemplo C# a seguir usa a biblioteca .NET em lote para imprimir informações sobre a última execução de dimensionamento automático no 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);

Exemplo de saída do exemplo anterior:

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:

Obtenha o histórico de execução do dimensionamento automático usando eventos de dimensionamento automático do pool

Você também pode verificar o histórico de dimensionamento automático consultando PoolAutoScaleEvent. O Batch emite esse evento para registrar cada ocorrência de avaliação e execução de fórmulas em escala automática, o que pode ser útil para solucionar possíveis problemas.

Evento de exemplo para 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": []
    }
}

Fórmulas de dimensionamento automático de exemplo

Vejamos algumas fórmulas que mostram diferentes maneiras de ajustar a quantidade de recursos de computação em um pool.

Exemplo 1: Ajustamento baseado no tempo

Suponha que você queira ajustar o tamanho da piscina com base no dia da semana e na hora do dia. Este exemplo mostra como aumentar ou diminuir o número de nós no pool de acordo.

A fórmula obtém primeiro a hora atual. Se for um dia da semana (1-5) e dentro do horário de trabalho (8h às 18h), o tamanho do pool de destino será definido como 20 nós. Caso contrário, é definido como 10 nós.

$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 pode ser ajustado para refletir o seu fuso horário local, adicionando time() ao produto de TimeZoneInterval_Hour e ao seu deslocamento UTC. Por exemplo, use $curTime = time() + (-6 * TimeInterval_Hour); para Mountain Daylight Time (MDT). Tenha em mente que o deslocamento precisa ser ajustado no início e no final do horário de verão, se aplicável.

Exemplo 2: Ajuste baseado em tarefas

Neste exemplo de C#, o tamanho do pool é ajustado com base no número de tarefas na fila. Comentários e quebras de linha são incluídos nas cadeias de caracteres da fórmula.

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

Exemplo 3: Contabilização de tarefas paralelas

Este exemplo de C# ajusta o tamanho do pool com base no número de tarefas. Essa fórmula também leva em conta o valor TaskSlotsPerNode que foi definido para o pool. Essa abordagem é útil em situações em que a execução de tarefas paralelas foi habilitada em seu pool.

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

Exemplo 4: Definir um tamanho de pool inicial

Este exemplo mostra um exemplo de C# com uma fórmula de dimensionamento automático que define o tamanho do pool para um número especificado de nós para um período de tempo inicial. Depois disso, ele ajusta o tamanho do pool com base no número de tarefas ativas e em execução.

Especificamente, esta fórmula faz o seguinte:

  • Define o tamanho inicial do pool como quatro nós.
  • Não ajusta o tamanho da piscina nos primeiros 10 minutos do seu ciclo de vida.
  • Após 10 minutos, obtém o valor máximo do número de tarefas ativas e em execução nos últimos 60 minutos.
    • Se ambos os valores forem 0, indicando que nenhuma tarefa estava em execução ou ativa nos últimos 60 minutos, o tamanho do pool será definido como 0.
    • Se qualquer um dos valores for maior que zero, nenhuma alteração será feita.
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);

Próximos passos