Introdução ao SDK Batch para JavaScript

Conheça as noções básicas de criar um cliente Batch em JavaScript usando Lote do Azure JavaScript SDK. Executamos uma abordagem passo a passo para entender um cenário para um aplicativo em lote e, em seguida, configurá-lo usando JavaScript.

Pré-requisitos

Este artigo pressupõe que você tenha um conhecimento funcional do JavaScript e familiaridade com o Linux. Ele também pressupõe que você tenha uma conta configurada no Azure com permissões de acesso para criar serviços de Batch e Armazenamento.

É recomendável ler Lote do Azure Visão geral técnica antes de percorrer as etapas descritas neste artigo.

Compreender o cenário

Aqui, temos um script simples escrito em Python que baixa todos os arquivos csv de um contêiner de armazenamento de blobs Azure e os converte em JSON. Para processar vários contêineres de conta de armazenamento em paralelo, podemos implantar o script como um trabalho de Lote do Azure.

arquitetura de Lote do Azure

O diagrama a seguir descreve como podemos dimensionar o script Python usando Lote do Azure e um cliente.

Diagrama mostrando a arquitetura do cenário.

O exemplo javaScript implanta um trabalho em lote com uma tarefa de preparação (explicada em detalhes posteriormente) e um conjunto de tarefas, dependendo do número de contêineres na conta de armazenamento. Você pode baixar os scripts do repositório GitHub.

Dica

O exemplo de JavaScript no link especificado não contém código específico a ser implantado como um aplicativo de funções Azure. Você pode consultar os links a seguir para obter instruções para criar um.

Criar o aplicativo

Agora, vamos seguir o processo passo a passo para criar o cliente JavaScript:

Etapa 1: Instalar Lote do Azure SDK

Você pode instalar Lote do Azure SDK para JavaScript usando o comando de instalação do npm. Você também precisa do pacote @azure/identity para autenticar com Microsoft Entra ID.

npm install @azure/batch @azure/identity

Esse comando instala a versão mais recente do SDK do Lote do Azure JavaScript junto com a biblioteca Azure Identity.

Dica

Em um aplicativo Azure Function, você pode acessar "Console do Kudu" na guia Configurações da função Azure para executar os comandos de instalação do npm. Nesse caso, instale Lote do Azure SDK para JavaScript.

Etapa 2: Criar uma conta de Lote do Azure

Você pode criá-lo no portal Azure ou na linha de comando (PowerShell /CLI do Azure).

A seguir estão os comandos para criar um por CLI do Azure.

Crie um Grupo de Recursos, ignore esta etapa se você já tiver uma em que deseja criar a Conta do Lote:

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

Em seguida, crie uma conta Lote do Azure.

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

Em vez de usar chaves de acesso de conta, este exemplo é autenticado com Microsoft Entra ID usando DefaultAzureCredential. Verifique se a identidade que está executando o código (sua conta de desenvolvedor, uma identidade gerenciada ou um principal de serviço) recebeu uma função apropriada do RBAC do Azure na conta do Batch, como Lote do Azure Data Contributor ou Lote do Azure Data Reader. Para obter mais informações, consulte Autenticar soluções do serviço Batch com o Microsoft Entra ID.

Ao executar localmente, DefaultAzureCredential pode obter credenciais da CLI do Azure (az login), do Azure PowerShell, do Visual Studio Code ou de variáveis de ambiente. Em ambientes hospedados Azure, como Azure Functions ou VMs Azure, ele pode usar uma identidade gerenciada.

Etapa 3: Criar um cliente de serviço Lote do Azure

O trecho de código a seguir importa os módulos @azure/batch e @azure/identity e, em seguida, cria um BatchClient usando DefaultAzureCredential.

// Initializing Azure Batch variables

import { DefaultAzureCredential } from "@azure/identity";
import { BatchClient } from "@azure/batch";

// Replace value below with your Batch account URL
const batchEndpoint = '<batch-account-url>';

const credentials = new DefaultAzureCredential();
const batchClient = new BatchClient(batchEndpoint, credentials);

O URI do Lote do Azure pode ser encontrado na guia Visão geral do portal de Azure. Ele é do formato:

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

Consulte a captura de tela:

URI de lote do Azure

Etapa 4: Criar um pool de Lote do Azure

Um pool do Lote do Azure consiste em várias VMs (também conhecidas como Nodes de Batch). O serviço Lote do Azure implanta as tarefas nesses nós e as gerencia. Você pode definir os seguintes parâmetros de configuração para o pool.

  • Tipo de imagem da Máquina Virtual
  • Tamanho dos nós da Máquina Virtual
  • Número de nós da Máquina Virtual

Dica

O tamanho e o número de nós da Máquina Virtual dependem em grande parte do número de tarefas que você deseja executar em paralelo e também da própria tarefa. É recomendável testar para determinar o número e o tamanho ideais.

O snippet de código a seguir cria os objetos de parâmetro de configuração.

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

Dica

Para obter a lista de imagens de VM do Linux disponíveis para Lote do Azure e suas IDs de SKU, consulte Lista de imagens de máquina virtual.

Depois que a configuração do pool for definida, você poderá criar o pool de Lote do Azure. O comando de pool do Batch cria nós de Máquina Virtual do Azure e os prepara para estarem prontos para receber tarefas a serem executadas. Cada pool deve ter uma ID exclusiva para referência nas etapas subsequentes.

O snippet de código a seguir cria um pool de Lote do Azure.

// 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
try {
    await batchClient.createPool(poolConfig);
} catch (error) {
    console.log(error);
}

Você pode verificar o status do pool criado e garantir o estado seja "ativo" antes de prosseguir com o envio de um trabalho ao pool.

try {
    const cloudPool = await batchClient.getPool(poolId);
    if (cloudPool.state === "active") {
        console.log("Pool is active");
    }
} catch (error) {
    if (error.statusCode === 404) {
        console.log("Pool not found yet returned 404...");
    } else {
        console.log("Error occurred while retrieving pool data");
    }
}

Veja a seguir um objeto de resultado de exemplo retornado pela função 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' }}

Etapa 4: Enviar uma tarefa Lote do Azure

Um processo Lote do Azure é um grupo lógico de tarefas semelhantes. Em nosso cenário, é "Process csv to JSON". Cada tarefa aqui pode estar processando arquivos csv presentes em cada contêiner Armazenamento do Azure.

Essas tarefas seriam executadas em paralelo e implantadas em vários nós, orquestradas pelo serviço Lote do Azure.

Dica

Você pode usar a propriedade taskSlotsPerNode para especificar o número máximo de tarefas que podem ser executadas simultaneamente em um único nó.

Tarefa de preparação

Os nós da VM criados são nós em branco do Ubuntu. Muitas vezes, você precisa instalar um conjunto de programas como pré-requisitos. Normalmente, para nodos Linux, você pode ter um script de shell que instala os pré-requisitos antes que as tarefas em si sejam executadas. No entanto, pode ser qualquer executável programável.

O script shell neste exemplo instala o Python-pip e o SDK do Blob Armazenamento do Azure para Python.

Você pode carregar o script em uma conta Armazenamento do Azure e gerar um URI sas para acessar o script. Esse processo também pode ser automatizado usando o SDK do JavaScript Armazenamento do Azure.

Dica

Uma tarefa de preparação para um trabalho é executada somente nos nós da VM em que a tarefa específica precisa ser executada. Se você quiser que os pré-requisitos sejam instalados em todos os nós, independentemente das tarefas executadas nele, use a propriedade startTask ao adicionar um pool. Você pode usar a seguinte definição de tarefa de preparação para referência.

Uma tarefa de preparação é especificada durante a submissão de um trabalho do Lote do Azure. A seguir estão alguns parâmetros de tarefa de preparação configurável:

  • ID: um identificador exclusivo para a tarefa de preparação
  • commandLine: linha de comando para executar o executável da tarefa
  • resourceFiles: matriz de objetos que fornecem detalhes dos arquivos necessários para serem baixados para que essa tarefa seja executada. A seguir estão suas opções
    • httpUrl: a URL do arquivo a ser baixado
    • filePath: caminho local para baixar e salvar o arquivo
    • fileMode: aplicável somente para nós de Linux, o fileMode está em formato octal com um valor padrão de 0770
  • waitForSuccess: se definido como true, a tarefa não é executada no caso de falhas de tarefa de preparação
  • runElevated: defina-o como true se forem necessários privilégios elevados para executar a tarefa.

O snippet de código a seguir mostra o exemplo de configuração de script de tarefa de preparação:

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

Se não houver pré-requisitos a serem instalados para que suas tarefas sejam executadas, você poderá ignorar as tarefas de preparação. O código a seguir cria um trabalho com o nome de exibição "processar arquivos 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
try {
    await batchClient.createJob(jobConfig);
} catch (error) {
    console.log("An error occurred while creating the job...");
    console.log(error);
}

Etapa 5: Enviar as tarefas do "Lote do Azure" para um trabalho

Agora que nosso processo de trabalho csv foi criado, vamos criar tarefas para esse processo. Supondo que tenhamos quatro contêineres, precisamos criar quatro tarefas, uma para cada contêiner.

Se examinarmos o script Python, ele aceitará dois parâmetros:

  • nome do contêiner: o contêiner de armazenamento do qual baixar arquivos
  • padrão: um parâmetro opcional do padrão de nome de arquivo

Supondo que tenhamos quatro contêineres "con1", "con2", "con3", "con4", o código mostrado a seguir demonstra como enviar quatro tarefas ao trabalho em lote do Microsoft Azure 'processamento de CSV' que foi criado previamente.

// storing container names in an array
const containerList = ["con1", "con2", "con3", "con4"];      //Replace with list of blob containers within storage account
for (const val of containerList) {
    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' }]
    };

    try {
        await batchClient.createTask(jobId, taskConfig);
        console.log("Task for container : " + containerName + " submitted successfully");
    } catch (error) {
        console.log("Error occurred while creating task for container " + containerName + ". Details : " + error);
    }
}

O código adiciona várias tarefas ao pool. E cada uma das tarefas é executada em um nó no pool de VMs criadas. Se o número de tarefas exceder o número de VMs em um pool ou na propriedade taskSlotsPerNode, as tarefas aguardarão até que um nó seja disponibilizado. Essa orquestração é manipulada por Lote do Azure automaticamente.

O portal tem exibições detalhadas sobre as tarefas e os status das atividades. Você também pode usar a lista e obter funções no SDK Azure JavaScript. Os detalhes são fornecidos no link da documentação.

Próximas etapas