Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Você pode maximizar o uso de recursos em um número menor de nós de computação em seu pool executando mais de uma tarefa simultaneamente em cada nó.
Embora alguns cenários funcionem melhor com todos os recursos de um nó dedicados a uma única tarefa, certas cargas de trabalho podem ter tempos de trabalho mais curtos e custos mais baixos quando várias tarefas compartilham esses recursos. Considere os seguintes cenários:
- Minimize a transferência de dados para tarefas que podem compartilhar dados. Você pode reduzir drasticamente as taxas de transferência de dados copiando dados compartilhados para um menor número de nós e depois executando tarefas em paralelo em cada nó. Essa estratégia se aplica especialmente se os dados a serem copiados para cada nó devem ser transferidos entre regiões geográficas.
- Maximize o uso de memória para tarefas que exigem uma grande quantidade de memória, mas apenas durante curtos períodos de tempo e em momentos variáveis durante a execução. Você pode empregar menos, mas maiores, nós de computação com mais memória para lidar eficientemente com esses picos. Esses nós têm várias tarefas em execução em paralelo em cada nó, mas cada tarefa pode tirar proveito da memória abundante dos nós em momentos diferentes.
- Reduza os limites de número de nós quando a comunicação entre nós for necessária dentro de um pool. Atualmente, os pools configurados para comunicação entre nós estão limitados a 50 nós de computação. Se cada nó em esse tipo de pool for capaz de realizar tarefas em paralelo, um maior número de tarefas pode ser executado simultaneamente.
- Replique um cluster de computação local, como quando você move um ambiente de computação pela primeira vez para o Azure. Se sua solução local atual executar várias tarefas por nó de computação, você poderá aumentar o número máximo de tarefas de nó para espelhar mais de perto essa configuração.
Cenário de exemplo
Como exemplo, imagine uma aplicação com requisitos de CPU e memória de modo a que as instâncias Standard_D1 sejam suficientes. No entanto, para concluir o trabalho no tempo necessário, 1.000 desses nós são necessários.
Em vez de usar Standard_D1 nós que têm um núcleo de CPU, você pode usar nós Standard_D14 que têm 16 núcleos cada e habilitar a execução de tarefas paralelas. Você poderia potencialmente usar 16 vezes menos nós em vez de 1.000 nós, apenas 63 seriam necessários. Se grandes arquivos de aplicativo ou dados de referência forem necessários para cada nó, a duração e a eficiência do trabalho serão melhoradas, uma vez que os dados são copiados para apenas 63 nós.
Habilitar a execução paralela de tarefas
Você configura nós de computação para execução de tarefas paralelas no nível do pool. Com a biblioteca Batch .NET, defina a propriedade CloudPool.TaskSlotsPerNode ao criar um pool. Se você estiver usando a API REST em lote, defina o elemento taskSlotsPerNode no corpo da solicitação durante a criação do pool.
Observação
Você pode definir o taskSlotsPerNode elemento e a propriedade TaskSlotsPerNode somente no momento da criação do pool. Eles não podem ser modificados depois que um pool já tiver sido criado.
O Azure Batch permite definir slots de tarefas por nó até (4x) o número de núcleos do nó. Por exemplo, se o pool estiver configurado com nós de tamanho "Grande" (quatro núcleos), então taskSlotsPerNode pode ser definido como 16. No entanto, independentemente de quantos núcleos o nó tem, você não pode ter mais de 256 slots de tarefa por nó. Para obter detalhes sobre o número de núcleos para cada um dos tamanhos de nó, consulte Tamanhos para serviços de nuvem (clássico). Para obter mais informações sobre limites de serviço, consulte Cotas e limites de serviço em lote.
Sugestão
Certifique-se de levar em conta o taskSlotsPerNode valor ao construir uma fórmula de dimensionamento automático para seu pool. Por exemplo, uma fórmula que avalia $RunningTasks poderá ser significativamente impactada por um aumento do número de tarefas por nó. Para obter mais informações, consulte Criar uma fórmula automatizada para dimensionar nós de computação num pool Batch.
Especificar distribuição de tarefas
Ao habilitar tarefas simultâneas, é importante especificar como você deseja que as tarefas sejam distribuídas entre os nós no pool.
Usando a propriedade CloudPool.TaskSchedulingPolicy , você pode especificar que as tarefas devem ser atribuídas uniformemente em todos os nós do pool ("spreading"). Ou você pode especificar que o maior número possível de tarefas deve ser atribuído a cada nó antes que as tarefas sejam atribuídas a outro nó no pool ("embalagem").
Como exemplo, considere o pool de nós Standard_D14 (no exemplo anterior) configurado com um valor CloudPool.TaskSlotsPerNode de 16. Se o CloudPool.TaskSchedulingPolicy estiver configurado com um ComputeNodeFillType de Pack, ele maximizará o uso de todos os 16 núcleos de cada nó e permitirá que um pool de dimensionamento automático remova os nós que não estão a ser utilizados (nós sem tarefas atribuídas) do pool. O dimensionamento automático minimiza o uso de recursos e pode economizar dinheiro.
Definir slots variáveis por tarefa
Uma tarefa pode ser definida com a propriedade CloudTask.RequiredSlots , especificando quantos slots ela requer para ser executada em um nó de computação. O valor padrão é 1. Você pode definir slots de tarefas variáveis se suas tarefas tiverem pesos diferentes associados ao uso de recursos no nó de computação. Os slots de tarefas variáveis permitem que cada nó de computação tenha um número razoável de tarefas em execução simultânea sem sobrecarregar os recursos do sistema, como CPU ou memória.
Por exemplo, para um pool com a propriedade taskSlotsPerNode = 8, é possível submeter tarefas intensivas em CPU que requerem múltiplos núcleos com requiredSlots = 8, enquanto outras tarefas podem ser configuradas para requiredSlots = 1. Quando essa carga de trabalho mista é agendada, as tarefas com uso intensivo de CPU são executadas exclusivamente em seus nós de computação, enquanto outras tarefas podem ser executadas simultaneamente (até oito tarefas ao mesmo tempo) em outros nós. A carga de trabalho mista ajuda você a equilibrar sua carga de trabalho entre nós de computação e melhorar a eficiência do uso de recursos.
Certifique-se de não especificar que uma tarefa seja requiredSlots maior do que a do pool taskSlotsPerNode, ou a tarefa nunca será executada. No momento, o Serviço em Lote não valida esse conflito quando você envia tarefas. Ele não valida o conflito, porque um trabalho pode não ter um pool vinculado no momento do envio, ou pode mudar para um pool diferente desabilitando/reativando.
Sugestão
Ao usar slots de tarefas variáveis, é possível que tarefas grandes com mais slots necessários não sejam agendadas temporariamente porque não há slots suficientes disponíveis em qualquer nó de computação, mesmo quando ainda há slots ociosos em alguns nós. Você pode aumentar a prioridade do trabalho para essas tarefas a fim de aumentar as suas hipóteses de competir por slots disponíveis nos nós.
O serviço Batch emite o TaskScheduleFailEvent quando não consegue agendar uma tarefa para ser executada e continua tentando novamente o agendamento até que os slots necessários fiquem disponíveis. Você pode ouvir esse evento para detetar possíveis problemas de agendamento de tarefas e tomar medidas apropriadas.
Exemplo de Batch .NET
Os seguintes trechos de código da API Batch .NET mostram como criar um pool com múltiplos slots de tarefas por nó e como submeter uma tarefa com os slots necessários.
Criar um pool com vários slots de tarefas por nó
Este trecho de código mostra uma solicitação para criar um pool que contém quatro nós, com quatro slots de tarefa permitidos por nós. Ele especifica uma política de agendamento de tarefas que preenche cada nó com tarefas antes de atribuir tarefas a outro nó no pool.
Para obter mais informações sobre como adicionar pools usando a API .NET em lote, consulte BatchClient.PoolOperations.CreatePool.
CloudPool pool =
batchClient.PoolOperations.CreatePool(
poolId: "mypool",
targetDedicatedComputeNodes: 4
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.TaskSlotsPerNode = 4;
pool.TaskSchedulingPolicy = new TaskSchedulingPolicy(ComputeNodeFillType.Pack);
pool.Commit();
Criar uma tarefa com os slots necessários
Este trecho de código cria uma tarefa com um valor não padrão requiredSlots. Esta tarefa é executada quando há slots livres suficientes disponíveis em um nó de computação.
CloudTask task = new CloudTask(taskId, taskCommandLine)
{
RequiredSlots = 2
};
Listar nós de computação com contagens para executar tarefas e slots
Este trecho de código lista todos os nós de computação no pool e imprime as contagens de tarefas em execução e os espaços de tarefas por nó.
ODATADetailLevel nodeDetail = new ODATADetailLevel(selectClause: "id,runningTasksCount,runningTaskSlotsCount");
IPagedEnumerable<ComputeNode> nodes = batchClient.PoolOperations.ListComputeNodes(poolId, nodeDetail);
await nodes.ForEachAsync(node =>
{
Console.WriteLine(node.Id + " :");
Console.WriteLine($"RunningTasks = {node.RunningTasksCount}, RunningTaskSlots = {node.RunningTaskSlotsCount}");
}).ConfigureAwait(continueOnCapturedContext: false);
Listar contagens de tarefas para a tarefa
Esse trecho de código obtém contagens de tarefas para o trabalho, o que inclui tarefas e slots de tarefas por estado de tarefa.
TaskCountsResult result = await batchClient.JobOperations.GetJobTaskCountsAsync(jobId);
Console.WriteLine("\t\tActive\tRunning\tCompleted");
Console.WriteLine($"TaskCounts:\t{result.TaskCounts.Active}\t{result.TaskCounts.Running}\t{result.TaskCounts.Completed}");
Console.WriteLine($"TaskSlotCounts:\t{result.TaskSlotCounts.Active}\t{result.TaskSlotCounts.Running}\t{result.TaskSlotCounts.Completed}");
Exemplo de REST em lote
Os seguintes trechos de código da API REST Batch mostram como criar um pool com múltiplos slots de tarefas por nó e como submeter uma tarefa com os slots necessários.
Criar um pool com vários slots de tarefas por nó
Este trecho mostra uma solicitação para criar um pool que contém dois nós grandes com um máximo de quatro tarefas por nó.
Para obter mais informações sobre como adicionar pools usando a API REST, consulte Adicionar um pool a uma conta.
{
"odata.metadata":"https://myaccount.myregion.batch.azure.com/$metadata#pools/@Element",
"id":"mypool",
"vmSize":"large",
"virtualMachineConfiguration": {
"imageReference": {
"publisher": "canonical",
"offer": "ubuntuserver",
"sku": "20.04-lts"
},
"nodeAgentSKUId": "batch.node.ubuntu 20.04"
},
"targetDedicatedComputeNodes":2,
"taskSlotsPerNode":4,
"enableInterNodeCommunication":true,
}
Criar uma tarefa com os slots necessários
Este trecho mostra uma solicitação para adicionar uma tarefa com uma configuração não padrão requiredSlots. Esta tarefa só é executada quando há slots livres suficientes disponíveis no nó de computação.
{
"id": "taskId",
"commandLine": "bash -c 'echo hello'",
"userIdentity": {
"autoUser": {
"scope": "task",
"elevationLevel": "nonadmin"
}
},
"requiredSLots": 2
}
Exemplo de código no GitHub
O projeto ParallelTasks no GitHub ilustra o uso da propriedade CloudPool.TaskSlotsPerNode .
Este aplicativo de console C# usa a biblioteca Batch .NET para criar um pool com um ou mais nós de computação. Ele executa um número configurável de tarefas nesses nós para simular uma carga variável. A saída do aplicativo mostra quais nós executaram cada tarefa. O aplicativo também fornece um resumo dos parâmetros e duração do trabalho.
O exemplo a seguir mostra a parte de resumo da saída de duas execuções diferentes do aplicativo de exemplo ParallelTasks. As durações de trabalho mostradas aqui não incluem o tempo de criação do pool, uma vez que cada trabalho foi enviado a um pool criado anteriormente cujos nós de computação estavam no estado ocioso no momento do envio.
A primeira execução da aplicação de exemplo mostra que, com um único nó no pool e a configuração padrão de uma tarefa por nó, o tempo de execução é superior a 30 minutos.
Nodes: 1
Node size: large
Task slots per node: 1
Max slots per task: 1
Tasks: 32
Duration: 00:30:01.4638023
A segunda execução da amostra mostra uma diminuição significativa na duração do trabalho. Essa redução ocorre porque o pool foi configurado com quatro tarefas por nó, permitindo a execução paralela de tarefas para concluir o trabalho em quase um quarto do tempo.
Nodes: 1
Node size: large
Task slots per node: 4
Max slots per task: 1
Tasks: 32
Duration: 00:08:48.2423500