Zelfstudie: Een parallelle workload uitvoeren met Azure Batch met behulp van de .NET API

Met Azure Batch kunt u grootschalige parallelle en HPC-batchrekentaken (High Performance Computing) efficiënt uitvoeren in Azure. Deze zelfstudie leidt u door een C#-voorbeeld van het uitvoeren van een parallelle workload met behulp van Batch. U leert een gangbare Batch-toepassingswerkstroom en leert hoe u via programmacode werkt met Batch- en Storage-bronnen.

  • Voeg een toepassingspakket toe aan uw Batch-account.
  • Verifiëren met Batch- en Storage-accounts.
  • Invoerbestanden uploaden naar Storage.
  • Maak een groep rekenknooppunten om een toepassing uit te voeren.
  • Maak een taak en taken om invoerbestanden te verwerken.
  • Taakuitvoering bewaken.
  • Uitvoerbestanden ophalen.

In deze zelfstudie converteert u MP4-mediabestanden naar mp3-indeling, parallel met behulp van het opensource-hulpprogramma ffmpeg .

Als u geen Azure-abonnement hebt, kunt u een gratis Azure-account maken voordat u begint.

Vereisten

  • Visual Studio 2017 of hoger, of .NET Core SDK voor Linux, macOS of Windows.

  • Een Batch-account en een gekoppeld Azure Storage-account. Als u deze accounts wilt maken, raadpleegt u de Batch-quickstartgidsen voor Azure Portal of Azure CLI.

  • Download de juiste versie van ffmpeg voor uw use case naar uw lokale computer. In deze zelfstudie en de bijbehorende voorbeeld-app wordt de volledige buildversie van Windows 64-bits van ffmpeg 4.3.1 gebruikt. Voor deze zelfstudie hebt u alleen het zip-bestand nodig. U hoeft het bestand niet uit te pakken of lokaal te installeren.

Aanmelden bij Azure

Meld u aan bij de Azure-portal.

Een toepassingspakket toevoegen

Gebruik de Azure Portal om ffmpeg als een toepassingspakket toe te voegen aan uw Batch-account. Toepassingspakketten helpen u bij het beheer van taaktoepassingen en de implementatie ervan in de rekenknooppunten in uw pool.

  1. Klik in Azure Portal op Meer services>Batch-accounts en selecteer de naam van uw Batch-account.

  2. Klik op Toepassingen>Toevoegen.

    Screenshot of the Applications section of the batch account.

  3. Voer ffmpeg in het veld Toepassings-id en een pakketversie van 4.3.1 in het veld Versie in. Selecteer het zip-bestand ffmpeg dat u hebt gedownload en selecteer vervolgens Verzenden. Het toepassingspakket voor ffmpeg wordt toegevoegd aan uw Batch-account.

    Screenshot of the ID and version fields in the Add application section.

Accountreferenties ophalen

In dit voorbeeld moet u referenties opgeven voor uw Batch- en Storage-accounts. U kunt de referenties eenvoudig ophalen in Azure Portal. (U kunt deze referenties ook ophalen met de Azure-API's of de opdrachtregelprogramma's.)

  1. Selecteer Alle services>Batch-accounts en selecteer vervolgens de naam van uw Batch-account.

  2. Selecteer Sleutels om de Batch-referenties te zien. Kopieer de waarden van Batch-account, URL en Primaire toegangssleutel in een teksteditor.

  3. Selecteer Opslagaccount als u de naam en sleutels van het opslagaccount wilt zien. Kopieer de waarden van Naam van opslagaccount en Key1 in een teksteditor.

De voorbeeld-app downloaden en uitvoeren

De voorbeeld-app downloaden

Download of kloon de voorbeeld-app vanuit GitHub. Als u de opslagplaats van de voorbeeld-app wilt klonen met een Git-client, gebruikt u de volgende opdracht:

git clone https://github.com/Azure-Samples/batch-dotnet-ffmpeg-tutorial.git

Navigeer naar de map met het Visual Studio-oplossingsbestand BatchDotNetFfmpegTutorial.sln.

Open het oplossingsbestand in Visual Studio en werk de referentiereeksen in Program.cs bij met de waarden die u voor uw accounts hebt verkregen. Bijvoorbeeld:

// Batch account credentials
private const string BatchAccountName = "yourbatchaccount";
private const string BatchAccountKey  = "xxxxxxxxxxxxxxxxE+yXrRvJAqT9BlXwwo1CwF+SwAYOxxxxxxxxxxxxxxxx43pXi/gdiATkvbpLRl3x14pcEQ==";
private const string BatchAccountUrl  = "https://yourbatchaccount.yourbatchregion.batch.azure.com";

// Storage account credentials
private const string StorageAccountName = "yourstorageaccount";
private const string StorageAccountKey  = "xxxxxxxxxxxxxxxxy4/xxxxxxxxxxxxxxxxfwpbIC5aAWA8wDu+AFXZB827Mt9lybZB1nUcQbQiUrkPtilK5BQ==";

Notitie

Ter vereenvoudiging van het voorbeeld worden de Batch- en Storage-accountreferenties in niet-versleutelde tekst weergegeven. In de praktijk wordt aangeraden dat u de toegang tot de referenties beperkt en hiernaar verwijst in uw code met behulp van omgevingsvariabelen of een configuratiebestand. Zie de codevoorbeelden-opslagplaats van Azure Batch voor voorbeelden.

Zorg er ook voor dat de verwijzing naar het ffmpeg-toepassingspakket in de oplossing overeenkomt met de id en versie van het ffmpeg-pakket dat u hebt geüpload naar uw Batch-account. Bijvoorbeeld ffmpeg en 4.3.1.

const string appPackageId = "ffmpeg";
const string appPackageVersion = "4.3.1";

Het voorbeeldproject compileren en uitvoeren

Bouw de toepassing in Visual Studio en voer deze uit. U kunt ook de opdrachtregel gebruiken met de opdrachten dotnet build en dotnet run. Nadat de toepassing is uitgevoerd, bekijkt u de code voor meer informatie over wat elk onderdeel van de toepassing doet. Dit kan bijvoorbeeld als volgt in Visual Studio:

  1. Klik met de rechtermuisknop op de oplossing in Solution Explorer en selecteer Oplossing bouwen.

  2. Bevestig het herstel van alle NuGet-pakketten als dit wordt gevraagd. Als u ontbrekende pakketten wilt downloaden, zorgt u ervoor dat NuGet-pakketbeheer is geïnstalleerd.

  3. Voer de oplossing uit. Wanneer u de voorbeeldtoepassing uitvoert, ziet de uitvoer van de console er ongeveer als volgt uit. De actieve uitvoering wordt bij Monitoring all tasks for 'Completed' state, timeout in 00:30:00... onderbroken terwijl de rekenknooppunten van de pool worden gestart.

Sample start: 11/19/2018 3:20:21 PM

Container [input] created.
Container [output] created.
Uploading file LowPriVMs-1.mp4 to container [input]...
Uploading file LowPriVMs-2.mp4 to container [input]...
Uploading file LowPriVMs-3.mp4 to container [input]...
Uploading file LowPriVMs-4.mp4 to container [input]...
Uploading file LowPriVMs-5.mp4 to container [input]...
Creating pool [WinFFmpegPool]...
Creating job [WinFFmpegJob]...
Adding 5 tasks to job [WinFFmpegJob]...
Monitoring all tasks for 'Completed' state, timeout in 00:30:00...
Success! All tasks completed successfully within the specified timeout period.
Deleting container [input]...

Sample end: 11/19/2018 3:29:36 PM
Elapsed time: 00:09:14.3418742

Ga naar uw Batch-account in de Azure Portal om de pool, rekenknooppunten, job en taken te controleren. Als u bijvoorbeeld een heatmap van de rekenknooppunten in uw pool wilt zien, klikt u op Pools>WinFFmpegPool.

Wanneer taken worden uitgevoerd, ziet de heatmap er bijvoorbeeld als volgt uit:

Screenshot of the pool heat map in the Azure portal.

Wanneer u de toepassing uitvoert in de standaardconfiguratie, bedraagt de uitvoeringstijd doorgaans ongeveer 10 minuten. Het maken van de pool kost de meeste tijd.

Uitvoerbestanden ophalen

U kunt in Azure Portal de MP3-uitvoerbestanden downloaden die in de ffmpeg-taken zijn gegenereerd.

  1. Klik op Alle services>Opslagaccounts en klik vervolgens op de naam van uw opslagaccount.
  2. Klik op Blobs>uitvoer.
  3. Klik met de rechtermuisknop op een van de MP3-uitvoerbestanden en klik vervolgens op Downloaden. Volg de aanwijzingen in de browser om het bestand te openen of op te slaan.

Download output file

Hoewel dit niet in dit voorbeeld wordt getoond, kunt u de bestanden ook programmatisch downloaden in de rekenknooppunten of in de opslagcontainer.

De code bekijken

In de volgende secties wordt de voorbeeldtoepassing uitgesplitst in de stappen die ermee worden uitgevoerd om een workload in de Batch-service te verwerken. Raadpleeg het bestand Program.cs in de oplossing terwijl u de rest van dit artikel leest, omdat niet elke regel code in het voorbeeld wordt besproken.

Blob- en Batch-clients verifiëren

Om te kunnen werken met het gekoppelde opslagaccount, gebruikt de app de Azure Storage-clientbibliotheek voor .NET. Er wordt een verwijzing naar het account gemaakt met CloudStorageAccount, waarbij verificatie met gedeelde sleutels wordt gebruikt. Vervolgens wordt een CloudBlobClient gemaakt.

// Construct the Storage account connection string
string storageConnectionString = String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
                                StorageAccountName, StorageAccountKey);

// Retrieve the storage account
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

De app maakt een BatchClient-object om pools, jobs en taken in de Batch-service te maken en te beheren. De Batch-client in het voorbeeld gebruikt verificatie met gedeelde sleutels. Batch biedt ook ondersteuning voor verificatie via Microsoft Entra-id om afzonderlijke gebruikers of een toepassing zonder toezicht te verifiëren.

BatchSharedKeyCredentials sharedKeyCredentials = new BatchSharedKeyCredentials(BatchAccountUrl, BatchAccountName, BatchAccountKey);

using (BatchClient batchClient = BatchClient.Open(sharedKeyCredentials))
...

Invoerbestanden uploaden

De app geeft het object blobClient door aan de methode CreateContainerIfNotExistAsync om een opslagcontainer voor de invoerbestanden (MP4-indeling) en een container voor de taakuitvoer te maken.

CreateContainerIfNotExistAsync(blobClient, inputContainerName);
CreateContainerIfNotExistAsync(blobClient, outputContainerName);

Vervolgens worden bestanden vanuit de lokale map InputFiles geüpload naar de invoercontainer. De bestanden in de opslag zijn gedefinieerd als Batch ResourceFile-objecten die later met Batch kunnen worden gedownload op rekenknooppunten.

Er zijn twee methoden in Program.cs betrokken bij het uploaden van de bestanden:

  • UploadFilesToContainerAsync: retourneert een verzameling ResourceFile objecten en intern aanroepen UploadResourceFileToContainerAsync om elk bestand te uploaden dat in de inputFilePaths parameter wordt doorgegeven.
  • UploadResourceFileToContainerAsync: deze methode uploadt elk bestand als een blob naar de invoercontainer. Nadat het bestand is geüpload, krijgt het een SAS (Shared Access Signature) voor de blob en wordt een ResourceFile object geretourneerd dat het bestand vertegenwoordigt.
string inputPath = Path.Combine(Environment.CurrentDirectory, "InputFiles");

List<string> inputFilePaths = new List<string>(Directory.GetFileSystemEntries(inputPath, "*.mp4",
    SearchOption.TopDirectoryOnly));

List<ResourceFile> inputFiles = await UploadFilesToContainerAsync(
  blobClient,
  inputContainerName,
  inputFilePaths);

Voor meer informatie over het uploaden van bestanden als blobs naar een opslagaccount met .NET raadpleegt u Blobs uploaden, downloaden en weergeven met behulp van .NET.

Een pool met rekenknooppunten maken

Daarna wordt in het voorbeeld met behulp van een aanroep naar CreatePoolIfNotExistAsync een pool van rekenknooppunten in het Batch-account gemaakt. Deze gedefinieerde methode gebruikt de methode BatchClient.PoolOperations.CreatePool om het aantal knooppunten, de VM-grootte en de poolconfiguratie in te stellen. Hier geeft het VirtualMachineConfiguration-object een ImageReference naar een Windows Server-installatiekopie op die is gepubliceerd in Azure Marketplace. Batch ondersteunt diverse VM-installatiekopieën in de Azure Marketplace, evenals aangepaste VM-installatiekopieën.

Het aantal knooppunten en de VM-grootte worden ingesteld met behulp van gedefinieerde constanten. Batch ondersteunt toegewezen knooppunten en Spot-knooppunten. U kunt beide of beide in uw pools gebruiken. Toegewezen rekenknooppunten zijn gereserveerd voor uw pool. Spot-knooppunten worden aangeboden tegen een gereduceerde prijs van overschot aan VM-capaciteit in Azure. Spot-knooppunten zijn niet beschikbaar als Azure onvoldoende capaciteit heeft. In het voorbeeld wordt standaard een pool gemaakt met slechts 5 spot-knooppunten in grootte Standard_A1_v2.

Notitie

Controleer de quota van uw knooppunten. Zie quota en limieten voor Batch-service voor instructies over het maken van een quotumaanvraag.

De toepassing ffmpeg wordt geïmplementeerd in de rekenknooppunten door een ApplicationPackageReference toe te voegen aan de poolconfiguratie.

Met de CommitAsync-methode wordt de pool naar de Batch-service verzonden.

ImageReference imageReference = new ImageReference(
    publisher: "MicrosoftWindowsServer",
    offer: "WindowsServer",
    sku: "2016-Datacenter-smalldisk",
    version: "latest");

VirtualMachineConfiguration virtualMachineConfiguration =
    new VirtualMachineConfiguration(
    imageReference: imageReference,
    nodeAgentSkuId: "batch.node.windows amd64");

pool = batchClient.PoolOperations.CreatePool(
    poolId: poolId,
    targetDedicatedComputeNodes: DedicatedNodeCount,
    targetLowPriorityComputeNodes: LowPriorityNodeCount,
    virtualMachineSize: PoolVMSize,
    virtualMachineConfiguration: virtualMachineConfiguration);

pool.ApplicationPackageReferences = new List<ApplicationPackageReference>
    {
    new ApplicationPackageReference {
    ApplicationId = appPackageId,
    Version = appPackageVersion}};

await pool.CommitAsync();  

Een taak maken

Een Batch-taak (job) geeft een pool op die taken moet uitvoeren en optionele instellingen, zoals een prioriteit en planning voor het werk. In het voorbeeld wordt een job gemaakt met een aanroep naar CreateJobAsync. Deze gedefinieerde methode gebruikt de methode BatchClient.JobOperations.CreateJob om een taak te maken in uw pool.

Met de CommitAsync-methode wordt de taak naar de Batch-service verzonden. De Batch-taak heeft in eerste instantie geen taken.

CloudJob job = batchClient.JobOperations.CreateJob();
job.Id = JobId;
job.PoolInformation = new PoolInformation { PoolId = PoolId };

await job.CommitAsync();

Taken maken

In het voorbeeld worden taken in de job gemaakt met een aanroep van de methode AddTasksAsync, die een lijst met CloudTask-objecten maakt. Elke CloudTask voert ffmpeg uit om een ResourceFile-invoerobject met de eigenschap CommandLine te verwerken. ffmpeg is eerder op elk knooppunt geïnstalleerd toen de pool werd gemaakt. Hier voert de opdrachtregel ffmpeg uit om elk MP4-invoerbestand (video) te converteren naar een MP3-bestand (audio).

Het voorbeeld maakt een OutputFile-object voor het MP3-bestand nadat de opdrachtregel is uitgevoerd. De uitvoerbestanden van elke taak (één in dit geval) worden geüpload naar een container in het gekoppelde opslagaccount met behulp van de eigenschap OutputFiles van de taak. In het codevoorbeeld werd voorheen een Shared Access Signature-URL (outputContainerSasUrl) verkregen om schrijftoegang te verlenen aan de uitvoercontainer. Schrijf de voorwaarden op die voor het outputFile-object zijn ingesteld. Een uitvoerbestand van een taak wordt alleen naar de container geüpload nadat de taak is voltooid (OutputFileUploadCondition.TaskSuccess). Zie het volledige codevoorbeeld op GitHub voor nadere implementatiedetails.

Vervolgens voegt het voorbeeld taken toe aan de taak met de methode AddTaskAsync, die ze in de wachtrij plaatst voor uitvoering op de rekenknooppunten.

Vervang het bestandspad van het uitvoerbare bestand door de naam van de versie die u hebt gedownload. In deze voorbeeldcode wordt het voorbeeld ffmpeg-4.3.1-2020-11-08-full_buildgebruikt.

 // Create a collection to hold the tasks added to the job.
List<CloudTask> tasks = new List<CloudTask>();

for (int i = 0; i < inputFiles.Count; i++)
{
    string taskId = String.Format("Task{0}", i);

    // Define task command line to convert each input file.
    string appPath = String.Format("%AZ_BATCH_APP_PACKAGE_{0}#{1}%", appPackageId, appPackageVersion);
    string inputMediaFile = inputFiles[i].FilePath;
    string outputMediaFile = String.Format("{0}{1}",
        System.IO.Path.GetFileNameWithoutExtension(inputMediaFile),
        ".mp3");
    string taskCommandLine = String.Format("cmd /c {0}\\ffmpeg-4.3.1-2020-09-21-full_build\\bin\\ffmpeg.exe -i {1} {2}", appPath, inputMediaFile, outputMediaFile);

    // Create a cloud task (with the task ID and command line)
    CloudTask task = new CloudTask(taskId, taskCommandLine);
    task.ResourceFiles = new List<ResourceFile> { inputFiles[i] };

    // Task output file
    List<OutputFile> outputFileList = new List<OutputFile>();
    OutputFileBlobContainerDestination outputContainer = new OutputFileBlobContainerDestination(outputContainerSasUrl);
    OutputFile outputFile = new OutputFile(outputMediaFile,
       new OutputFileDestination(outputContainer),
       new OutputFileUploadOptions(OutputFileUploadCondition.TaskSuccess));
    outputFileList.Add(outputFile);
    task.OutputFiles = outputFileList;
    tasks.Add(task);
}

// Add tasks as a collection
await batchClient.JobOperations.AddTaskAsync(jobId, tasks);
return tasks

Taken controleren

Wanneer Batch taken toevoegt aan een job, plaatst de service ze automatisch in de wachtrij en plant de uitvoering ervan op rekenknooppunten in de gekoppelde pool. Op basis van de instellingen die u opgeeft, zal Batch alle taken in de wachtrij plaatsen, plannen en opnieuw proberen uit te voeren, en ook andere taakbeheertaken uitvoeren.

Er zijn veel manieren om de uitvoering van taken te controleren. In dit voorbeeld wordt de methode MonitorTasks gedefinieerd om alleen te rapporteren bij voltooiing en wanneer de taak de status mislukt of geslaagd heeft. De code MonitorTasks geeft een ODATADetailLevel op om efficiënt alleen minimale informatie over de taken te selecteren. Vervolgens wordt een TaskStateMonitor gemaakt die hulpprogramma's voor het controleren van taakstatussen biedt. In MonitorTasks wacht het voorbeeld totdat alle taken TaskState.Completed bereiken binnen een tijdslimiet. Vervolgens wordt de job beëindigd en worden taken gerapporteerd die zijn voltooid, maar waarbij een fout is opgetreden, zoals een afsluitcode die niet nul is.

TaskStateMonitor taskStateMonitor = batchClient.Utilities.CreateTaskStateMonitor();
try
{
    await taskStateMonitor.WhenAll(addedTasks, TaskState.Completed, timeout);
}
catch (TimeoutException)
{
    batchClient.JobOperations.TerminateJob(jobId);
    Console.WriteLine(incompleteMessage);
    return false;
}
batchClient.JobOperations.TerminateJob(jobId);
 Console.WriteLine(completeMessage);
...

Resources opschonen

Nadat de taken zijn uitgevoerd, verwijdert de app automatisch de gemaakte invoeropslagcontainer en biedt u de mogelijkheid de Batch-pool en -taak te verwijderen. De klassen JobOperations en PoolOperations van BatchClient hebben overeenkomstige verwijderingsmethoden, die worden aangeroepen wanneer u de verwijdering bevestigt. Hoewel jobs en taken zelf niet in rekening worden gebracht, worden rekenknooppunten wel in rekening gebracht. Daarom is het raadzaam om pools alleen toe te wijzen als dat nodig is. Wanneer u de pool verwijdert, wordt ook alle taakuitvoer op de knooppunten verwijderd. De uitvoerbestanden blijven echter aanwezig in het opslagaccount.

Verwijder de resourcegroep, het Batch-account en het opslagaccount wanneer u deze niet meer nodig hebt. Hiervoor selecteert u in Azure Portal de resourcegroep voor het Batch-account en klikt u op Resourcegroep verwijderen.

Volgende stappen

In deze zelfstudie heeft u het volgende geleerd:

  • Voeg een toepassingspakket toe aan uw Batch-account.
  • Verifiëren met Batch- en Storage-accounts.
  • Invoerbestanden uploaden naar Storage.
  • Maak een groep rekenknooppunten om een toepassing uit te voeren.
  • Maak een taak en taken om invoerbestanden te verwerken.
  • Taakuitvoering bewaken.
  • Uitvoerbestanden ophalen.

Zie de Batch C#-voorbeelden op GitHub voor meer voorbeelden van het gebruik van de .NET-API om Batch-workloads te plannen en verwerken.