Självstudie: Kör en parallell arbetsbelastning med Azure Batch med hjälp av .NET API

Använd Azure Batch till att effektivt köra storskaliga parallella program och HPC-program (databehandling med höga prestanda) i Azure. I den här självstudien går vi igenom ett C#-exempel på att köra en parallell arbetsbelastning med Batch. Du lär dig ett vanligt arbetsflöde för Batch-program och hur du interagerar programmatiskt med Batch- och Storage-resurser.

  • Lägg till ett programpaket till ditt Batch-konto.
  • Autentisera med Batch- och Storage-konton.
  • Ladda upp indatafiler till Storage.
  • Skapa en pool med beräkningsnoder för att köra ett program.
  • Skapa ett jobb och uppgifter för att bearbeta indatafiler.
  • Övervaka aktivitetskörning.
  • Hämta utdatafiler.

I den här självstudien konverterar du MP4-mediefiler till MP3-format parallellt med hjälp av verktyget ffmpeg med öppen källkod.

Om du inte har en Azure-prenumeration skapar du ett kostnadsfritt Azure-konto innan du börjar.

Förutsättningar

Logga in på Azure

Logga in på Azure-portalen.

Lägg till ett programpaket

Använd Azure-portalen och lägg till ffmpeg i Batch-kontot som ett programpaket. Med programpaket kan du hantera uppgiftsprogram och deras distribution till beräkningsnoderna i din pool.

  1. I Azure-portalen klickar du på Fler tjänster>Batch-konton och väljer namnet på ditt Batch-konto.

  2. Klicka på Program>Lägg till.

    Screenshot of the Applications section of the batch account.

  3. Ange ffmpeg i fältet Program-ID och en paketversion av 4.3.1 i fältet Version . Välj zip-filen ffmpeg som du laddade ned och välj sedan Skicka. Programpaketet för ffmpeg läggs till i Batch-kontot.

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

Hämta kontouppgifter

Du måste ange autentiseringsuppgifter för dina Batch- och Storage-konton i det här exemplet. Ett enkelt sätt att hämta de autentiseringsuppgifter som behövs är i Azure-portalen. (Du kan också hämta autentiseringsuppgifterna via Azures API:er och kommandoradsverktyg.)

  1. Välj Alla tjänster>Batch-konton och välj sedan namnet på ditt Batch-konto.

  2. Om du vill se Batch-autentiseringsuppgifterna väljer du Nycklar. Kopiera värdena för Batch-konto, URL och Primär åtkomstnyckel till en textredigerare.

  3. Om du vill se lagringskontots namn och nycklar väljer du Lagringskonto. Kopiera värdena för Lagringskontonamn och Key1 till en textredigerare.

Ladda ned och kör exempelappen

Ladda ned exempelprogrammet

Ladda ned eller klona exempelappen från GitHub. Om du vill klona lagringsplatsen för exempelappen med en Git-klient använder du följande kommando:

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

Navigera till katalogen som innehåller Visual Studio-lösningsfilen BatchDotNetFfmpegTutorial.sln.

Öppna lösningsfilen i Visual Studio och uppdatera autentiseringssträngarna i Program.cs med de värden som du fick för dina konton. Till exempel:

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

Kommentar

För att förenkla exemplet visas autentiseringsuppgifterna för Batch- och Storage-konto i klartext. I praktiken rekommenderar vi att du begränsar åtkomsten till autentiseringsuppgifterna och referera till dem i din kod med miljövariabler eller en konfigurationsfil. Exempel finns på lagringsplatsen med kodexempel för Azure Batch.

Kontrollera också att referensen för ffmpeg-programpaketet i lösningen matchar identifieraren och versionen av ffmpeg-paketet som du laddade upp till ditt Batch-konto. Till exempel ffmpeg och 4.3.1.

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

Skapa och kör exempelprojektet

Skapa och kör programmet i Visual Studio eller på kommandoraden med kommandona dotnet build och dotnet run. När du har kört appen ska du granska koden för att lära dig hur varje del av appen fungerar. Till exempel i Visual Studio:

  1. Högerklicka på lösningen i Solution Explorer och välj Skapa lösning.

  2. Bekräfta återställningen av NuGet-paket om du uppmanas att göra det. Om du behöver hämta paket som saknas ska du se till att NuGet Package Manager är installerad.

  3. Kör lösningen. När du kör exempelappen ser konsolens utdata ut ungefär så här. Under körningen uppstår det en paus vid Monitoring all tasks for 'Completed' state, timeout in 00:30:00... medan poolens beräkningsnoder startas.

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

Gå till Batch-kontot på Azure-portalen för att övervaka poolen, beräkningsnoderna, jobbet och aktiviteterna. Om du till exempel vill se en termisk karta över beräkningsnoderna i din pool klickar du på Pooler>WinFFmpegPool.

När uppgifter körs ser den termiska kartan ut ungefär så här:

Screenshot of the pool heat map in the Azure portal.

Körningen tar normalt runt 10 minuter om du kör programmet med standardkonfigurationen. Att skapa poolen är det som tar mest tid.

hämta utdatafilerna.

Du kan använda Azure-portalen till att hämta de utdatafiler i MP3-format som genereras av ffmpeg-uppgifter.

  1. Klicka på Alla tjänster>Lagringskonton och sedan på namnet på lagringskontot.
  2. Klicka på Blobbar>Utdata.
  3. Högerklicka på en av MP3-utdatafilerna och klicka sedan på Ladda ned. Följ anvisningarna i webbläsaren för att öppna eller spara filen.

Download output file

Även om det inte visas i det här exemplet kan du också ladda ned filerna programmatiskt från beräkningsnoderna eller från lagringscontainern.

Granska koden

I följande avsnitt bryter vi ned exempelprogrammet i de steg som utförs när en arbetsbelastning bearbetas i Batch-tjänsten. Se filen Program.cs i lösningen medan du läser resten av den här artikeln, eftersom inte alla kodrader i exemplet diskuteras.

Autentisera Blob- och Batch-klienter

I interaktionen med det länkade lagringskontot använder appen Azure Storage Client Library för .NET. En referens till kontot skapas med CloudStorageAccount och autentiseringen görs med hjälp av delad nyckel. Sedan skapas en CloudBlobClient.

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

Appen skapar ett BatchClient-objekt för att skapa och hantera pooler, jobb och uppgifter i Batch-tjänsten. Batch-klienten i exemplet använder autentisering med delad nyckel. Batch stöder också autentisering via Microsoft Entra-ID för att autentisera enskilda användare eller ett obevakat program.

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

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

Ladda upp indatafiler

Appen skickar blobClient-objektet till metoden CreateContainerIfNotExistAsync för att skapa en lagringscontainer för indatafilerna (MP4-format) och en container för uppgiftsutdata.

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

Sedan laddas filer upp till indatacontainern från den lokala mappen InputFiles . De lagrade filerna har definierats som Batch ResourceFile-objekt som Batch senare kan hämta till beräkningsnoder.

Två metoder i Program.cs är inblandade i att ladda upp filerna:

  • UploadFilesToContainerAsync: Returnerar en samling ResourceFile objekt och anropar UploadResourceFileToContainerAsync internt för att ladda upp varje fil som skickas i parametern inputFilePaths .
  • UploadResourceFileToContainerAsync: laddar upp varje fil som en blob till containern för indata. När filen har laddats upp hämtar den en signatur för delad åtkomst (SAS) för blobben och returnerar ett ResourceFile objekt som representerar den.
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);

Mer information om hur du laddar upp filer som blobar till ett lagringskonto med .NET finns i Ladda upp, ladda ned och lista blobar med hjälp av .NET.

Skapa en pool med beräkningsnoder

Därefter skapar exempelkoden en pool med beräkningsnoder i Batch-kontot med ett anrop till CreatePoolIfNotExistAsync. I den här definierade metoden används metoden BatchClient.PoolOperations.CreatePool till att ange antalet noder, VM-storlek och en poolkonfiguration. Här anger ett VirtualMachineConfiguration-objektet en ImageReference till en Windows Server-avbildning som publicerats på Azure Marketplace. Batch har stöd för ett stort antal Linux- och Windows Server-avbildningar på Azure Marketplace samt för anpassade VM-avbildningar.

Antalet noder och VM-storleken anges med definierade konstanter. Batch har stöd för dedikerade noder och spotnoder, och du kan använda antingen eller båda i dina pooler. Dedikerade noder är reserverade för din pool. Spotnoder erbjuds till ett reducerat pris från överskott av VM-kapacitet i Azure. Dekornoder blir otillgängliga om Azure inte har tillräckligt med kapacitet. Exemplet skapar som standard en pool som endast innehåller 5 oanvända noder i storlek Standard_A1_v2.

Kommentar

Kontrollera dina nodkvoter. Se Batch-tjänstkvoter och -gränser för instruktioner om hur du skapar en kvotbegäran.

Programmet ffmpeg distribueras till beräkningsnoderna genom att en ApplicationPackageReference läggs till i poolkonfigurationen.

Metoden CommitAsync skickar poolen till Batch-tjänsten.

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

Skapa ett jobb

Ett Batch-jobb anger en pool för körning av uppgifter, samt valfria inställningar som en prioritet och ett schema för arbetet. I exemplet skapas ett jobb med ett anrop till CreateJobAsync. I den här definierade metoden används metoden BatchClient.JobOperations.CreateJob till att skapa ett jobb i din pool.

Metoden CommitAsync skickar jobbet till Batch-tjänsten. Från början har jobbet inga aktiviteter.

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

await job.CommitAsync();

Skapa uppgifter

I exemplet skapas uppgifterna i jobbet med ett anrop till metoden AddTasksAsync, som skapar en lista med CloudTask-objekt. Varje CloudTask kör ffmpeg för bearbetning av ett ResourceFile-indataobjekt med egenskapen CommandLine. ffmpeg installerades tidigare på varje nod när poolen skapades. Här kör kommandoraden ffmpeg för att konvertera varje MP4-indatafil (video) till en MP3-fil (ljud).

I exemplet skapas ett OutputFile-objekt för MP3-filen när du kör kommandoraden. Varje uppgifts utdatafiler (i det här fallet en) laddas upp till en container i länkade lagringskontot med uppgiftsegenskapen OutputFiles. Tidigare i kodexemplet hämtades en signatur-URL för delad åtkomst (outputContainerSasUrl) för att ge skrivåtkomst till utdatacontainern. Observera de villkor som angetts på objektet outputFile. En utdatafil från en uppgift laddas upp till containern först när uppgiften har slutförts (OutputFileUploadCondition.TaskSuccess). Ytterligare information om implementering finns i det fullständiga kodexemplet på GitHub.

Sedan lägger exemplet till uppgifter i jobbet med metoden AddTaskAsync, som placerar dem i kö för att köras på beräkningsnoderna.

Ersätt filsökvägen för den körbara filen med namnet på den version som du laddade ned. Den här exempelkoden använder exemplet ffmpeg-4.3.1-2020-11-08-full_build.

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

Övervaka aktiviteter

När Batch lägger till uppgifter i ett jobb placerar tjänsten dem automatiskt i kö och schemalägger dem för körning vid beräkningsnoder i den associerade poolen. Baserat på de inställningar du anger sköter Batch all köhantering, all schemaläggning, alla omförsök och all annan uppgiftsadministration åt dig.

Du kan övervaka aktivitetskörningen på många sätt. I det här exemplet definieras metoden MonitorTasks för att rapportera endast vid slutförande och vid uppgiftstillstånden för fel eller framgång. Koden i MonitorTasks anger en ODATADetailLevel så att endast minimalt med information om uppgifterna väljs. Sedan skapas en TaskStateMonitor som tillhandahåller hjälpkomponenter för övervakning av uppgiftstillstånd. I MonitorTasks väntar exemplet på att alla uppgifter ska nå TaskState.Completed inom en tidsgräns. Sedan avslutas jobbet och alla uppgifter som slutfördes men där det kan ha uppstått ett fel rapporteras, till exempel vid slutkoder skilda från noll.

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

Rensa resurser

När uppgifterna har körts tar appen automatiskt bort den lagringscontainer som skapades och du får möjlighet att ta bort Batch-poolen och jobbet. Klasserna JobOperations och PoolOperations i BatchClient har båda motsvarande borttagningsmetoder som anropas om du bekräftar borttagningen. Även om du inte debiteras för själva jobben och aktiviteterna debiteras du för beräkningsnoder. Vi rekommenderar därför att du endast allokerar pooler efter behov. När du tar bort poolen raderas alla aktivitetsutdata på noderna. Utdatafilerna ligger däremot kvar i lagringskontot.

När de inte längre behövs tar du bort resursgruppen, Batch-kontot och lagringskontot. Om du vill göra det i Azure-portalen väljer du resursgruppen för Batch-kontot och klickar på Ta bort resursgrupp.

Nästa steg

I den här självstudiekursen lärde du dig att:

  • Lägg till ett programpaket till ditt Batch-konto.
  • Autentisera med Batch- och Storage-konton.
  • Ladda upp indatafiler till Storage.
  • Skapa en pool med beräkningsnoder för att köra ett program.
  • Skapa ett jobb och uppgifter för att bearbeta indatafiler.
  • Övervaka aktivitetskörning.
  • Hämta utdatafiler.

Fler exempel på hur du använder .NET API för att schemalägga och bearbeta Batch-arbetsbelastningar finns i Batch C#-exemplen på GitHub.