Partage via


Tutoriel : Exécuter une charge de travail parallèle avec Azure Batch à l’aide de l’API .NET

Utilisez Azure Batch pour exécuter des programmes de traitement par lots de calcul haute performance (HPC) en parallèle, efficacement et à grande échelle dans Azure. Ce didacticiel vous permet de découvrir un exemple d’exécution C# d’une charge de travail parallèle utilisant Batch. Vous découvrez un workflow d’application Batch courant et comment interagir par programme avec les ressources de stockage et Batch.

  • Ajouter un package d’application à votre compte Batch.
  • S’authentifier avec des comptes de stockage et Batch.
  • Charger des fichiers d’entrée sur le stockage.
  • Créer un pool de nœuds de calcul pour exécuter une application.
  • Créer un travail et des tâches pour traiter les fichiers d’entrée.
  • Surveiller l’exécution d’une tâche.
  • Récupérer les fichiers de sortie.

Dans ce tutoriel, vous convertissez des fichiers multimédias MP4 au format MP3, en parallèle, à l’aide de l’outil open source ffmpeg.

Si vous n’avez pas d’abonnement Azure, créez un compte gratuit Azure avant de commencer.

Prérequis

Connexion à Azure

Connectez-vous au portail Azure.

Ajouter un package d’application

Utiliser le portail Azure pour ajouter ffmpeg à votre compte Batch en tant que package d’application. Les packages d’application permettent de gérer les applications de tâche et leur déploiement sur les nœuds de calcul dans votre pool.

  1. Dans le portail Azure, cliquez sur Plus de services>Comptes Batch, puis sélectionnez le nom de votre compte Batch.

  2. Cliquez sur Applications>Ajouter.

    Capture d’écran de la section Applications du compte Batch.

  3. Entrez ffmpeg dans le champ ID d’application et la version de package 4.3.1 dans le champ Version. Sélectionnez le fichier zip ffmpeg que vous avez téléchargé, puis sélectionnez Envoyer. Le package d’application ffmpeg est ajouté à votre compte Batch.

    Capture d’écran des champs d’ID et de version dans la section d’ajout d’une application.

Obtenir les informations d’identification du compte

Dans le cadre de cet exemple, vous devez fournir les informations d’identification de vos comptes Azure Batch et de stockage. Pour obtenir rapidement les informations d’identification nécessaires, dirigez-vous vers le portail Azure. (Vous pouvez aussi les obtenir avec les API Azure ou des outils en ligne de commande.)

  1. Sélectionnez Tous les services>Comptes Batch, puis le nom de votre compte Batch.

  2. Pour voir les informations d’identification Batch, sélectionnez Clés. Copiez les valeurs des champs Compte Batch, URL et Clé d’accès principale dans un éditeur de texte.

  3. Pour voir le nom et les clés du compte de stockage, sélectionnez Compte de stockage. Copiez les valeurs des champs Nom du compte de stockage et Clé1 dans un éditeur de texte.

Télécharger et exécuter l’exemple d’application

Télécharger l’exemple d’application

Téléchargez ou clonez l’exemple d’application à partir de GitHub. Pour cloner le référentiel d’exemple d’application avec un client Git, utilisez la commande suivante :

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

Accédez au répertoire qui contient le fichier de la solution Visual Studio BatchDotNetFfmpegTutorial.sln.

Vérifiez également que la référence du package d’application ffmpeg de la solution correspond à l’identificateur et à la version du package ffmpeg chargée sur votre compte Batch. Par exemple : ffmpeg et 4.3.1.

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

Créer et exécuter l’exemple de projet

Générez et exécutez l’application dans Visual Studio ou sur la ligne de commande avec les commandes dotnet build et dotnet run. Après avoir exécuté l’application, passez en revue le code pour savoir ce que fait chaque partie de l’application. Par exemple, dans Visual Studio :

  1. Cliquez avec le bouton droit sur la solution dans l’Explorateur de solutions, puis sélectionnez Générer la solution.

  2. Si vous y êtes invité, confirmez la restauration de tous les packages NuGet. Si vous devez télécharger des packages manquants, vérifiez que le Gestionnaire de Package NuGet est installé.

  3. Exécutez la solution. Lorsque vous exécutez l’exemple d’application, la sortie de la console est identique à ce qui suit. Pendant l’exécution, l’étape Monitoring all tasks for 'Completed' state, timeout in 00:30:00... fait l’objet d’une pause correspondant au démarrage des nœuds de calcul du pool.

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

Accédez à votre compte Batch dans le portail Azure pour surveiller le pool, les nœuds de calcul, les travaux et les tâches. Par exemple, pour voir une carte thermique des nœuds de calcul de votre pool, cliquez sur Pools>WinFFmpegPool.

Lorsque les tâches sont en cours d’exécution, la carte thermique est similaire à ce qui suit :

Capture d’écran de la carte thermique du pool dans le portail Azure.

Le temps d’exécution standard est d’environ 10 minutes lorsque l’application fonctionne dans sa configuration par défaut. La création d’un pool est l’opération la plus longue.

Récupérer les fichiers de sortie

Vous pouvez utiliser le portail Azure pour télécharger les fichiers de sortie MP3 générés par les tâches ffmpeg.

  1. Cliquez sur Tous les services>Comptes de stockage, puis sur le nom de votre compte de stockage.
  2. Cliquez sur BLOB>sortie.
  3. Cliquez avec le bouton droit sur l’un des fichiers de sortie MP3 puis cliquez sur Télécharger. Suivez les invites dans votre navigateur pour ouvrir ou enregistrer le fichier.

Télécharger le fichier de sortie

Même si ce n’est pas montré dans cet exemple, vous pouvez aussi télécharger les fichiers par programmation depuis les nœuds de calcul ou depuis le conteneur de stockage.

Vérifier le code

Dans les sections suivantes, nous examinons l’exemple d’application en nous servant des opérations qu’elle effectue pour traiter une charge de travail dans le service Batch. Référez-vous au fichier Program.cs dans la solution quand vous lisez le reste de cet article, car certaines lignes de code de cet exemple ne sont pas expliquées ici.

Authentifier les clients Blob et Batch

Pour interagir avec le compte de stockage lié, l’application utilise la bibliothèque Azure.Storage.Blobs pour .NET. Utilisation de la classe BlobServiceClient qui prend une référence à l’URI du compte et authentification du Jeton tel que 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());

L’application crée une référence au BatchAccountResource via l’ArmClient du gestionnaire de ressources pour créer le pool dans le service Batch. Le client Arm dans l’exemple utilise l’authentification DefaultAzureCredential.

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

L’application crée un objet BatchClient pour créer des travaux et des tâches dans le service Batch. Le client Batch dans l’exemple utilise l’authentification DefaultAzureCredential.

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

Charger des fichiers d’entrée

L’application transmet l’objet blobServerClient à la méthode CreateContainerIfNotExistc pour créer un conteneur de stockage pour les fichiers d’entrée (format MP4) et un conteneur pour la sortie de la tâche.

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

Ensuite, les fichiers sont chargés dans le conteneur d’entrée à partir du dossier InputFiles local. Les fichiers de stockage sont définis en tant qu’objets Batch ResourceFile que Batch peut télécharger ultérieurement sur les nœuds de calcul.

Deux méthodes de Program.cs sont impliquées dans le chargement des fichiers :

  • UploadFilesToContainerAsync : retourne une collection d’objets ResourceFile et appelle UploadResourceFileToContainerAsync en interne pour charger chaque fichier transmis dans le paramètre inputFilePaths.
  • UploadResourceFileToContainerAsync: charge chaque fichier en tant qu’objet blob dans le conteneur d’entrée. Après le chargement du fichier, la méthode obtient une signature d’accès partagé (SAP) pour l’objet blob et renvoie un objet ResourceFile pour la représenter.
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);

Pour plus d’informations sur le chargement de fichiers en tant qu’objets blob sur un compte de stockage avec .NET, consultez Upload, download, and list blobs using .NET (Charger, télécharger et répertorier des objets blob à l’aide de .NET).

Créer un pool de nœuds de calcul

Ensuite, l’exemple crée un pool de nœuds de traitement dans le compte Batch, avec un appel à CreatePoolIfNotExistAsync. Cette méthode définie utilise la méthode BatchAccountResource.GetBatchAccountPools().CreateOrUpdateAsync pour définir le nombre de nœuds, la taille de la machine virtuelle et une configuration de pool. Ici, un objet BatchVmConfiguration spécifie une BatchImageReference à une image Windows Server publiée dans la Place de marché Azure. Azure Batch prend en charge une large plage de machine virtuelle dans la Place de marché Microsoft Azure, ainsi que des images de machines virtuelles personnalisées.

Le nombre de nœuds et la taille de machine virtuelle sont définis à l’aide de constantes définies. Azure Batch prend en charge les nœuds dédiés et les nœuds de faible priorité que vous pouvez utiliser dans vos pools. Les nœuds dédiés sont réservés à votre pool. Les nœuds de faible priorité sont proposés à prix réduit à partir de la capacité de machine virtuelle excédentaire dans Azure. Les nœuds de faible priorité deviennent indisponibles si la capacité d’Azure est insuffisante. L’exemple par défaut crée un pool contenant seulement 5 nœuds de faible priorité taille Standard_A1_v2.

Notes

Veillez à vérifier vos quotas de nœud. Consultez l’article Quotas et limites du service Batch pour obtenir des instructions sur la création d’une demande de quota.

L’application ffmpeg est déployée sur les nœuds de calcul en ajoutant un ApplicationPackageReference à la configuration du pool.

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(appPacakgeResourceID))
                    {
                        Version = appPackageVersion,
                    }
            },

        });
    BatchAccountPoolResource pool = armOperation.Value;

Créer un travail

Un programme de traitement par lots spécifie un pool pour exécuter des tâches et des paramètres facultatifs tels qu’une priorité et un calendrier pour le travail. L’exemple crée un travail avec un appel à CreateJobAsync. Cette méthode définie utilise la méthode BatchClient.CreateJobAsync pour créer un travail sur votre pool.

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

Créer des tâches

L’exemple crée des tâches dans le travail avec un appel à la méthode AddTasksAsync, ce qui crée une liste d’objets BatchTask. Chaque BatchTask exécute ffmpeg pour traiter un objet ResourceFile d’entrée à l’aide de la propriété CommandLine. ffmpeg a été précédemment installé sur chaque nœud lors de la création du pool. Ici, la ligne de commande exécute ffmpeg pour convertir chaque fichier (vidéo) MP4 en fichier MP3 (audio).

L’exemple crée un objet OutputFile pour le fichier MP3 après l’exécution de la ligne de commande. Les fichiers de sortie de chaque tâche (un, dans ce cas) sont chargés sur un conteneur dans le compte de stockage lié, à l’aide de la propriété OutputFiles. Notez les conditions définies sur l’objet outputFile. Un fichier de sortie d’une tâche est chargé sur le conteneur seulement une fois la tâche terminée avec succès (OutputFileUploadCondition.TaskSuccess). Pour plus de détails sur l’implémentation, consultez l’exemple de code complet sur GitHub.

Ensuite, l’exemple ajoute des tâches au travail avec la méthode CreateTaskAsync, qui les met en file d’attente afin de les exécuter sur les nœuds de calcul.

Remplacez le chemin d’accès du fichier exécutable par le nom de la version que vous avez téléchargée. Cet exemple de code utilise l’exemple 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));

Nettoyer les ressources

Après avoir exécuté les tâches, l’application supprime automatiquement le conteneur de stockage d’entrée créé et vous donne la possibilité de supprimer le travail et le pool Azure Batch. BatchClient a une méthode pour supprimer un travail DeleteJobAsync et supprimer un pool DeletePoolAsync, qui sont appelés si vous confirmez la suppression. Bien que vous ne soyez pas facturé pour les travaux et les tâches à proprement parler, les nœuds de calcul vous sont facturés. Par conséquent, nous vous conseillons d’affecter les pools uniquement en fonction des besoins. Lorsque vous supprimez le pool, toutes les sorties de tâche sur les nœuds sont supprimées. Toutefois, les fichiers de sortie restent dans le compte de stockage.

Lorsque vous n’en avez plus besoin, supprimez le groupe de ressources, le compte Batch et le compte de stockage. Pour ce faire, dans le portail Azure, sélectionnez le groupe de ressources pour le compte Batch, puis cliquez sur Supprimer le groupe de ressources.

Étapes suivantes

Dans ce didacticiel, vous avez appris à :

  • Ajouter un package d’application à votre compte Batch.
  • S’authentifier avec des comptes de stockage et Batch.
  • Charger des fichiers d’entrée sur le stockage.
  • Créer un pool de nœuds de calcul pour exécuter une application.
  • Créer un travail et des tâches pour traiter les fichiers d’entrée.
  • Surveiller l’exécution d’une tâche.
  • Récupérer les fichiers de sortie.

Pour plus d’exemples d’utilisation de l’API .NET pour planifier et traiter les charges de travail Batch, consultez les exemples C# Batch sur GitHub.