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

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

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

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

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

Предварительные требования

Вход в Azure

Войдите на портал Azure по адресу https://portal.azure.com.

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

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

  1. На портале Azure выберите Дополнительные службы > Учетные записи пакетной службы и щелкните имя учетной записи пакетной службы.
  2. Выберите Приложения > Добавить.
  3. В поле Идентификатор приложения введите ffmpeg и версию пакета 4.3.1. Выберите файл zfmpeg zip, который вы загрузили ранее, и нажмите кнопку ОК. Пакет приложений ffmpeg добавляется в учетную запись пакетной службы.

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

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

В этом примере нужно предоставить учетные данные для доступа к учетной записи службы хранилища и пакетной службы. Проще всего получить необходимые учетные данные на портале 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 = "mybatchaccount";
private const string BatchAccountKey  = "xxxxxxxxxxxxxxxxE+yXrRvJAqT9BlXwwo1CwF+SwAYOxxxxxxxxxxxxxxxx43pXi/gdiATkvbpLRl3x14pcEQ==";
private const string BatchAccountUrl  = "https://mybatchaccount.mybatchregion.batch.azure.com";

// Storage account credentials
private const string StorageAccountName = "mystorageaccount";
private const string StorageAccountKey  = "xxxxxxxxxxxxxxxxy4/xxxxxxxxxxxxxxxxfwpbIC5aAWA8wDu+AFXZB827Mt9lybZB1nUcQbQiUrkPtilK5BQ==";

Примечание

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

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

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

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

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

  • Щелкните правой кнопкой мыши решение в обозревателе решений и выберите Build Solution (Сборка решения).

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

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

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

Тепловая карта пула

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

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

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

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

Скачивание выходного файла

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

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

В следующих разделах мы разобьем пример приложения на действия, выполняемые для обработки рабочей нагрузки в пакетной службе. Во время работы с оставшейся частью статьи сверяйтесь с файлом 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 для создания пулов, заданий и задач в пакетной службе, а также для управления ими. В примере клиент пакетной службы использует проверку подлинности с общим ключом. Пакетная служба Azure также поддерживает аутентификацию отдельных пользователей или автоматических приложений с помощью Azure Active Directory.

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: возвращает коллекцию объектов ResourceFile и выполняет внутренний вызов UploadResourceFileToContainerAsync, чтобы отправить каждый файл, переданный в параметре 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, который ставит их в очередь для запуска на вычислительных узлах.

 // 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 выберите группу ресурсов для учетной записи пакетной службы и щелкните Удалить группу ресурсов.

Дальнейшие действия

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

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

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