Introdução ao Batch SDK for JavaScript

Aprenda o básico para construir um cliente Batch em JavaScript usando Azure Batch JavaScript SDK. Adotamos 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 prático de JavaScript e familiaridade com Linux. Também assume que tens uma conta Azure configurada com direitos de acesso para criar serviços de Batch e de Armazenamento.

Recomendamos a leitura de Azure Batch Technical Overview antes de seguir os passos descritos neste artigo.

Compreender o cenário

Aqui, temos um script simples escrito em Python que descarrega todos os ficheiros csv de um contentor de armazenamento Azure Blob e converte-os para JSON. Para processar múltiplos contentores de contas de armazenamento em paralelo, podemos implementar o script como um trabalho Azure Batch.

Arquitetura Azure Batch

O diagrama seguinte mostra como podemos escalar o script Python usando o Azure Batch e um cliente.

Diagrama a mostrar a arquitetura do cenário.

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

Sugestão

O exemplo de JavaScript no link especificado não contém código específico para ser implementado como uma aplicação de funções do 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 construir o cliente JavaScript:

Passo 1: Instalar o Azure Batch SDK

Podes instalar o Azure Batch SDK para JavaScript usando o comando de instalação npm. Também precisa do pacote @azure/identity para autenticar com a Microsoft Entra ID.

npm install @azure/batch @azure/identity

Este comando instala a versão mais recente do Azure Batch JavaScript SDK juntamente com a biblioteca Azure Identity.

Sugestão

Numa aplicação Azure Function, podes ir a "Kudu Console" no separador Definições da função Azure para executar os comandos de instalação npm. Neste caso, instalar o Azure Batch SDK para JavaScript.

Passo 2: Criar uma conta Azure Batch

Pode criá-lo a partir do portal Azure ou da linha de comandos (PowerShell /CLI do Azure).

A seguir estão os comandos para criar um através do CLI do Azure.

Crie um Grupo de Recursos, ignore esta etapa se já tiver um onde deseja criar a Conta em lote:

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

De seguida, crie uma conta Azure Batch.

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

Em vez de usar chaves de acesso à conta, este exemplo autentica com Microsoft Entra ID usando DefaultAzureCredential. Certifique-se de que a identidade que executa o código (login do seu programador, uma identidade gerida ou um principal de serviço) foi atribuída a um papel Azure RBAC apropriado na conta Batch, como Azure Batch Data Contributor ou Azure Batch Data Reader. Para mais informações, consulte Autenticar soluções de serviço Batch com Microsoft Entra ID.

Ao correr localmente, DefaultAzureCredential pode captar credenciais das variáveis CLI do Azure (az login), Azure PowerShell, Visual Studio Code ou de ambiente. Em ambientes alojados no Azure, como Funções do Azure ou VMs do Azure, pode usar uma identidade gerida.

Passo 3: Criar um cliente de serviço Azure Batch

O seguinte excerto de código importa os @azure/batch módulos e @azure/identity e depois 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 Azure Batch URI pode ser encontrado no separador Overview do portal Azure. É do formato:

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

Consulte a captura de tela:

Azure batch uri

Passo 4: Criar um Azure Batch pool

Um Azure Batch pool consiste em múltiplas VMs (também conhecidas como Batch Nodes). O serviço Azure Batch implementa as tarefas nestes nós e gere-as. Você pode definir os seguintes parâmetros de configuração para seu pool.

  • Tipo de imagem da máquina virtual
  • Tamanho dos nós da máquina virtual
  • Número de nós de máquina virtual

Sugestão

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. Recomendamos testes para determinar o número e o tamanho ideais.

O trecho 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";

Sugestão

Para a lista de imagens de máquinas virtuais Linux disponíveis para Azure Batch e os seus IDs de SKU, veja Lista de imagens de máquinas virtuais.

Depois de definida a configuração do pool, podes criar o Azure Batch pool. O comando Batch pool cria nós de Máquinas Virtuais Azure e prepara-os para receberem tarefas para execução. Cada pool deve ter um ID exclusivo para referência nas etapas subsequentes.

O seguinte excerto de código cria um Azure Batch pool.

// 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 estado do pool criado e assegurar-se de que o estado seja "ativo" antes de prosseguir com o envio de um trabalho para esse 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");
    }
}

A seguir está 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' }}

Passo 4: Enviar um trabalho para o Azure Batch

Um trabalho do Azure Batch é um grupo lógico de tarefas semelhantes. No nosso cenário, é "Processar csv para JSON." Cada tarefa aqui pode ser processar ficheiros csv presentes em cada contentor do Armazenamento do Azure.

Estas tarefas seriam executadas em paralelo e implementadas em múltiplos nós, orquestradas pelo serviço Azure Batch.

Sugestão

Pode usar a propriedade taskSlotsPerNode para especificar o número máximo de tarefas que podem ser executadas simultaneamente num único nó.

Tarefa de preparação

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

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

Podes carregar o script numa conta Armazenamento do Azure e gerar um URI SAS para aceder ao script. Este processo também pode ser automatizado usando o Armazenamento do Azure JavaScript SDK.

Sugestão

Uma tarefa de preparação para um trabalho é executada somente nos nós da VM onde a tarefa específica precisa ser executada. Se quiseres que os pré-requisitos sejam instalados em todos os nós, independentemente das tarefas que neles corram, podes usar a propriedade startTask enquanto adicionas 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 do Azure Batch Job. A seguir estão alguns parâmetros configuráveis da tarefa de preparação:

  • ID: Um identificador único para a tarefa de preparação
  • CommandLine: Linha de comandos para executar o executável da tarefa
  • resourceFiles: Array de objetos que fornecem detalhes dos ficheiros necessários para que esta tarefa seja executada. Seguem-se as suas opções
    • httpUrl: O URL do arquivo para baixar
    • filePath: Caminho local para baixar e salvar o arquivo
    • fileMode: Aplicável apenas para nós Linux, fileMode está em formato octal com um valor predefinido de 0770
  • waitForSuccess: Caso seja definido como verdadeiro, a tarefa não é executada em caso de falhas na tarefa de preparação
  • runElevated: Defina-o como true se forem necessários privilégios elevados para executar a tarefa.

O trecho 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);
}

Passo 5: Submeter tarefas em Azure Batch para um trabalho

Agora que a nossa tarefa de processo CSV está criada, vamos criar tarefas para essa tarefa. Supondo que temos quatro contêineres, temos que criar quatro tarefas, uma para cada contêiner.

Se olharmos para o script Python, aceita dois parâmetros:

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

Assumindo que temos quatro contentores "con1", "con2", "con3", "con4", o código seguinte mostra como submeter quatro tarefas ao trabalho em lote do Azure "process csv" que criámos anteriormente.

// 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 num pool ou a propriedade taskSlotsPerNode, as tarefas esperarão até que um nó esteja disponível. Esta orquestração é gerida automaticamente pelo Azure Batch.

O portal tem vistas detalhadas sobre as tarefas e os status das funções. Também podes usar a lista e obter funções no Azure JavaScript SDK. Os detalhes são fornecidos no link da documentação.

Próximos passos