Ejecución simultánea de tareas para maximizar el uso de los nodos de proceso de BatchRun tasks concurrently to maximize usage of Batch compute nodes

Mediante la ejecución simultánea de más de una tarea en cada nodo del grupo de Azure Batch, puede maximizar el uso de los recursos en un menor número de nodos de ejecución en el grupo.You can maximize resource usage on a smaller number of compute nodes in your pool by running more than one task simultaneously on each node.

Aunque algunos escenarios funcionan mejor con todos los recursos de un nodo dedicados a una sola tarea, en algunas cargas de trabajo se pueden observar tiempos de trabajo más cortos y menores costos si varias tareas comparten esos recursos.While some scenarios work best with all of a node's resources dedicated to a single task, certain workloads may see shorter job times and lower costs when multiple tasks share those resources. Considere los siguientes escenarios:Consider the following scenarios:

  • Reducción al mínimo de la transferencia de datos de las tareas que pueden compartir datos.Minimize data transfer for tasks that are able to share data. Puede reducir considerablemente los gastos de transferencia de datos copiando los datos compartidos en un número menor de nodos y ejecutando tareas en paralelo en cada nodo.You can dramatically reduce data transfer charges by copying shared data to a smaller number of nodes, then executing tasks in parallel on each node. Esto es válido especialmente si los datos que se copian en cada nodo deben transferirse entre regiones geográficas.This especially applies if the data to be copied to each node must be transferred between geographic regions.
  • Maximización del uso de memoria para las tareas que requieren una gran cantidad de memoria, pero solo durante períodos breves y en momentos variables durante la ejecución.Maximize memory usage for tasks which require a large amount of memory, but only during short periods of time, and at variable times during execution. Puede emplear menos nodos de ejecución, pero de mayor tamaño y con más memoria, para controlar de forma eficaz dichos aumentos.You can employ fewer, but larger, compute nodes with more memory to efficiently handle such spikes. Estos nodos tendrán varias tareas ejecutándose en paralelo en cada nodo, pero cada tarea puede aprovechar la abundante memoria de los nodos en distintos momentos.These nodes will have multiple tasks running in parallel on each node, but each task can take advantage of the nodes' plentiful memory at different times.
  • Mitigación de los límites de número de nodos cuando se requiere la comunicación entre nodos dentro de un grupo.Mitigate node number limits when inter-node communication is required within a pool. Actualmente, los grupos configurados para la comunicación entre nodos están limitados a 50 nodos de ejecución.Currently, pools configured for inter-node communication are limited to 50 compute nodes. Si cada uno de los nodos de este tipo de grupo es capaz de ejecutar tareas en paralelo, el número de tareas que se podrán ejecutar simultáneamente será mayor.If each node in such a pool is able to execute tasks in parallel, a greater number of tasks can be executed simultaneously.
  • Replicación en un clúster de proceso local, como cuando mueve por primera vez un entorno de procesos a Azure.Replicate an on-premises compute cluster, such as when you first move a compute environment to Azure. Si la solución local existente ejecuta varias tareas en cada nodo de proceso, puede aumentar el número máximo de tareas de nodo para que refleje con mayor fidelidad esa configuración.If your current on-premises solution executes multiple tasks per compute node, you can increase the maximum number of node tasks to more closely mirror that configuration.

Escenario de ejemploExample scenario

Por ejemplo, imagine una aplicación de tarea con unos requisitos de CPU y memoria tales que unos nodos Estándar_D1 sean suficientes.As an example, imagine a task application with CPU and memory requirements such that Standard_D1 nodes are sufficient. Sin embargo, para ejecutar el trabajo en el tiempo requerido, se necesitan 1000 nodos de ese tipo.However, in order to finish the job in the required time, 1,000 of these nodes are needed.

En lugar de utilizar nodos Standard_D1 con un núcleo de CPU, podría utilizar nodos Standard_D14 con 16 núcleos en cada nodo y habilitar la ejecución de tareas en paralelo.Instead of using Standard_D1 nodes that have 1 CPU core, you could use Standard_D14 nodes that have 16 cores each, and enable parallel task execution. De este modo, se podría usar un número de nodos 16 veces menor; es decir, en lugar de 1000 nodos, solo serían necesarios 63.This means that 16 times fewer nodes could be used--instead of 1,000 nodes, only 63 would be required. Si se necesitan datos de referencia o archivos de aplicación de gran tamaño para cada nodo, la eficiencia y la duración del trabajo se mejoran, ya que los datos se copian en solo 63 nodos.If large application files or reference data are required for each node, job duration and efficiency are improved, since the data is copied to only 63 nodes.

Habilitación de la ejecución en paralelo de tareasEnable parallel task execution

Los nodos de proceso para la ejecución en paralelo de tareas se configuran a nivel de grupo.You configure compute nodes for parallel task execution at the pool level. Con la biblioteca .NET de Batch, establezca la propiedad CloudPool.TaskSlotsPerNode al crear un grupo.With the Batch .NET library, set the CloudPool.TaskSlotsPerNode property when you create a pool. Si usa la API REST de Batch, establezca el elemento taskSlotsPerNode en el cuerpo de la solicitud durante la creación del grupo.If you're using the Batch REST API, set the taskSlotsPerNode element in the request body during pool creation.

Nota

Solo puede establecer el elemento taskSlotsPerNode y la propiedad TaskSlotsPerNode en el momento de crear el grupo.You can set the taskSlotsPerNode element and TaskSlotsPerNode property only at pool creation time. No se pueden modificar después de haber creado el grupo.They can't be modified after a pool has already been created.

Azure Batch permite una configuración de ranuras de tarea por nodo que cuadriplica el número de núcleos de nodo.Azure Batch allows you to set task slots per node up to (4x) the number of node cores. Por ejemplo, si el grupo está configurado con nodos de tamaño "Grande" (cuatro núcleos), taskSlotsPerNode se puede establecer en 16.For example, if the pool is configured with nodes of size "Large" (four cores), then taskSlotsPerNode may be set to 16. Sin embargo, independientemente de cuántos núcleos tiene el nodo, no puede tener más de 256 ranuras de tarea por nodo.However, regardless of how many cores the node has, you can't have more than 256 task slots per node. Para más información sobre el número de núcleos de cada uno de los tamaños de nodo, consulte Tamaños de Cloud Services.For details on the number of cores for each of the node sizes, see Sizes for Cloud Services. Para más información sobre los límites del servicio, consulte Cuotas y límites del servicio Azure Batch.For more information on service limits, see Quotas and limits for the Azure Batch service.

Sugerencia

Asegúrese de tener en cuenta el valor taskSlotsPerNode al construir una fórmula de escalado automático para el grupo.Be sure to take into account the taskSlotsPerNode value when you construct an autoscale formula for your pool. Por ejemplo, una fórmula que evalúe $RunningTasks podría verse afectada considerablemente por un aumento en las tareas por nodo.For example, a formula that evaluates $RunningTasks could be dramatically affected by an increase in tasks per node. Para más información, consulte Escalación automática de los nodos de ejecución en un grupo de Azure Batch.For more information, see Automatically scale compute nodes in an Azure Batch pool.

Especificación de la distribución de tareasSpecify task distribution

A la hora de habilitar tareas simultáneas, es importante especificar cómo desea que se distribuyan las tareas entre los nodos del grupo.When enabling concurrent tasks, it's important to specify how you want the tasks to be distributed across the nodes in the pool.

Mediante la propiedad CloudPool.TaskSchedulingPolicy, puede especificar que las tareas se deberían asignar de manera uniforme entre todos los nodos del grupo ("propagación").By using the CloudPool.TaskSchedulingPolicy property, you can specify that tasks should be assigned evenly across all nodes in the pool ("spreading"). O bien, puede especificar que se deberían asignar todas las tareas posibles a cada nodo antes de asignarlas a otro nodo del grupo ("empaquetado").Or you can specify that as many tasks as possible should be assigned to each node before tasks are assigned to another node in the pool ("packing").

Como ejemplo, considere el grupo de nodos Estándar_D14 (en el ejemplo anterior) configurado con un valor CloudPool.TaskSlotsPerNode de 16.As an example, consider the pool of Standard_D14 nodes (in the example above) that is configured with a CloudPool.TaskSlotsPerNode value of 16. Si CloudPool.TaskSchedulingPolicy se configura con un ComputeNodeFillType de Pack, se podría maximizar el uso de los 16 núcleos de cada nodo y permitir que un grupo con escalabilidad automática elimine los nodos sin usar del grupo (nodos sin tareas asignadas).If the CloudPool.TaskSchedulingPolicy is configured with a ComputeNodeFillType of Pack, it would maximize usage of all 16 cores of each node and allow an autoscaling pool to remove unused nodes (nodes without any tasks assigned) from the pool. Esto minimiza el uso de recursos y permite ahorrar dinero.This minimizes resource usage and saves money.

Definición de ranuras variables por tareaDefine variable slots per task

Una tarea se puede definir con la propiedad CloudTask.RequiredSlots especificando el número de ranuras que requiere para ejecutarse en un nodo de ejecución.A task can be defined with CloudTask.RequiredSlots property, specifying how many slots it requires to run on a compute node. El valor predeterminado es 1.The default value is 1. Puede establecer ranuras de tareas variables si las tareas tienen pesos diferentes en cuanto al uso de recursos en el nodo de ejecución.You can set variable task slots if your tasks have different weights regarding to resource usage on the compute node. Esto permite que cada nodo de ejecución tenga un número razonable de tareas en ejecución simultáneas que no llegue a saturar los recursos del sistema, como la CPU o la memoria.This lets each compute node have a reasonable number of concurrent running tasks without overwhelming system resources like CPU or memory.

Por ejemplo, en el caso de un grupo con la propiedad taskSlotsPerNode = 8, puede enviar tareas de uso intensivo de CPU que requieren varios núcleos con requiredSlots = 8, y otras tareas con requiredSlots = 1.For example, for a pool with property taskSlotsPerNode = 8, you can submit multi-core required CPU-intensive tasks with requiredSlots = 8, while other tasks can be set to requiredSlots = 1. Cuando esta carga de trabajo mixta está programada, las tareas de uso intensivo de CPU se ejecutarán exclusivamente en sus nodos de ejecución, mientras que otras tareas se podrán ejecutar simultáneamente (hasta ocho tareas a la vez) en otros nodos.When this mixed workload is scheduled, the CPU-intensive tasks will run exclusively on their compute nodes, while other tasks can run concurrently (up to eight tasks at once) on other nodes. Esto le ayuda a equilibrar la carga de trabajo entre los nodos de ejecución y mejorar la eficacia del uso de los recursos.This helps you balance your workload across compute nodes and improve resource usage efficiency.

Asegúrese de que no especifica un valor de requiredSlots para la tarea que sea mayor que el valor de taskSlotsPerNode para el grupo.Be sure you don't specify a task's requiredSlots to be greater than the pool's taskSlotsPerNode. Esto hará que la tarea no se pueda ejecutar nunca.This will result in the task never being able to run. El servicio Batch no valida actualmente este conflicto cuando envía tareas, porque es posible que el trabajo no tenga un grupo enlazado en el momento del envío, o que se cambie a un grupo diferente si se deshabilita y se vuelve a habilitar.The Batch Service doesn't currently validate this conflict when you submit tasks because a job may not have a pool bound at submission time, or it could be changed to a different pool by disabling/re-enabling.

Sugerencia

Cuando se usan ranuras de tareas variables, es posible que las tareas grandes con más ranuras necesarias no se puedan programar temporalmente debido a que no hay suficientes ranuras disponibles en ningún nodo de ejecución, incluso cuando todavía hay ranuras inactivas en algunos nodos.When using variable task slots, it's possible that large tasks with more required slots can temporarily fail to be scheduled because not enough slots are available on any compute node, even when there are still idle slots on some nodes. Puede subir la prioridad del trabajo para estas tareas con el fin de aumentar su oportunidad de competir por las ranuras disponibles en los nodos.You can raise the job priority for these tasks to increase their chance to compete for available slots on nodes.

El servicio Batch emite TaskScheduleFailEvent cuando no puede programar una tarea para que se ejecute, y sigue reintentando la programación hasta que están disponibles las ranuras necesarias.The Batch service emits the TaskScheduleFailEvent when it fails to schedule a task to run, and keeps retrying the scheduling until required slots become available. Puede escuchar ese evento para detectar posibles problemas de programación de tareas y llevar a cabo su mitigación en consecuencia.You can listen to that event to detect potential task scheduling issues and mitigate accordingly.

Ejemplo de Batch .NETBatch .NET example

En los siguientes fragmentos de código de la API de .NET para Batch se muestra cómo crear un grupo con varias ranuras de tareas por nodo y cómo enviar una tarea con las ranuras necesarias.The following Batch .NET API code snippets show how to create a pool with multiple task slots per node and how to submit a task with required slots.

Creación de un grupo con varias ranuras de tareas por nodoCreate a pool with multiple task slots per node

En este fragmento de código se muestra una solicitud para crear un grupo que contiene cuatro nodos con cuatro ranuras de tarea por nodo.This code snippet shows a request to create a pool that contains four nodes, with four task slots allowed per node. Se especifica una directiva de programación de tareas que llenará cada nodo de tareas antes de asignarlas a otro nodo del grupo.It specifies a task scheduling policy that will fill each node with tasks prior to assigning tasks to another node in the pool.

Para obtener más información sobre cómo agregar grupos mediante la API de .NET para Batch, consulte BatchClient.PoolOperations.CreatePool.For more information on adding pools by using the Batch .NET API, see BatchClient.PoolOperations.CreatePool.

CloudPool pool =
    batchClient.PoolOperations.CreatePool(
        poolId: "mypool",
        targetDedicatedComputeNodes: 4
        virtualMachineSize: "standard_d1_v2",
        cloudServiceConfiguration: new CloudServiceConfiguration(osFamily: "5"));

pool.TaskSlotsPerNode = 4;
pool.TaskSchedulingPolicy = new TaskSchedulingPolicy(ComputeNodeFillType.Pack);
pool.Commit();

Creación de una tarea con las ranuras necesariasCreate a task with required slots

Este fragmento de código crea una tarea con requiredSlots no predeterminado.This code snippet creates a task with non-default requiredSlots. Esta tarea solo se ejecutará cuando haya suficientes ranuras libres disponibles en un nodo de ejecución.This task will only run when there are enough free slots available on a compute node.

CloudTask task = new CloudTask(taskId, taskCommandLine)
{
    RequiredSlots = 2
};

Enumeración de los nodos de ejecución con recuentos para ejecutar tareas y ranurasList compute nodes with counts for running tasks and slots

En este fragmento de código se enumeran todos los nodos de ejecución del grupo y se imprimen los recuentos para ejecutar tareas y ranuras de tarea por nodo.This code snippet lists all compute nodes in the pool, and prints out the counts for running tasks and task slots per node.

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

Enumeración de recuentos de tarea para el trabajoList task counts for the job

Este fragmento de código obtiene los recuentos de tareas para el trabajo, lo que incluye los recuentos de tareas y de ranuras de tarea por estado de tarea.This code snippet gets task counts for the job, which includes both tasks and task slots count per task state.

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

Ejemplo de REST BatchBatch REST example

En los siguientes fragmentos de código de la API REST para Batch se muestra cómo crear un grupo con varias ranuras de tareas por nodo y cómo enviar una tarea con las ranuras necesarias.The following Batch REST API code snippets show how to create a pool with multiple task slots per node and how to submit a task with required slots.

Creación de un grupo con varias ranuras de tareas por nodoCreate a pool with multiple task slots per node

En este fragmento de código, se muestra una solicitud para crear un grupo que contiene dos nodos de gran tamaño con un máximo de cuatro tareas por nodo.This snippet shows a request to create a pool that contains two large nodes with a maximum of four tasks per node.

Para más información sobre cómo agregar grupos mediante la API REST, consulte Agregar un grupo a una cuenta.For more information on adding pools by using the REST API, see Add a pool to an account.

{
  "odata.metadata":"https://myaccount.myregion.batch.azure.com/$metadata#pools/@Element",
  "id":"mypool",
  "vmSize":"large",
  "cloudServiceConfiguration": {
    "osFamily":"4",
    "targetOSVersion":"*",
  },
  "targetDedicatedComputeNodes":2,
  "taskSlotsPerNode":4,
  "enableInterNodeCommunication":true,
}

Creación de una tarea con las ranuras necesariasCreate a task with required slots

En este fragmento de código se muestra una solicitud para agregar una tarea con requiredSlots no predeterminado.This snippet shows a request to add a task with non-default requiredSlots. Esta tarea solo se ejecutará cuando haya suficientes ranuras libres disponibles en el nodo de ejecución.This task will only run when there are enough free slots available on the compute node.

{
  "id": "taskId",
  "commandLine": "bash -c 'echo hello'",
  "userIdentity": {
    "autoUser": {
      "scope": "task",
      "elevationLevel": "nonadmin"
    }
  },
  "requiredSLots": 2
}

Código de ejemplo en GitHubCode sample on GitHub

El proyecto ParallelTasks en GitHub muestra el uso de la propiedad CloudPool.TaskSlotsPerNode.The ParallelTasks project on GitHub illustrates the use of the CloudPool.TaskSlotsPerNode property.

Esta aplicación de consola de C# utiliza la biblioteca de .NET de Batch para crear un grupo con uno o más nodos de proceso.This C# console application uses the Batch .NET library to create a pool with one or more compute nodes. Ejecuta un número configurable de tareas en esos nodos para simular una carga variable.It executes a configurable number of tasks on those nodes to simulate a variable load. La salida de la aplicación especifica qué nodos han ejecutado cada tarea.Output from the application shows which nodes executed each task. La aplicación también proporciona un resumen de los parámetros de trabajo y la duración.The application also provides a summary of the job parameters and duration.

A modo de ejemplo, se muestra a continuación la parte de resumen de la salida de dos ejecuciones diferentes de la aplicación de ejemplo ParallelTasks.As an example, below is the summary portion of the output from two different runs of the ParallelTasks sample application. Las duraciones del trabajo que se muestran aquí no incluyen la hora de creación del grupo, ya que cada trabajo se envió a un grupo creado anteriormente cuyos nodos de ejecución tenían el estado Inactivo en el momento del envío.Job durations shown here don't include pool creation time, since each job was submitted to a previously created pool whose compute nodes were in the Idle state at submission time.

La primera ejecución de la aplicación de ejemplo muestra que, con un solo nodo en el grupo y la configuración predeterminada de una tarea por nodo, la duración del trabajo es superior a 30 minutos.The first execution of the sample application shows that with a single node in the pool and the default setting of one task per node, the job duration is over 30 minutes.

Nodes: 1
Node size: large
Task slots per node: 1
Max slots per task: 1
Tasks: 32
Duration: 00:30:01.4638023

La segunda ejecución del ejemplo muestra una disminución notable en la duración del trabajo.The second run of the sample shows a significant decrease in job duration. Esto se debe a que el grupo se configuró con cuatro tareas por nodo, lo que permite la ejecución en paralelo de tareas de forma que el trabajo se completa en casi una cuarta parte del tiempo.This is because the pool was configured with four tasks per node, allowing for parallel task execution to complete the job in nearly a quarter of the time.

Nodes: 1
Node size: large
Task slots per node: 4
Max slots per task: 1
Tasks: 32
Duration: 00:08:48.2423500

Pasos siguientesNext steps

  • Pruebe el mapa térmico de Batch Explorer.Try the Batch Explorer Heat Map. Batch Explorer es una herramienta de cliente independiente, completa y gratuita que puede ayudarle a crear, depurar y supervisar aplicaciones de Azure Batch.Batch Explorer is a free, rich-featured, standalone client tool to help create, debug, and monitor Azure Batch applications. Cuando ejecuta la aplicación de ejemplo ParallelTasks, la característica Mapa térmico de Batch Explorer le permite ver fácilmente la ejecución de tareas paralelas en cada nodo.When you're executing the ParallelTasks sample application, the Batch Explorer Heat Map feature lets you easily visualize the execution of parallel tasks on each node.
  • Explore ejemplos de Azure Batch en GitHub.Explore Azure Batch samples on GitHub.
  • Obtenga más información sobre las dependencias de las tareas de Batch.Learn more about Batch task dependencies.