Erste Schritte mit dem Batch SDK für JavaScript

Hier werden die Grundlagen für die Erstellung eines Batch-Clients in JavaScript mit dem Azure Batch JavaScript SDK vermittelt. Zum besseren Verständnis gehen wir ein Szenario für eine Batch-Anwendung Schritt für Schritt durch und richten sie dann mithilfe von JavaScript ein.

Voraussetzungen

In diesem Artikel wird davon ausgegangen, dass Sie über JavaScript-Kenntnisse verfügen und mit Linux vertraut sind. Außerdem wird davon ausgegangen, dass Sie über ein Azure-Konto mit Zugriffsrechten für die Erstellung von Batches und Speicherdiensten verfügen.

Sehen Sie sich am besten zuerst die technische Übersicht zu Azure Batch an, bevor Sie sich mit den Schritten in diesem Artikel beschäftigen.

Das Szenario

Wir verwenden hier ein einfaches, in Python geschriebenes Skript, das alle CSV-Dateien aus einem Azure Blob Storage-Container herunterlädt und sie in das JSON-Format konvertiert. Zur parallelen Verarbeitung mehrerer Speicherkontocontainer stellen wir das Skript als Azure Batch-Auftrag bereit.

Azure Batch-Architektur

Das folgende Diagramm zeigt, wie sich das Python-Skript mit Azure Batch und einem Client skalieren lässt.

Abbildung der Szenarioarchitektur.

Die JavaScript-Stichprobe stellt einen Batchauftrag mit einer Vorbereitungsaufgabe (wird weiter unten noch ausführlicher erläutert) und einer Reihe von Aufgaben (abhängig von der Containeranzahl im Speicherkonto) bereit. Die Skripts können aus dem GitHub-Repository heruntergeladen werden.

Tipp

Die JavaScript-Stichprobe unter dem angegebenen Link enthält keinen spezifischen Code für die Bereitstellung als Azure-Funktionen-App. Erstellungsanweisungen für eine solche App finden Sie unter folgenden Links:

Erstellen der Anwendung

Sehen wir uns nun Schritt für Schritt den Prozess zur Erstellung des JavaScript-Clients an:

Schritt 1: Installieren des Azure Batch SDK

Das Azure Batch SDK für JavaScript kann mithilfe des Befehls „npm install“ installiert werden.

npm install @azure/batch

Dieser Befehl installiert die neueste Version des Azure Batch SDKs für JavaScript.

Tipp

In einer Azure-Funktionen-App können auf der Registerkarte „Einstellungen“ der Azure-Funktion zur Kudu-Konsole navigieren, um Befehle vom Typ „npm install“ auszuführen. In diesem Fall installieren Sie so das Azure Batch SDK für JavaScript.

Schritt 2: Erstellen eines Azure Batch-Kontos

Ein Azure Batch-Konto kann über das Azure-Portal oder über die Befehlszeile (PowerShell /Azure-Befehlszeilenschnittstelle) erstellt werden.

Im Anschluss finden Sie die Befehle für die Erstellung über die Azure-Befehlszeilenschnittstelle.

Erstellen Sie eine Ressourcengruppe. (Falls Sie bereits über eine Ressourcengruppe verfügen, in der Sie das Batch-Konto erstellen möchten, können Sie diesen Schritt überspringen.)

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

Erstellen Sie als Nächstes ein Azure Batch-Konto.

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

Jedes Batch-Konto verfügt über entsprechende Zugriffsschlüssel. Diese Schlüssel werden für die Erstellung weiterer Ressourcen im Azure Batch-Konto benötigt. In Produktionsumgebungen empfiehlt es sich, diese Schlüssel mit Azure Key Vault zu speichern. Anschließend können Sie einen Dienstprinzipal für die Anwendung erstellen. Mit diesem Dienstprinzipal kann die Anwendung ein OAuth-Token für den Zugriff auf Schlüssel aus dem Schlüsseltresor erstellen.

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

Kopieren Sie den Schlüssel, und speichern Sie ihn für die späteren Schritte.

Schritt 3: Erstellen eines Azure Batch-Dienstclients

Der folgende Codeausschnitt importiert zunächst das JavaScript-Modul „azure-batch“ und erstellt anschließend einen Batch-Dienstclient. Sie müssen zuerst ein SharedKeyCredentials-Objekt mit dem Batch-Kontoschlüssel erstellen, den Sie im vorherigen Schritt kopiert haben.

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

Den Azure Batch-URI finden Sie auf der Registerkarte „Übersicht“ des Azure-Portals. Er liegt im folgenden Format vor:

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

Screenshot:

Azure Batch-URI

Schritt 4: Erstellen eines Azure Batch-Pools

Ein Azure Batch-Pool besteht aus mehreren virtuellen Computern (auch Batch-Knoten genannt). Der Azure Batch-Dienst stellt die Aufgaben auf diesen Knoten bereit und verwaltet sie. Sie können für Ihren Pool folgende Konfigurationsparameter definieren:

  • Art des VM-Images
  • Größe des VM-Images
  • Anzahl von VM-Knoten

Tipp

Größe und Anzahl der VM-Knoten hängen größtenteils von der Anzahl von Aufgaben ab, die parallel ausgeführt werden sollen, sowie von der Aufgabe selbst. Die optimale Anzahl und Größe können Sie mithilfe von Tests ermitteln.

Der folgende Codeausschnitt erstellt die Konfigurationsparameterobjekte:

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

Tipp

Eine Liste mit den für Azure Batch verfügbaren Linux-VM-Images und ihren SKU-IDs finden Sie unter Liste mit VM-Images.

Nach dem Definieren der Poolkonfiguration können Sie den Azure Batch-Pool erstellen. Der Batch-Poolbefehl erstellt die Azure-VM-Knoten und bereitet sie für den Empfang auszuführender Aufgaben vor. Jeder Pool muss über eine eindeutige ID verfügen, damit in späteren Schritten auf ihn verwiesen werden kann.

Der folgende Codeausschnitt erstellt einen 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
var pool = batchClient.pool.add(poolConfig, function (error, result){
    if(error!=null){console.log(error.response)};
});

Sie können den Status des erstellten Pools überprüfen und sich vergewissern, dass er sich im Zustand „Aktiv“ befindet, bevor Sie einen Auftrag an diesen Pool übermitteln.

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

Im Anschluss sehen Sie ein Beispielergebnisobjekt, das von der Funktion „pool.get“ zurückgegeben wurde:

{
  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' }}

Schritt 4: Übermitteln eines Azure Batch-Auftrags

Ein Azure Batch-Auftrag ist eine logische Gruppe ähnlicher Aufgaben. In unserem Szenario lautet dies „Csv in JSON verarbeiten“. Jede Aufgabe hier kann die Verarbeitung von CSV-Dateien sein, die in jedem Azure Storage Container vorhanden sind.

Diese Aufgaben werden parallel ausgeführt, über mehrere Knoten hinweg bereitgestellt und vom Azure Batch-Dienst koordiniert.

Tipp

Mit der Eigenschaft taskSlotsPerNode können Sie die maximale Anzahl von Aufgaben angeben, die auf einem einzelnen Knoten gleichzeitig ausgeführt werden können.

Vorbereitungsaufgabe

Bei den erstellten VM-Knoten handelt es sich um leere Ubuntu-Knoten. Oftmals müssen zur Vorbereitung bestimmte Programme installiert werden. Für Linux-Knoten können Sie in der Regel ein Shellskript verwenden, das vor der Ausführung der eigentlichen Aufgaben die erforderlichen Komponenten installiert. Sie können jedoch auch eine andere programmierbare ausführbare Datei verwenden.

Das Shellskript in diesem Beispiel installiert „python-pip“ und das Azure Storage Blob SDK für Python.

Sie können das Skript in ein Azure Storage-Konto hochladen und einen SAS-URI für den Zugriff auf das Skript generieren. Dieser Prozess kann mit dem Azure Storage SDK für JavaScript auch automatisiert werden.

Tipp

Eine Vorbereitungsaufgabe für einen Auftrag wird nur auf den VM-Knoten ausgeführt, auf denen diese spezielle Aufgabe ausgeführt werden muss. Falls erforderliche Komponenten unabhängig von den ausgeführten Aufgaben auf allen Knoten installiert werden sollen, können Sie beim Hinzufügen eines Pools die Eigenschaft startTask verwenden. Verwenden Sie bei Bedarf die folgende Vorbereitungsaufgabendefinition als Referenz.

Eine Vorbereitungsaufgabe wird im Rahmen der Azure Batch-Auftragsübermittlung angegeben. Im Folgenden finden Sie einige konfigurierbare Parameter für die Vorbereitungsaufgabe:

  • ID: Ein eindeutiger Bezeichner für die Vorbereitungsaufgabe.
  • commandLine: Befehlszeile zum Ausführen der ausführbaren Aufgabendatei.
  • resourceFiles: Array mit Objekten, die Details zu Dateien angeben, welche zum Ausführen dieser Aufgabe heruntergeladen werden müssen. Verfügbare Optionen:
    • httpUrl: Die URL der herunterzuladenden Datei
    • filePath: Lokaler Pfad zum Herunterladen und Speichern der Datei.
    • fileMode: Nur relevant für Linux-Knoten. „fileMode“ wird im Oktalformat mit dem Standardwert „0770“ angegeben.
  • waitForSuccess: Wird dieser Parameter auf „true“ festgelegt, wird die Aufgabe nicht ausgeführt, wenn bei der Vorbereitungsaufgabe ein Fehler auftritt.
  • runElevated: Legen Sie diesen Parameter auf „true“ fest, falls für die Aufgabenausführung erhöhte Rechte erforderlich sind.

Der folgende Codeausschnitt zeigt das Skriptkonfigurationsbeispiel für die Vorbereitungsaufgabe:

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

Wenn zur Ausführung Ihrer Aufgaben keine erforderlichen Komponenten installiert werden müssen, können Sie die Vorbereitungsaufgaben überspringen. Der folgende Code erstellt einen Auftrag mit dem Anzeigenamen „process csv files“:

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

Schritt 5: Übermitteln von Azure Batch-Aufgaben für einen Auftrag

Nach der Erstellung des CSV-Verarbeitungsauftrags können wir nun Aufgaben für diesen Auftrag erstellen. Wenn wir beispielsweise über vier Container verfügen, müssen wir vier Aufgaben erstellen (jeweils eine pro Container).

Das Python-Skript akzeptiert zwei Parameter:

  • container_name: Der Storage-Container zum Herunterladen von Dateien.
  • pattern: Ein optionaler Parameter für das Dateinamensmuster.

Der folgende Code zeigt die Übermittlung von vier Aufgaben an den zuvor erstellten Azure Batch-Auftrag „process csv“ für vier Container („con1“, „con2“, „con3“ und „con4“).

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

Der Code fügt dem Pool mehrere Aufgaben hinzu. Jede dieser Aufgaben wird auf einem Knoten im Pool mit erstellten virtuellen Computern ausgeführt. Falls die Anzahl von Aufgaben die Anzahl virtueller Computer in einem Pool oder den Wert der Eigenschaft „taskSlotsPerNode“ übersteigt, wird gewartet, bis ein Knoten verfügbar gemacht wird. Diese Orchestrierung wird von Azure Batch automatisch durchgeführt.

Im Portal stehen detaillierte Ansichten für den Aufgaben- und Auftragsstatus zur Verfügung. Sie können aber auch die list- und get-Funktionen im Azure JavaScript SDK verwenden. Ausführliche Informationen finden Sie in der Dokumentation.

Nächste Schritte