Dela via


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

Använd Azure Batch för att effektivt köra storskaliga parallella och högpresterande databehandlingsjobb (HPC) i Azure. I den här handledningen går vi igenom ett C#-exempel på hur du kör parallella arbetsuppgifter med Batch. Du lär dig en vanlig arbetsflöde för Batch-applikationer och hur du programmatiskt kan interagera med Batch- och Storage-resurser.

  • Lägg till ett applikationspaket i ditt Batch-konto.
  • Autentisera med Batch- och lagringskonton.
  • Ladda upp indatafiler till Storage.
  • Skapa en pool av beräkningsnoder för att köra en applikation.
  • Skapa ett jobb och uppgifter för att bearbeta inmatningsfiler.
  • Övervaka uppgiftsutförande.
  • Hämta utdatafiler.

I denna handledning konverterar du MP4-mediefiler till MP3-format parallellt genom att använda verktyget ffmpeg med öppen källkod.

Om du inte har något Azure-konto skapar du ett kostnadsfritt konto innan du börjar.

Förutsättningar

Logga in på Azure

Logga in på Azure-portalen.

Lägg till ett applikationspaket

Använd Azure-portalen för att lägga till ffmpeg till ditt Batch-konto som ett applikationspaket. Programpaket hjälper dig att hantera aktivitetsprogram och deras distribution till beräkningsnoderna i din pool.

  1. I Azure-portalen, klicka på Fler tjänster>Batchkonton, och välj namnet på ditt Batchkonto.

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

    Skärmbild av avsnittet Program i batchkontot.

  3. Ange ffmpeg i fältet Application Id, och en paketversion av 4.3.1 i fältet Version. Välj ffmpeg zip-filen som du har laddat ner och välj sedan Skicka in. Ffmpeg-applikationspaketet har lagts till i ditt Batch-konto.

    Skärmbild av ID- och versionsfälten i avsnittet Lägg till applikation.

Hämta kontouppgifter

För det här exemplet måste du ange referenser för dina Batch- och Lagringskonton. Ett enkelt sätt att få de nödvändiga autentiseringsuppgifterna är i Azure-portalen. (Du kan också få dessa autentiseringsuppgifter med Azure APIs eller kommandoradsverktyg.)

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

  2. För att se Batch-autentiseringsuppgifterna, välj Keys. Kopiera värdena för Batchkonto, URL och Primär åtkomstnyckel till en textredigerare.

  3. För att se lagringskontots namn och nycklar, välj lagringskonto. Kopiera värdena för Lagringskontonamn och Nyckel1 till en textredigerare.

Ladda ner och kör exempelappen

Ladda ner exempalappen

Ladda ner 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

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

Steg 2: Se till att referensen till ffmpeg-applikationspaketet i lösningen matchar identifieraren och versionen av ffmpeg-paketet som du har laddat 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 programmet granskar du koden för att lära dig vad varje del av programmet gör. 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 eventuella NuGet-paket, om du blir uppmanad. Om du behöver ladda ner saknade paket, se till att NuGet Package Manager är installerad.

  3. Kör lösningen. När du kör exempelapplikationen, är konsolutskriften liknande följande. Under körningen upplever du en paus vid Monitoring all tasks for 'Completed' state, timeout in 00:30:00... medan poolens datorknuter 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 värmekarta över beräkningsnoderna i poolen klickar du på Pooler>WinFFmpegPool.

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

Skärmbild av poolvärmekartan i Azure-portalen.

Den typiska körtiden är ungefär 10 minuter när du kör programmet i dess standardkonfiguration. 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å Blobs>output.
  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.

Ladda ned utdatafil

Även om det inte visas i det här exemplet kan du också programmera för att hämta filer från beräkningsnoderna eller från lagringsbehållaren.

Granska koden

Följande avsnitt bryter ner exempelapplikationen i de steg som den utför för att bearbeta en arbetsbelastning 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

För att interagera med det länkade lagringskontot använder appen Azure.Storage.Blobs-biblioteket för .NET. Använd klassen BlobServiceClient som tar en referens till kontots Uri och autentiserar med en Token som DefaultAzureCredential.

// TODO: Replace <storage-account-name> with your actual storage account name
Uri accountUri = new Uri("https://<storage-account-name>.blob.core.windows.net/");
BlobServiceClient blobClient = new BlobServiceClient(accountUri, new DefaultAzureCredential());

Appen skapar en referens till BatchAccountResource via resurschefens ArmClient för att skapa poolen i Batch-tjänsten. Arm-klienten i exemplet använder DefaultAzureCredential-autentisering.

ArmClient _armClient = new ArmClient(new DefaultAzureCredential());
var batchAccountIdentifier = ResourceIdentifier.Parse(BatchAccountResourceID);
BatchAccountResource batchAccount = await _armClient.GetBatchAccountResource(batchAccountIdentifier).GetAsync();

Appen skapar ett BatchClient-objekt för att skapa jobb och uppgifter i Batch-tjänsten. Exempelkodens Batch-klient använder DefaultAzureCredential autentisering.

// TODO: Replace <batch-account-name> with your actual storage account name
Uri batchUri = new Uri("https://<batch-account-name>t.eastus.batch.azure.com");
BatchClient _batchClient = new BatchClient(batchUri, new DefaultAzureCredential());

Ladda upp inmatningsfiler

Appen överför blobServerClient objektet till CreateContainerIfNotExist metoden för att skapa en lagringsbehållare för indatafilerna (MP4-format) och en behållare för uppgiftens utdata.

CreateContainerIfNotExist(blobClient, inputContainerName);
CreateContainerIfNotExist(blobClient, outputContainerName);

Sedan laddas filer upp till indatacontainern från den lokala mappen InputFiles . Filerna i lagringen definieras som Batch ResourceFile-objekt som Batch senare kan ladda ner till beräkningsnoder.

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

  • UploadFilesToContainerAsync: Returnerar en samling av ResourceFile-objekt och kallar internt UploadResourceFileToContainerAsync för att ladda upp varje fil som skickas i inputFilePaths-parametern.
  • UploadResourceFileToContainerAsync: Laddar upp varje fil som en blob till inmatningsbehållaren. Efter att ha laddat upp filen får den en delad åtkomstsignatur (SAS) för blobben och returnerar ett ResourceFile objekt för att representera det.
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);

För detaljer om hur du laddar upp filer som blobbar till ett lagringskonto med .NET, se Ladda upp, ladda ner och lista blobbar med .NET.

Skapa en pool av datorknutar

Därefter skapar exempelkoden en pool med beräkningsnoder i Batch-kontot med ett anrop till CreatePoolIfNotExistAsync. Denna definierade metod använder metoden BatchAccountResource.GetBatchAccountPools().CreateOrUpdateAsync för att ställa in antalet noder, VM-storlek och en poolkonfiguration. Här specificerar ett BatchVmConfiguration-objekt en BatchImageReference till en Windows Server-avbildning som publicerats i Azure Marketplace. Batch stöder ett brett utbud av VM-avbildningar i Azure Marketplace samt anpassade VM-avbildningar.

Antalet noder och VM-storlek sätts med hjälp av definierade konstanter. Batch stöder dedikerade noder och Spot nodes, 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. Spot-noder blir otillgängliga om Azure inte har tillräckligt med kapacitet. Exemplet skapar som standard en pool som bara innehåller 5 Spot-noder i storlek Standard_A1_v2.

Anmärkning

Se till att du kontrollerar dina nodkvoter. Se Batch service kvoter och gränser för instruktioner om hur du skapar en kvotförfrågan.

ffmpeg-programmet distribueras till beräkningsnoderna genom att lägga till en ApplicationPackageReference i poolkonfigurationen.

var credential = new DefaultAzureCredential();
ArmClient _armClient = new ArmClient(credential);

var batchAccountIdentifier = ResourceIdentifier.Parse(BatchAccountResourceID);
BatchAccountResource batchAccount = await _armClient.GetBatchAccountResource(batchAccountIdentifier).GetAsync();

BatchAccountPoolCollection collection = batchAccount.GetBatchAccountPools();
if (collection.Exists(poolId) == false)
{
    var poolName = poolId;
    var imageReference = new BatchImageReference()
    {
        Publisher = "MicrosoftWindowsServer",
        Offer = "WindowsServer",
        Sku = "2019-datacenter-smalldisk",
        Version = "latest"
    };
    string nodeAgentSku = "batch.node.windows amd64";


    ArmOperation<BatchAccountPoolResource> armOperation = await batchAccount.GetBatchAccountPools().CreateOrUpdateAsync(
        WaitUntil.Completed, poolName, new BatchAccountPoolData()
        {
            VmSize = "Standard_DS1_v2",
            DeploymentConfiguration = new BatchDeploymentConfiguration()
            {
                VmConfiguration = new BatchVmConfiguration(imageReference, nodeAgentSku)
            },
            ScaleSettings = new BatchAccountPoolScaleSettings()
            {
                FixedScale = new BatchAccountFixedScaleSettings()
                {
                    TargetDedicatedNodes = DedicatedNodeCount,
                    TargetLowPriorityNodes = LowPriorityNodeCount
                }
            },
            Identity = new ManagedServiceIdentity(ManagedServiceIdentityType.UserAssigned)
            {
                UserAssignedIdentities =
                {
                        [new ResourceIdentifier(ManagedIdentityId)] = new Azure.ResourceManager.Models.UserAssignedIdentity(),
                },
            },
            ApplicationPackages =
            {
                    new Azure.ResourceManager.Batch.Models.BatchApplicationPackageReference(new ResourceIdentifier(appPackageResourceID))
                    {
                        Version = appPackageVersion,
                    }
            },

        });
    BatchAccountPoolResource pool = armOperation.Value;

Skapa ett jobb

En batch-jobb anger en pool att köra uppgifter i och valfria inställningar, såsom prioritet och schema för arbetet. Exemplet skapar ett jobb med ett anrop till CreateJobAsync. Den här definierade metoden använder BatchClient.CreateJobAsync-metoden för att skapa ett jobb på din pool.

 BatchJobCreateContent batchJobCreateContent = new BatchJobCreateContent(jobId, new BatchPoolInfo { PoolId = poolId });
 await batchClient.CreateJobAsync(batchJobCreateContent);

Skapa uppgifter

Exemplet skapar uppgifter i jobbet med ett anrop till AddTasksAsync metoden, vilket skapar en lista över BatchTask-objekt . Varje BatchTask kör ffmpeg för att bearbeta ett indataResourceFile-objekt med hjälp av en CommandLine-egenskap. ffmpeg installerades tidigare på varje nod när poolen skapades. Här kör kommandoraden ffmpeg för att konvertera varje inmatad MP4 (video) fil till en MP3 (ljud) fil.

I exemplet skapas ett OutputFile-objekt för MP3-filen när du kör kommandoraden. Varje aktivitets utdatafiler (en i det här fallet) laddas upp till en container i det länkade lagringskontot med hjälp av aktivitetens outputfiles-egenskap . Observera de villkor som angetts för outputFile objektet. En utdatafil från en aktivitet laddas bara upp till containern när uppgiften har slutförts (OutputFileUploadCondition.TaskSuccess). Mer information om implementering finns i det fullständiga kodexemplet på GitHub.

Sedan lägger exemplet till uppgifter till jobbet med metoden CreateTaskAsync, vilket köar dem för att köras på beräkningsnoderna.

Ersätt körbarens filsökväg med namnet på den version du laddade ner. 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<BatchTaskCreateContent> tasks = new List<BatchTaskCreateContent>();

for (int i = 0; i < inputFiles.Count; i++)
{
    // Assign a task ID for each iteration
    string taskId = String.Format("Task{0}", i);

    // Define task command line to convert the video format from MP4 to MP3 using ffmpeg.
    // Note that ffmpeg syntax specifies the format as the file extension of the input file
    // and the output file respectively. In this case inputs are MP4.
    string appPath = String.Format("%AZ_BATCH_APP_PACKAGE_{0}#{1}%", appPackageId, appPackageVersion);
    string inputMediaFile = inputFiles[i].StorageContainerUrl;
    string outputMediaFile = String.Format("{0}{1}",
        System.IO.Path.GetFileNameWithoutExtension(inputMediaFile),
        ".mp3");
    string taskCommandLine = String.Format("cmd /c {0}\\ffmpeg-4.3.1-2020-11-08-full_build\\bin\\ffmpeg.exe -i {1} {2}", appPath, inputMediaFile, outputMediaFile);

    // Create a batch task (with the task ID and command line) and add it to the task list

    BatchTaskCreateContent batchTaskCreateContent = new BatchTaskCreateContent(taskId, taskCommandLine);
    batchTaskCreateContent.ResourceFiles.Add(inputFiles[i]);

    // Task output file will be uploaded to the output container in Storage.
    // TODO: Replace <storage-account-name> with your actual storage account name
    OutputFileBlobContainerDestination outputContainer = new OutputFileBlobContainerDestination("https://<storage-account-name>.blob.core.windows.net/output/" + outputMediaFile)
    {
        IdentityReference = inputFiles[i].IdentityReference,
    };

    OutputFile outputFile = new OutputFile(outputMediaFile,
                                           new OutputFileDestination() { Container = outputContainer },
                                           new OutputFileUploadConfig(OutputFileUploadCondition.TaskSuccess));
    batchTaskCreateContent.OutputFiles.Add(outputFile);

    tasks.Add(batchTaskCreateContent);
}

// Call BatchClient.CreateTaskCollectionAsync() to add the tasks as a collection rather than making a
// separate call for each. Bulk task submission helps to ensure efficient underlying API
// calls to the Batch service. 

await batchClient.CreateTaskCollectionAsync(jobId, new BatchTaskGroup(tasks));

Rensa resurser

Efter att den har kört uppgifterna, tar appen automatiskt bort den lagringsbehållare för indatan som den skapade och ger dig möjligheten att ta bort Batch-poolen och jobbet. BatchClient har en metod för att ta bort ett jobb DeleteJobAsync och ta bort en pool DeletePoolAsync, som anropas om du bekräftar borttagning. Även om du inte debiteras för jobben och uppgifterna i sig, debiteras du för beräkningsnoder. Vi rekommenderar därför att du endast tilldelar pooler vid behov. När du tar bort poolen, raderas all uppgiftsutdata på noderna. Utdatafilerna finns dock kvar i lagringskontot.

När de inte längre behövs, ta bort resursgruppen, Batch-kontot och lagringskontot. För att göra detta i Azure-portalen, välj resursgruppen för Batch-kontot och klicka på Ta bort resursgrupp.

Nästa steg

I denna handledning lärde du dig hur du:

  • Lägg till ett applikationspaket i ditt Batch-konto.
  • Autentisera med Batch- och lagringskonton.
  • Ladda upp indatafiler till Storage.
  • Skapa en pool av beräkningsnoder för att köra en applikation.
  • Skapa ett jobb och uppgifter för att bearbeta inmatningsfiler.
  • Övervaka uppgiftsutförande.
  • Hämta utdatafiler.

För fler exempel på hur du använder .NET API för att schemalägga och bearbeta Batch-arbetsbelastningar, se Batch C#-exemplen på GitHub.