Introducción al SDK de Batch para JavaScript

En el artículo sobre el SDK de JavaScript para Azure Batch, puede obtener información acerca de los conceptos básicos de la creación de clientes de Batch con JavaScript. Vamos a describir paso a paso un escenario de aplicación por lotes y, a continuación, su configuración mediante JavaScript.

Requisitos previos

En este artículo se considera que tiene conocimientos prácticos de JavaScript y está familiarizado con Linux. También necesitará una cuenta de Azure configurada con derechos de acceso para crear servicios de Batch y Storage.

Es recomendable leer Azure Batch Technical Overview (Información general técnica de Azure Batch) antes de seguir los pasos que se describen en este artículo.

Descripción del escenario

Aquí, tenemos un script sencillo escrito en Python que descarga todos los archivos CSV de un contenedor de Azure Blob Storage y los convierte en JSON. Para procesar en paralelo varios contenedores de la cuenta de almacenamiento, podemos implementar el script como un trabajo de Azure Batch.

Arquitectura de Azure Batch

El siguiente diagrama muestra cómo se puede escalar el script de Python con Azure Batch y un cliente.

Diagrama que muestra la arquitectura del escenario.

El ejemplo de JavaScript implementa un trabajo por lotes con una tarea de preparación (más adelante se explica con detalle) y un conjunto de tareas en función del número de contenedores de la cuenta de almacenamiento. Puede descargar los scripts del repositorio de GitHub.

Sugerencia

El ejemplo de JavaScript del enlace especificado no contiene código específico para implementarse como una instancia de Azure Functions App. Puede consultar los siguientes enlaces para obtener instrucciones de cómo crear una.

Compilar la aplicación

Ahora, sigamos el proceso paso a paso para crear el cliente de JavaScript:

Paso 1: Instalación del SDK de Azure Batch

Puede instalar el SDK de Azure Batch para JavaScript con el comando npm install.

npm install @azure/batch

Este comando instala la versión más reciente del SDK de JavaScript.

Sugerencia

En una instancia de Azure Function App, puede ir a la "Consola Kudu" en la pestaña de configuración de la función de Azure para ejecutar los comandos npm install. En este caso, para instalar el SDK de Azure Batch para JavaScript.

Paso 2: Creación de una cuenta de Azure Batch

Puede crearla desde Azure Portal o desde la línea de comandos (Powershell /CLI de Azure).

A continuación se muestran los comandos para crear una mediante la CLI de Azure.

Cree un grupo de recursos; omita este paso si ya tiene uno en el que desea crear la cuenta de Batch:

az group create -n "<resource-group-name>" -l "<location>"

A continuación, cree una cuenta de Azure Batch.

az batch account create -l "<location>" -g "<resource-group-name>" -n "<batch-account-name>"

Cada cuenta de Batch tiene sus claves de acceso correspondientes. Estas claves se necesitan para crear más recursos en la cuenta de Azure Batch. Una práctica recomendada para el entorno de producción es usar Azure Key Vault para almacenar estas claves. Después, puede crear una entidad de servicio para la aplicación. Mediante esta entidad de servicio, la aplicación puede crear un token de OAuth para tener acceso a las claves del almacén de claves.

az batch account keys list -g "<resource-group-name>" -n "<batch-account-name>"

Copie y guarde la clave que se usará en los pasos siguientes.

Paso 3: Creación de un cliente de servicio de Azure Batch

El siguiente fragmento de código importa en primer lugar el módulo de JavaScript de Azure Batch y, a continuación, crea un cliente de servicio Batch. Debe crear primero un objeto SharedKeyCredentials con la clave de la cuenta de Batch que copió en el paso anterior.

// Initializing Azure Batch variables

import { BatchServiceClient, BatchSharedKeyCredentials } from "@azure/batch";

// Replace values below with Batch Account details
const batchAccountName = '<batch-account-name>';
const batchAccountKey = '<batch-account-key>';
const batchEndpoint = '<batch-account-url>';

const credentials = new BatchSharedKeyCredentials(batchAccountName, batchAccountKey);
const batchClient = new BatchServiceClient(credentials, batchEndpoint);

La dirección URI de Azure Batch se puede encontrar en la pestaña Información general de Azure Portal. Tiene el formato:

https://accountname.location.batch.azure.com

Consulte la captura de pantalla:

URI de Azure Batch

Paso 4: Creación de un grupo de Azure Batch

Un grupo de Azure Batch consta de varias máquinas virtuales (también conocidas como nodos de Batch). El servicio Azure Batch implementa las tareas en los nodos y las administra. Puede definir los siguientes parámetros de configuración para el grupo.

  • Tipo de imagen de máquina virtual
  • Tamaño de los nodos de máquina virtual
  • Número de nodos de máquina virtual

Sugerencia

El tamaño y el número de los nodos de máquina virtual dependen en gran medida del número de tareas que desee ejecutar en paralelo y de la propia tarea. Se recomienda realizar pruebas para determinar el número y tamaño ideales.

El fragmento de código siguiente crea los objetos de parámetros de configuración.

// Creating Image reference configuration for Ubuntu Linux VM
const imgRef = {
    publisher: "Canonical",
    offer: "UbuntuServer",
    sku: "20.04-LTS",
    version: "latest"
}
// Creating the VM configuration object with the SKUID
const vmConfig = {
    imageReference: imgRef,
    nodeAgentSKUId: "batch.node.ubuntu 20.04"
};
// Number of VMs to create in a pool
const numVms = 4;

// Setting the VM size
const vmSize = "STANDARD_D1_V2";

Sugerencia

Para obtener la lista de imágenes de máquinas virtuales Linux disponibles para Azure Batch y sus identificadores SKU, consulte la Lista de imágenes de máquina virtual.

Una vez definida la configuración del grupo, puede crear el grupo de Azure Batch. El comando batch pool crea nodos de máquina virtual de Azure y los prepara para recibir tareas para ejecutar. Cada grupo debe tener un identificador único para hacer referencia a él en los siguientes pasos.

El siguiente fragmento de código crea un grupo de Azure Batch.

// Create a unique Azure Batch pool ID
const now = new Date();
const poolId = `processcsv_${now.getFullYear()}${now.getMonth()}${now.getDay()}${now.getHours()}${now.getSeconds()}`;

const poolConfig = {
    id: poolId,
    displayName: "Processing csv files",
    vmSize: vmSize,
    virtualMachineConfiguration: vmConfig,
    targetDedicatedNodes: numVms,
    enableAutoScale: false
};

// Creating the Pool
var pool = batchClient.pool.add(poolConfig, function (error, result){
    if(error!=null){console.log(error.response)};
});

Puede comprobar el estado del grupo creado y asegurarse de que el estado es "activo" antes de continuar con el envío de un trabajo a ese grupo.

var cloudPool = batchClient.pool.get(poolId,function(error,result,request,response){
        if(error == null)
        {

            if(result.state == "active")
            {
                console.log("Pool is active");
            }
        }
        else
        {
            if(error.statusCode==404)
            {
                console.log("Pool not found yet returned 404...");

            }
            else
            {
                console.log("Error occurred while retrieving pool data");
            }
        }
        });

A continuación se muestra un ejemplo de objeto devuelto por la función pool.get.

{
  id: 'processcsv_2022002321',
  displayName: 'Processing csv files',
  url: 'https://<batch-account-name>.westus.batch.azure.com/pools/processcsv_2022002321',
  eTag: '0x8D9D4088BC56FA1',
  lastModified: 2022-01-10T07:12:21.943Z,
  creationTime: 2022-01-10T07:12:21.943Z,
  state: 'active',
  stateTransitionTime: 2022-01-10T07:12:21.943Z,
  allocationState: 'steady',
  allocationStateTransitionTime: 2022-01-10T07:13:35.103Z,
  vmSize: 'standard_d1_v2',
  virtualMachineConfiguration: {
    imageReference: {
      publisher: 'Canonical',
      offer: 'UbuntuServer',
      sku: '20.04-LTS',
      version: 'latest'
    },
    nodeAgentSKUId: 'batch.node.ubuntu 20.04'
  },
  resizeTimeout: 'PT15M',
  currentDedicatedNodes: 4,
  currentLowPriorityNodes: 0,
  targetDedicatedNodes: 4,
  targetLowPriorityNodes: 0,
  enableAutoScale: false,
  enableInterNodeCommunication: false,
  taskSlotsPerNode: 1,
  taskSchedulingPolicy: { nodeFillType: 'Spread' }}

Paso 4: Envío de un trabajo a Azure Batch

Un trabajo de Azure Batch es un grupo lógico de tareas similares. En nuestro escenario, es "Procesar CSV a JSON". Cada tarea aquí podría estar procesando archivos CSV presentes en cada contenedor de Azure Storage.

Estas tareas se ejecutan en paralelo y se implementan a través de varios nodos, organizados por el servicio de Azure Batch.

Sugerencia

Puede usar la propiedad taskSlotsPerNode para especificar el número máximo de tareas que se pueden ejecutar simultáneamente en un único nodo.

Tarea de preparación

Los nodos de máquina virtual creados son nodos Ubuntu en blanco. A menudo, necesitará instalar un conjunto de programas como requisitos previos. Por lo general, para los nodos de Linux puede tener un script de shell que instale los requisitos previos antes de la ejecución de las tareas reales. No obstante, puede ser cualquier programa ejecutable.

El script de shell de este ejemplo instala Python-pip y el SDK de Azure Storage Blob para Python.

Puede cargar el script en una cuenta de Azure Storage y generar un URI de SAS para tener acceso al script. Este proceso también se puede automatizar utilizando el SDK de Azure Storage para JavaScript.

Sugerencia

Una tarea de preparación de un trabajo se ejecuta solo en los nodos de máquina virtual en los que la tarea específica necesita ejecutarse. Si desea que los requisitos previos se instalen en todos los nodos con independencia de las tareas que se ejecutan en él, puede usar la propiedad startTask al agregar un grupo. Puede utilizar como referencia la definición de tarea de preparación siguiente.

La tarea de preparación se especifica durante el envío de un trabajo de Azure Batch. A continuación se indican algunos parámetros configurables de la tarea de preparación:

  • Identificador: identificador único de la tarea de preparación.
  • commandLine: línea de comandos para ejecutar el ejecutable de la tarea.
  • resourceFiles: matriz de objetos que proporciona detalles de los archivos que se deben descargar para que la tarea se ejecute. Las opciones son
    • httpUrl: la dirección URL del archivo que se va a descargar.
    • filePath: ruta de acceso local para descargar y guardar el archivo.
    • fileMode: solo es aplicable para nodos de Linux; está en formato octal con un valor predeterminado de 0770.
  • waitForSuccess: si se establece en true, la tarea no se ejecuta si existen errores en la tarea de preparación.
  • runElevated: establézcalo en true si se necesitan privilegios elevados para ejecutar la tarea.

El fragmento de código siguiente muestra el ejemplo de script de configuración de la tarea de preparación:

var jobPrepTaskConfig = {id:"installprereq",commandLine:"sudo sh startup_prereq.sh > startup.log",resourceFiles: [{ 'httpUrl': 'Blob sh url', 'filePath': 'startup_prereq.sh' }],waitForSuccess:true,runElevated:true, userIdentity: {autoUser: {elevationLevel: "admin", scope: "pool"}}}

Si no hay requisitos previos de instalación para la ejecución de las tareas, puede omitir las tareas de preparación. El código siguiente crea un trabajo con el nombre para mostrar "process csv files" (procesar archivos CSV).

// Setting Batch Pool ID
const poolInfo = { poolId: poolId };
// Batch job configuration object
const jobId = "processcsvjob";
const jobConfig = {
    id: jobId,
    displayName: "process csv files",
    jobPreparationTask: jobPrepTaskConfig,
    poolInfo: poolInfo
};
// Adding Azure batch job to the pool
const job = batchClient.job.add(jobConfig, function (error, result) {
        if (error !== null) {
            console.log("An error occurred while creating the job...");
            console.log(error.response);
        }
    }
);

Paso 5: Envío de tareas de Azure Batch para un trabajo

Una vez creado el trabajo para procesar archivos CSV, se crearán las tareas para dicho trabajo. Suponiendo que tenemos cuatro contenedores, tenemos que crear cuatro tareas, una para cada contenedor.

Si observamos el script de Python, vemos que acepta dos parámetros:

  • container name (nombre del contenedor): el contenedor de almacenamiento del que se van a descargar los archivos.
  • pattern (patrón): parámetro opcional de un patrón de nombre de archivo

Suponiendo que tenemos cuatro contenedores denominados "con1", "con2", "con3" y "con4", el siguiente código muestra el envío de cuatro tareas al trabajo de Azure Batch denominado "process csv" (procesar archivos CSV) que creamos anteriormente.

// storing container names in an array
const containerList = ["con1", "con2", "con3", "con4"];      //Replace with list of blob containers within storage account
containerList.forEach(function (val, index) {
    console.log("Submitting task for container : " + val);
    const containerName = val;
    const taskID = containerName + "_process";
    // Task configuration object
    const taskConfig = {
        id: taskID,
        displayName: 'process csv in ' + containerName,
        commandLine: 'python processcsv.py --container ' + containerName,
        resourceFiles: [{ 'httpUrl': 'Blob script url', 'filePath': 'processcsv.py' }]
    };

    const task = batchClient.task.add(jobId, taskConfig, function (error, result) {
        if (error !== null) {
            console.log("Error occurred while creating task for container " + containerName + ". Details : " + error.response);
        }
        else {
            console.log("Task for container : " + containerName + " submitted successfully");
        }
    });
});

El código agrega varias tareas al grupo. Y cada una de las tareas se ejecuta en un nodo en el grupo de máquinas virtuales que se creó. Si el número de tareas supera el número de máquinas virtuales de un grupo o el valor de la propiedad taskSlotsPerNode, las tareas esperan hasta que un nodo quede disponible. Azure Batch controla esta orquestación de un modo automático.

El portal tiene vistas detalladas del estado de las tareas y trabajos. También puede utilizar la lista y obtener funciones en el SDK de JavaScript para Azure. En la documentación del siguiente enlace se proporcionan más detalles.

Pasos siguientes