Руководство. Запуск параллельной рабочей нагрузки с помощью пакета Azure с использованием .NET API

Используйте пакетную службу Azure, чтобы эффективно выполнять пакетные задания для крупномасштабных параллельных и высокопроизводительных вычислений (HPC). В этом руководстве рассматривается пример C# для запуска параллельной рабочей нагрузки с помощью пакетной службы Azure. Вы изучите общий рабочий процесс приложения пакетной службы и узнаете, как программно взаимодействовать с ресурсами пакетной службы и службы хранилища.

  • Добавьте пакет приложения в учетную запись пакетной службы.
  • Проверка подлинности с помощью учетных записей пакетной службы и служба хранилища.
  • Отправьте входные файлы в служба хранилища.
  • Создайте пул вычислительных узлов для запуска приложения.
  • Создайте задание и задачи для обработки входных файлов.
  • Мониторинг выполнения задач.
  • Получение выходных файлов.

В этом руководстве вы преобразуете файлы мультимедиа MP4 в формат MP3 параллельно с помощью средства ffmpeg с открытым исходным кодом.

Если у вас еще нет подписки Azure, создайте бесплатную учетную запись Azure, прежде чем начинать работу.

Необходимые компоненты

  • Visual Studio 2017 или более поздней версии или пакет SDK для .NET Core для Linux, macOS или Windows.

  • учетная запись пакетной службы и связанная учетная запись службы хранилища Azure. Чтобы создать эти учетные записи, ознакомьтесь с краткими руководствами по пакетной службе для портал Azure или Azure CLI.

  • Скачайте соответствующую версию ffmpeg для варианта использования на локальный компьютер. В этом руководстве и соответствующем примере приложения используется полная сборка Windows 64-разрядная версия ffmpeg 4.3.1. Для этого руководства вам нужен только ZIP-файл. Вам не нужно распаковывать или локально устанавливать файл.

Вход в Azure

Войдите на портал Azure.

Добавление пакета приложения

Добавьте ffmpeg в учетную запись пакетной службы в качестве пакета приложений с помощью портала Azure. Пакеты приложений упрощают управление приложениями задач и их развертывание на вычислительных узлах в пуле.

  1. В портал Azure щелкните "Другие учетные>записи пакетной службы" и выберите имя учетной записи пакетной службы.

  2. Выберите Приложения>Добавить.

    Screenshot of the Applications section of the batch account.

  3. Введите ffmpeg в поле "Идентификатор приложения" и пакет версии 4.3.1 в поле "Версия ". Выберите скачанный ZIP-файл ffmpeg и нажмите кнопку "Отправить". Пакет приложений ffmpeg добавляется в учетную запись пакетной службы.

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

Получение учетных данных учетной записи

В этом примере нужно предоставить учетные данные для доступа к учетной записи службы хранилища и пакетной службы. Проще всего получить необходимые учетные данные на портале Azure. (Можно также получить эти учетные данные с помощью API-интерфейсов Azure или средств командной строки.)

  1. Выберите Все службы>Учетные записи пакетной службы и щелкните имя учетной записи пакетной службы.

  2. Для просмотра учетных данных пакетной службы нажмите Ключи. Скопируйте значения учетной записи пакетной службы, URL-адреса, и первичного ключа доступа в текстовый редактор.

  3. Чтобы просмотреть имя и ключи учетной записи хранения, выберите Учетная запись хранения. Скопируйте значения имени учетной записи службы хранилища и Key1 в текстовый редактор.

Загрузка и запуск примера приложения

загрузка примера приложения;

Скачайте или клонируйте пример приложения с GitHub. Чтобы клонировать пример репозитория приложения с клиентом Git, выполните следующую команду:

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

Перейдите в каталог, содержащий файл решения Visual Studio BatchDotNetFfmpegTutorial.sln.

Откройте файл решения в Visual Studio и обновите строки учетных данных в Program.cs со значениями, полученными для учетных записей. Например:

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

Примечание.

Для упрощения примера учетные данные пакетной службы и службы хранения указаны в виде текста. На практике мы рекомендуем ограничить доступ к учетным данным и ссылаться на них в коде, используя переменные среды или файл конфигурации. См. репозиторий с примерами кода для пакетной службы Azure.

Кроме того, убедитесь, что ссылка на пакет приложения ffmpeg в решении совпадает с идентификатором и версией пакета ffmpeg, который вы отправили в свою учетную запись. Например, ffmpeg и 4.3.1.

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

Создание и запуск примера проекта

Создавайте и запускайте приложения в Visual Studio или с помощью команд dotnet build и dotnet run в командной строке. После запуска приложения просмотрите код, чтобы узнать, как работает каждый компонент приложения. Visual Studio:

  1. В обозревателе решений щелкните решение правой кнопкой мыши и выберите пункт Собрать решение.

  2. Подтвердите восстановление пакетов NuGet, если появится соответствующий запрос. Если вам необходимо скачать отсутствующие пакеты, установите диспетчер пакетов NuGet.

  3. Запустите решение. Когда вы запустите пример приложения, консоль будет выглядеть так. Во время выполнения может возникнуть пауза на этапе Monitoring all tasks for 'Completed' state, timeout in 00:30:00..., когда будут запускаться вычислительные узлы пула.

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

Перейдите в учетную запись пакетной службы на портале Azure, чтобы отследить пул, вычислительные узлы, задания и задачи. Например, чтобы увидеть тепловую карту вычислительных узлов в вашем пуле, выберите Пулы>WinFFmpegPool.

Во время выполнения задач тепловая карта выглядит следующим образом:

Screenshot of the pool heat map in the Azure portal.

Обычное время выполнения — примерно 10 минут, если для приложения задана конфигурация по умолчанию. Для создания пула потребуется больше всего времени.

Извлечение выходных файлов

Портал Azure можно использовать для скачивания выходных MP3-файлов, созданных задачами ffmpeg.

  1. Выберите Все службы>Учетные записи службы хранилища и щелкните имя учетной записи службы хранилища.
  2. Щелкните Большие двоичные объекты>Вывод.
  3. Щелкните правой кнопкой мыши один из выходных MP3-файлов и нажмите кнопку Загрузить. Следуйте инструкциям в браузере, чтобы открыть или сохранить этот файл.

Download output file

Хотя это не показано в этом примере, файлы можно также скачать программным способом из вычислительных узлов или контейнера хранилищ.

Просмотр кода

В следующих разделах мы разобьем пример приложения на действия, выполняемые для обработки рабочей нагрузки в пакетной службе. Обратитесь к файлу Program.cs в решении при чтении остальной части этой статьи, так как в образце рассматривается не каждая строка кода.

Проверка подлинности клиентов больших двоичных объектов и пакетной службы

Чтобы взаимодействовать со связанной учетной записью хранения, приложение использует клиентскую библиотеку службы хранилища для .NET. Оно создает ссылку на учетную запись с CloudStorageAccount, выполняя проверку подлинности с помощью общего ключа. Затем оно создает 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();

Приложение создает объект BatchClient для создания пулов, заданий и задач в пакетной службе, а также для управления ими. В примере клиент пакетной службы использует проверку подлинности с общим ключом. Пакетная служба также поддерживает проверку подлинности с помощью идентификатора Microsoft Entra для проверки подлинности отдельных пользователей или автоматического приложения.

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

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

Передача входных файлов

Приложение передает объект blobClient методу CreateContainerIfNotExistAsync, чтобы создать контейнер для хранения входных файлов (формат MP4) и контейнер для выходных данных задач.

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

Затем файлы отправляются в входной контейнер из локальной папки InputFiles . Файлы в хранилище определяются как объекты пакетной службы ResourceFile, которые она может впоследствии скачать на вычислительные узлы.

Два метода в Program.cs участвуют в отправке файлов:

  • UploadFilesToContainerAsync: возвращает коллекцию объектов и внутренние вызовы UploadResourceFileToContainerAsync для отправки ResourceFile каждого файла, передаваемого в параметреinputFilePaths.
  • UploadResourceFileToContainerAsync. Загружает каждый файл в качестве большого двоичного объекта в контейнер входных данных. После отправки файла он получает подписанный URL-адрес (SAS) для большого двоичного объекта и возвращает ResourceFile объект для представления.
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);

Подробнее о загрузке файлов в качестве больших двоичных объектов в учетную запись хранения с .NET см. в статье об отправке, скачивании и перечислении больших двоичных объектов с помощью .NET.

Создание пула вычислительных узлов

Затем в учетной записи пакетной службы создается пул вычислительных узлов с помощью вызова CreatePoolIfNotExistAsync. С помощью метода BatchClient.PoolOperations.CreatePool можно настроить количество узлов, размер виртуальной машины и конфигурацию пула. Объект VirtualMachineConfiguration указывает ImageReference в образе Windows Server, опубликованном в Azure Marketplace. Пакетная служба Azure поддерживает широкий спектр образов виртуальной машины в Azure Marketplace, а также пользовательских образов виртуальной машины.

Количество узлов и размер виртуальной машины настраиваются с помощью определенных констант. Пакетная служба Azure поддерживает выделенные узлы и точечные узлы. Вы можете использовать их в своих пулах. Выделенные узлы зарезервированы для пула. Точечные узлы предлагаются по сниженной цене с учетом избыточных ресурсов виртуальной машины в Azure. Эти узлы становятся недоступны, если в Azure недостаточно ресурсов. Пример по умолчанию создает пул, содержащий только 5 точечных узлов размером Standard_A1_v2.

Примечание.

Проверьте квоты узла. Инструкции по созданию запроса на квоту в пакетной службе см . в разделе "Квоты пакетной службы" и ограничения .

Приложение ffmpeg развертывается на вычислительных узлах, добавляя ApplicationPackageReference к конфигурации пула.

Метод CommitAsync отправляет пул в пакетную службу.

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

Создание задания

Пакетное задание указывает пул для запуска задач и дополнительные параметры, такие как приоритет и расписание работы. Пример создает задание путем вызова CreateJobAsync. С помощью метода BatchClient.JobOperations.CreateJob можно создать задание в пуле.

Метод CommitAsync отправляет задание в пакетную службу. Изначально у задания нет задач.

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

await job.CommitAsync();

Создание задач

Пример создает задачи в задании путем вызова метода AddTasksAsync, который создает список объектов CloudTask. Каждый CloudTask запускает ffmpeg для обработки объекта входных данных ResourceFile с помощью свойства CommandLine. ffmpeg был ранее установлен на каждом узле при создании пула. В командной строке выполняется ffmpeg для преобразования каждого входного файла MP4 (видео) в файл MP3 (аудио).

В примере создается объект OutputFile для файла MP3 после запуска командной строки. Выходные файлы каждой задачи (в этом случае один) передаются в контейнер в связанной учетной записи с помощью свойства задачи OutputFiles. Ранее в примере кода был получен подписанный URL-адрес (outputContainerSasUrl), чтобы предоставить доступ на запись к выходному контейнеру. Обратите внимание на набор условий в объекте outputFile. Выходной файл из задачи передается в контейнер только после успешного завершения задачи (OutputFileUploadCondition.TaskSuccess). Ознакомьтесь с полным примером кода на сайте GitHub для получения дальнейших сведений о реализации.

Затем в примере к заданию добавляются задачи с помощью метода AddTaskAsync, который ставит их в очередь для запуска на вычислительных узлах.

Замените путь к исполняемому файлу именем загруженной версии. В этом коде используется пример 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

Мониторинг задач

Когда пакетная служба добавляет задачи к заданию, служба автоматически ставит в очередь и назначает их для выполнения на вычислительных узлах в связанном пуле. Пакетная служба обрабатывает постановку задач в очередь, их планирование, повтор и другие задачи администрирования с учетом указанных параметров.

Есть несколько подходов к отслеживанию выполнения задач. Этот пример определяет метод MonitorTasks для отчета о завершении и состоянии задачи (успешного выполнения или сбоя). Код MonitorTasks указывает ODATADetailLevel, чтобы эффективно выбирать только минимум сведений о задачах. Затем он создает TaskStateMonitor , который предоставляет вспомогательные утилиты для мониторинга состояний задач. В MonitorTasks пример ждет, пока все задачи не перейдут в состояние TaskState.Completed в течение определенного времени. Затем он завершает работу задания и сообщает о любых выполненных задачах. Однако он может обнаружить сбой, например с ненулевым кодом выхода.

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

Очистка ресурсов

После выполнения задач приложение автоматически удаляет созданный входной контейнер хранилища, а также предоставляет возможность удалить пул и задания пакетной службы. Классы JobOperations и PoolOperations BatchClient предусматривают соответствующие методы удаления, которые вызываются, если подтвердить удаление. Вы не оплачиваете задания и задачи, но платите за используемые вычислительные узлы. Поэтому рекомендуется выделять пулы только при необходимости. При удалении пула удаляются все выходные данные задачи на узлах. Но выходные файлы сохраняются в учетной записи хранения.

Ставшие ненужными группу ресурсов, учетную запись пакетной службы и учетную запись хранения можно удалить. Для этого на портале Azure выберите группу ресурсов для учетной записи пакетной службы и щелкните Удалить группу ресурсов.

Следующие шаги

Из этого руководства вы узнали, как:

  • Добавьте пакет приложения в учетную запись пакетной службы.
  • Проверка подлинности с помощью учетных записей пакетной службы и служба хранилища.
  • Отправьте входные файлы в служба хранилища.
  • Создайте пул вычислительных узлов для запуска приложения.
  • Создайте задание и задачи для обработки входных файлов.
  • Мониторинг выполнения задач.
  • Получение выходных файлов.

Дополнительные примеры использования API .NET для планирования и обработки рабочих нагрузок пакетной службы см. в примерах пакетной службы C# на GitHub.