Samouczek: uruchamianie równoległego obciążenia w usłudze Azure Batch przy użyciu interfejsu API .NET

Usługa Azure Batch umożliwia wydajne uruchamianie równoległych zadań wsadowych oraz zadań wsadowych obliczeń o wysokiej wydajności na platformie Azure. W tym samouczku przedstawiono przykład uruchamiania równoległego obciążenia za pomocą usługi Azure Batch i języka C#. Poznasz prosty przepływ pracy aplikacji usługi Azure Batch i sposób pracy programowej z zasobami usług Azure Batch i Storage.

  • Dodaj pakiet aplikacji do konta usługi Batch.
  • Uwierzytelnianie przy użyciu kont usługi Batch i usługi Storage.
  • Przekazywanie plików wejściowych do usługi Storage.
  • Utwórz pulę węzłów obliczeniowych, aby uruchomić aplikację.
  • Utwórz zadanie i zadania przetwarzania plików wejściowych.
  • Monitorowanie wykonywania zadań.
  • Pobieranie plików wyjściowych.

W tym samouczku przekonwertujesz pliki multimedialne MP4 na format MP3, równolegle przy użyciu narzędzia open source ffmpeg .

Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto platformy Azure.

Wymagania wstępne

Logowanie się do platformy Azure

Zaloguj się w witrynie Azure Portal.

Dodawanie pakietu aplikacji

W witrynie Azure Portal dodaj narzędzie ffmpeg jako pakiet aplikacji do konta usługi Batch. Pakiety aplikacji ułatwiają zarządzanie aplikacjami zadań i wdrażanie ich w węzłach obliczeniowych w puli.

  1. W witrynie Azure Portal kliknij pozycję Więcej usług>Usługi Batch i wybierz nazwę konta usługi Batch.

  2. Kliknij pozycję Aplikacje>Dodaj.

    Screenshot of the Applications section of the batch account.

  3. Wprowadź wartość ffmpeg w polu Identyfikator aplikacji i wersję pakietu 4.3.1 w polu Wersja. Wybierz pobrany plik zip ffmpeg, a następnie wybierz pozycję Prześlij. Pakiet aplikacji z narzędziem ffmpeg zostanie dodany do konta usługi Batch.

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

Uzyskiwanie poświadczeń konta

W tym przykładzie należy podać poświadczenia dla kont usług Batch i Storage. Najprościej jest uzyskać wymagane poświadczenia w witrynie Azure Portal. (Te poświadczenia możesz również uzyskać za pomocą interfejsów API platformy Azure lub narzędzi wiersza polecenia).

  1. Wybierz pozycję Wszystkie konta usługi>Batch, a następnie wybierz nazwę konta usługi Batch.

  2. Aby wyświetlić poświadczenia usługi Batch, wybierz pozycję Klucze. Skopiuj wartości z pól Konto usługi Batch, Adres URL i Podstawowy klucz dostępu do edytora tekstów.

  3. Aby wyświetlić nazwę i klucze konta magazynu, wybierz pozycję Konto magazynu. Skopiuj wartości z pól Nazwa konta usługi Storage i Klucz1 do edytora tekstów.

Pobieranie i uruchamianie przykładowej aplikacji

Pobieranie przykładowej aplikacji

Pobierz lub sklonuj przykładową aplikację z usługi GitHub. Aby sklonować repozytorium przykładowej aplikacji za pomocą klienta Git, użyj następującego polecenia:

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

Przejdź do katalogu zawierającego plik rozwiązania programu Visual Studio BatchDotNetFfmpegTutorial.sln.

Otwórz plik rozwiązania w programie Visual Studio i zaktualizuj ciągi poświadczeń w pliku Program.cs przy użyciu wartości uzyskanych dla kont. Na przykład:

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

Uwaga

Aby uprościć ten przykład, poświadczenia konta usług Batch i Storage są wyświetlane w postaci zwykłego tekstu. W praktyce zalecamy ograniczenie dostępu do poświadczeń i odwoływanie się do nich w kodzie przy użyciu zmiennych środowiskowych lub pliku konfiguracji. Przykłady można znaleźć w repozytorium przykładów kodu usługi Azure Batch.

Upewnij się również, że odwołanie do pakietu aplikacji ffmpeg w rozwiązaniu jest zgodne z identyfikatorem i wersją pakietu ffmpeg przekazanego do konta usługi Batch. Przykład: ffmpeg i 4.3.1.

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

Kompilowanie i uruchamianie przykładowego projektu

Skompiluj i uruchom aplikację w programie Visual Studio lub w wierszu polecenia, używając poleceń dotnet build i dotnet run. Po uruchomieniu aplikacji przejrzyj kod, aby poznać działanie poszczególnych części aplikacji. Na przykład w programie Visual Studio:

  1. Kliknij prawym przyciskiem myszy rozwiązanie w Eksplorator rozwiązań i wybierz pozycję Kompiluj rozwiązanie.

  2. Jeśli zostanie wyświetlony monit, potwierdź przywrócenie pakietów NuGet. Jeśli musisz pobrać brakujące pakiety, upewnij się, że zainstalowano menedżera pakietów NuGet.

  3. Uruchom rozwiązanie. Po uruchomieniu aplikacji przykładowej dane wyjściowe w konsoli będą wyglądać mniej więcej następująco. W czasie wykonywania nastąpi wstrzymanie operacji w momencie wyświetlenia komunikatu Monitoring all tasks for 'Completed' state, timeout in 00:30:00... podczas uruchamiania węzłów obliczeniowych puli.

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

Przejdź do konta usługi Batch w witrynie Azure Portal, aby monitorować pulę, węzły obliczeniowe, zadanie i zadania podrzędne. Na przykład aby wyświetlić mapę cieplną węzłów obliczeniowych w puli, kliknij pozycję Pule>WinFFmpegPool.

Podczas wykonywania zadań podrzędnych mapa cieplna może wyglądać następująco:

Screenshot of the pool heat map in the Azure portal.

Typowy czas wykonywania wynosi mniej więcej 10 minut w przypadku uruchomienia aplikacji w konfiguracji domyślnej. Tworzenie puli zajmuje najwięcej czasu.

Pobieranie plików wyjściowych

Przy użyciu witryny Azure Portal można pobrać wyjściowe pliki MP3 wygenerowane przez zadania ffmpeg.

  1. Kliknij pozycję Wszystkie usługi>Konta usługi Storage i kliknij nazwę odpowiedniego konta usługi Storage.
  2. Kliknij pozycję Obiekty Blob>dane wyjściowe.
  3. Kliknij prawym przyciskiem myszy jeden z wyjściowych plików MP3, a następnie kliknij polecenie Pobierz. Postępuj zgodnie z monitami wyświetlanymi w przeglądarce, aby otworzyć lub zapisać plik.

Download output file

Mimo że nie pokazano tego w tym przykładzie, pliki można również pobrać programowo z węzłów obliczeniowych lub z kontenera magazynu.

Przeglądanie kodu

W poniższych sekcjach przykładowa aplikacja została podzielona na kroki wykonywane w celu przetworzenia obciążenia w usłudze Batch. Zapoznaj się z plikiem Program.cs w rozwiązaniu podczas czytania pozostałej części tego artykułu, ponieważ nie omówiono każdego wiersza kodu w przykładzie.

Uwierzytelnianie klientów obiektów blob i usługi Batch

Podczas interakcji z połączonym kontem magazynu aplikacja używa biblioteki klienta usługi Azure Storage dla środowiska .NET. Tworzy odwołanie do konta przy użyciu obiektu CloudStorageAccount, korzystając z uwierzytelniania za pomocą klucza współużytkowanego. Następnie tworzy obiekt 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();

Aplikacja tworzy obiekt BatchClient w celu tworzenia pul, zadań i zadań podrzędnych w usłudze Batch i zarządzania nimi. Klient usługi Batch w przykładzie korzysta z uwierzytelniania za pomocą klucza wspólnego. Usługa Batch obsługuje również uwierzytelnianie za pośrednictwem identyfikatora Entra firmy Microsoft w celu uwierzytelniania poszczególnych użytkowników lub aplikacji nienadzorowanej.

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

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

Przekazywanie plików wejściowych

Aplikacja przekazuje obiekt blobClient do metody CreateContainerIfNotExistAsync w celu utworzenia kontenera magazynu dla plików wejściowych (w formacie MP4) oraz kontenera dla danych wyjściowych zadania podrzędnego.

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

Następnie pliki są przekazywane do kontenera wejściowego z lokalnego folderu InputFiles . Pliki w magazynie są definiowane jako obiekty ResourceFile usługi Batch, które następnie mogą być pobierane przez tę usługę do węzłów obliczeniowych.

Dwie metody w pliku Program.cs są związane z przekazywaniem plików:

  • UploadFilesToContainerAsync: zwraca kolekcję ResourceFile obiektów i wewnętrznie wywołuje UploadResourceFileToContainerAsync metodę przekazywania każdego pliku przekazanego w parametrze inputFilePaths .
  • UploadResourceFileToContainerAsync: przekazuje poszczególne pliki jako obiekty blob do kontenera wejściowego. Po przekazaniu pliku uzyskuje sygnaturę dostępu współdzielonego (SAS) dla obiektu blob i zwraca ResourceFile obiekt, który ma go reprezentować.
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);

Szczegółowe informacje na temat przekazywania plików jako obiektów blob na konto magazynu przy użyciu środowiska .NET zawiera artykuł Szybki start: przekazywanie, pobieranie i wyświetlanie listy obiektów blob za pomocą platformy .NET.

Tworzenie puli węzłów obliczeniowych

Następnie w przykładzie tworzona jest pula węzłów obliczeniowych na koncie usługi Batch z wywołaniem funkcji CreatePoolIfNotExistAsync. Ta zdefiniowana metoda używa metody BatchClient.PoolOperations.CreatePool w celu ustawienia liczby węzłów, rozmiaru maszyny wirtualnej i konfiguracji puli. W tym przypadku obiekt VirtualMachineConfiguration określa parametr ImageReference z odwołaniem do obrazu systemu Windows Server opublikowanego w witrynie Azure Marketplace. Usługa Batch obsługuje szeroki zakres obrazów maszyn wirtualnych z witryny Azure Marketplace oraz niestandardowe obrazy maszyn wirtualnych.

Liczba węzłów i rozmiar maszyny wirtualnej są ustawiane przy użyciu zdefiniowanych stałych. Usługa Batch obsługuje dedykowane węzły i węzły typu spot, a w pulach można używać obu tych węzłów. Węzły dedykowane są zarezerwowane dla Twojej puli. Węzły typu spot są oferowane w obniżonej cenie od nadwyżkowej pojemności maszyny wirtualnej na platformie Azure. Węzły typu spot stają się niedostępne, jeśli platforma Azure nie ma wystarczającej pojemności. Przykład domyślnie tworzy pulę zawierającą tylko 5 węzłów typu spot o rozmiarze Standard_A1_v2.

Uwaga

Upewnij się, że sprawdzasz przydziały węzłów. Aby uzyskać instrukcje dotyczące tworzenia żądania przydziału przydziału, zobacz Limity i limity usługi Batch.

Aplikacja ffmpeg jest wdrażana w węzłach obliczeniowych przez dodanie parametru ApplicationPackageReference do konfiguracji puli.

Metoda CommitAsync przesyła pulę do usługi Batch.

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

Tworzenie zadania

Zadanie usługi Batch określa pulę, w której będą uruchamiane zadania podrzędne, wraz z ustawieniami opcjonalnymi, takimi jak priorytet i harmonogram pracy. Przykładowa aplikacja tworzy zadanie z wywołaniem CreateJobAsync. W tej zdefiniowanej metodzie zadanie jest tworzone w puli za pomocą metody BatchClient.JobOperations.CreateJob.

Metoda CommitAsync przesyła zadanie do usługi Batch. Początkowo zadanie nie zawiera zadań podrzędnych.

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

await job.CommitAsync();

Tworzenie zadań

Przykładowa aplikacja tworzy zadania podrzędne w ramach zadania, wywołując metodę AddTasksAsync, co powoduje utworzenie listy obiektów CloudTask. Każdy obiekt CloudTask uruchamia narzędzie ffmpeg w celu przetworzenia wejściowego obiektu ResourceFile za pomocą właściwości CommandLine. Narzędzie ffmpeg zostało już zainstalowane na wszystkich węzłach podczas tworzenia puli. Tutaj wiersz polecenia jest używany do uruchomienia narzędzia ffmpeg w celu przekonwertowania każdego z plików wejściowych w formacie MP4 (wideo) na format MP3 (audio).

Przykładowa aplikacja tworzy obiekt OutputFile dla pliku MP3 po uruchomieniu wiersza polecenia. Pliki wyjściowe z każdego zadania podrzędnego (w tym przypadku jeden plik) są przekazywane do kontenera na połączonym koncie magazynu przy użyciu właściwości OutputFiles w zadaniu podrzędnym. Wcześniej w przykładowym kodzie uzyskano adres URL sygnatury dostępu współdzielonego (outputContainerSasUrl) w celu zapewnienia dostępu do zapisu do kontenera wyjściowego. Zwróć uwagę na warunki ustawione dla obiektu outputFile. Plik wyjściowy z zadania jest przekazywany do kontenera tylko po pomyślnym zakończeniu zadania (OutputFileUploadCondition.TaskSuccess). Zobacz cały przykładowy kod w witrynie GitHub, aby uzyskać więcej informacji o szczegółach implementacji.

Następnie przykładowa aplikacja dodaje zadania podrzędne do zadania za pomocą metody AddTaskAsync, która tworzy kolejkę zadań podrzędnych do uruchomienia w węzłach obliczeniowych.

Zastąp ścieżkę pliku pliku wykonywalnego nazwą pobranej wersji. W tym przykładowym kodzie użyto przykładu 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

Monitorowanie podzadań

Po dodaniu zadań podrzędnych do zadania usługa Batch automatycznie tworzy kolejkę zadań podrzędnych i planuje ich wykonanie w węzłach obliczeniowych powiązanej puli. Na podstawie określonych przez użytkownika ustawień usługa Batch obsługuje dodawanie zadań podrzędnych do kolejki, ich planowanie, ponawianie prób ich wykonania oraz inne czynności administracyjne.

Istnieje wiele podejść do wykonywania monitorowania podzadań. Ta przykładowa aplikacja definiuje metodę MonitorTasks, umożliwiającą tylko raportowanie zakończenia zadań podrzędnych oraz ich powodzenia lub niepowodzenia. Kod metody MonitorTasks określa parametr ODATADetailLevel, aby efektywnie wybrać tylko minimum informacji o zadaniach podrzędnych. Następnie tworzy funkcję TaskStateMonitor, która udostępnia narzędzia do monitorowania stanu zadań podrzędnych. W przypadku metody MonitorTasks przykładowa aplikacja czeka, aż wszystkie zadania podrzędne osiągną stan TaskState.Completed w określonym czasie. Następnie kończy zadanie i zgłasza wszystkie zadania podrzędne, które zostały ukończone, ale w przypadku których mógł wystąpić błąd, na przykład niezerowy kod zakończenia.

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

Czyszczenie zasobów

Po wykonaniu zadań podrzędnych aplikacja automatycznie usuwa utworzony wejściowy kontener magazynu, a opcjonalnie także pulę i zadanie usługi Batch. Dla obu klas JobOperations i PoolOperations klienta BatchClient istnieją odpowiednie metody usuwania, które są wywoływane, jeśli potwierdzisz usunięcie. Mimo że nie są naliczane opłaty za same zadania i zadania podrzędne, są naliczane opłaty za węzły obliczeniowe. W związku z tym zaleca się przydzielanie pul stosownie do potrzeb. W przypadku usunięcia puli usuwane są również wszystkie dane wyjściowe zadań podrzędnych w węzłach. Pliki wyjściowe pozostają jednak na koncie magazynu.

Gdy grupa zasobów, konto usługi Batch i konto magazynu nie będą już potrzebne, usuń je. W tym celu w witrynie Azure Portal zaznacz grupę zasobów konta usługi Batch i kliknij pozycję Usuń grupę zasobów.

Następne kroki

W tym samouczku zawarto informacje na temat wykonywania następujących czynności:

  • Dodaj pakiet aplikacji do konta usługi Batch.
  • Uwierzytelnianie przy użyciu kont usługi Batch i usługi Storage.
  • Przekazywanie plików wejściowych do usługi Storage.
  • Utwórz pulę węzłów obliczeniowych, aby uruchomić aplikację.
  • Utwórz zadanie i zadania przetwarzania plików wejściowych.
  • Monitorowanie wykonywania zadań.
  • Pobieranie plików wyjściowych.

Aby uzyskać więcej przykładów użycia interfejsu API platformy .NET do planowania i przetwarzania obciążeń usługi Batch, zobacz przykłady języka C# usługi Batch w witrynie GitHub.