Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Задачи с несколькими экземплярами позволяют одновременно выполнять задачу пакетная служба Azure на нескольких вычислительных узлах. Эти задачи поддерживают сценарии высокопроизводительных вычислений, такие как приложения с использованием интерфейса передачи сообщений (MPI) в Batch. В этой статье вы узнаете, как выполнять многоэкземплярные задачи с помощью библиотеки Azure.Compute.Batch.
Примечание.
Хотя в этой статье рассматриваются примеры, связанные с Azure.Compute.Batch, MS-MPI и вычислительными узлами Windows, описанные здесь концепции многоэкземплярных задач применимы и к другим платформам и технологиям (например, к Python и Intel MPI на узлах Linux).
Обзор задачи для нескольких экземпляров
В пакетной службе каждая задача обычно выполняется на одном вычислительном узле: вы отправляете несколько задач в задание, и пакетная служба планирует выполнение каждой задачи на узле. Однако, настроив параметры множественных экземпляров задачи, вы указываете службе Batch вместо этого создать одну основную задачу и несколько подзадач, которые затем выполняются на нескольких узлах.
При отправке в задание задачи с параметрами многоэкземплярности служба Batch выполняет несколько шагов, характерных только для многоэкземплярных задач:
- Служба Batch создает один основной и несколько подзадач на основе настроек многопоточности. Общее количество задач (основных и всех подзадач) соответствует количеству экземпляров (вычислительных узлов), указанному в настройках множественных экземпляров.
- Пакет назначает один из вычислительных узлов в качестве главного и планирует выполнение основной задачи на главном сервере. Выполнение подзадач она планирует на остальных вычислительных узлах, выделенных для многоэкземплярной задачи, размещая по одной подзадаче на каждом узле.
- Основная задача и все подзадачи загружают общие файлы ресурсов, которые вы указываете в настройках многозадачности.
- После загрузки общих файлов ресурсов основная задача и подзадачи выполняют команду coordination, указанную в параметрах многоэкземплярного режима. Команда координации обычно используется для подготовки узлов к выполнению задачи. Подготовка может включать запуск фоновых служб (таких как Microsoft MPI
smpd.exe) и проверку готовности узлов к обработке сообщений, передаваемых между узлами. -
После того, как основная задача и все подзадачи успешно выполнят команду координации, основная задача выполнит команду приложения на главном узле. Команда приложения — это командная строка самой многоэкземплярной задачи, и она выполняется только основной задачей. В решении на основе MS-MPI именно здесь вы выполняете свое приложение с поддержкой MPI, используя
mpiexec.exe.
Примечание.
Хотя она функционально отличается, "задача с несколькими экземплярами" не является уникальным типом задачи, например BatchStartTask или BatchJobPreparationTask. Многоэкземплярная задача — это просто стандартная задача Batch (BatchTask в Azure.Compute.Batch), для которой настроены параметры многоэкземплярности. В этой статье это называется многоэкземплярной задачей.
Требования к задачам с несколькими инстанциями
При выполнении многоэкземплярной задачи требуется, чтобы в пуле был включен обмен данными между узлами и отключено параллельное выполнение задач. Чтобы отключить параллельное выполнение задачи, задайте для свойства BatchAccountPoolData.TaskSlotsPerNode значение 1.
Примечание.
Батч ограничивает размер пула, для которого включен обмен данными между узлами.
В этом фрагменте кода показано, как создать пул для задач с несколькими экземплярами с помощью библиотеки Azure.ResourceManager.Batch.
ArmClient armClient = new ArmClient(new DefaultAzureCredential());
ResourceIdentifier batchAccountResourceId =
BatchAccountResource.CreateResourceIdentifier("subscriptionId", "resourceGroupName", "accountName");
BatchAccountResource batchAccount = armClient.GetBatchAccountResource(batchAccountResourceId);
BatchAccountPoolCollection poolCollection = batchAccount.GetBatchAccountPools();
BatchAccountPoolData poolData = new BatchAccountPoolData()
{
VmSize = "standard_d1_v2",
DeploymentConfiguration = new BatchDeploymentConfiguration()
{
VmConfiguration = new BatchVmConfiguration(
imageReference: new BatchImageReference()
{
Publisher = "MicrosoftWindowsServer",
Offer = "WindowsServer",
Sku = "2019-datacenter-core",
Version = "latest"
},
nodeAgentSkuId: "batch.node.windows amd64")
},
ScaleSettings = new BatchAccountPoolScaleSettings()
{
FixedScale = new BatchAccountFixedScaleSettings() { TargetDedicatedNodes = 3 }
},
// Multi-instance tasks require inter-node communication, and those nodes
// must run only one task at a time.
InterNodeCommunication = InterNodeCommunicationState.Enabled,
TaskSlotsPerNode = 1
};
Примечание.
Если вы пытаетесь запустить многоэкземплярную задачу в пуле с отключённой связью между узлами или с параметром taskSlotsPerNode больше 1, задача никогда не будет запланирована и останется в состоянии "Активно" на неопределённый срок.
Пулы с включенной функцией InterComputeNodeCommunication не допускают автоматического вывода узла из эксплуатации.
Установка MPI с помощью StartTask
Для выполнения приложений MPI с многоэкземплярной задачей на вычислительных узлах в пуле сначала необходимо установить реализацию MPI (например, MS-MPI или Intel MPI). Это хорошее время для использования BatchAccountPoolStartTask, который выполняется всякий раз, когда узел присоединяется к пулу или перезапускается. Этот фрагмент кода добавляет начальную задачу в определение пула, указывающее пакет установки MS-MPI в качестве файла ресурса. Командная строка команды начальной задачи выполняется после загрузки файла ресурсов на вычислительный узел. В этом случае командная строка выполняет автоматическую установку MS-MPI.
// Add a start task to the pool which we use for installing MS-MPI on
// the nodes as they join the pool (or when they are restarted).
poolData.StartTask = new BatchAccountPoolStartTask()
{
CommandLine = "cmd /c MSMpiSetup.exe -unattend -force",
UserIdentity = new BatchUserIdentity()
{
AutoUser = new BatchAutoUserSpecification() { ElevationLevel = BatchUserAccountElevationLevel.Admin }
},
WaitForSuccess = true,
};
poolData.StartTask.ResourceFiles.Add(new BatchResourceFile()
{
HttpUri = new Uri("https://mystorageaccount.blob.core.windows.net/mycontainer/MSMpiSetup.exe"),
FilePath = "MSMpiSetup.exe"
});
// Create the fully configured pool.
ArmOperation<BatchAccountPoolResource> pool = await poolCollection.CreateOrUpdateAsync(
WaitUntil.Completed, "MultiInstanceSamplePool", poolData);
Удаленный доступ к памяти (RDMA)
Если для вычислительных узлов пула пакетной обработки выбран размер с поддержкой RDMA, например А9, то ваше MPI-приложение может воспользоваться преимуществами высокопроизводительной сети RDMA Azure с удаленным доступом к памяти и низкими задержками.
Найдите размеры, помеченные как "С поддержкой доступа RDMA" в Размеры виртуальных машин в Azure (для пулов VirtualMachineConfiguration) или Размеры для облачных служб (для пулов CloudServicesConfiguration).
Примечание.
Чтобы воспользоваться преимуществами RDMA на вычислительных узлах Linux, на узлах необходимо использовать Intel MPI.
Создайте задачу с несколькими экземплярами с Azure. Compute.Batch
Теперь, когда мы рассмотрели требования к пулу и установку пакета MPI, давайте создадим многоэкземплярную задачу. В этом фрагменте мы создаем стандартный BatchTaskCreateOptions, а затем настраиваем его свойство MultiInstanceSettings. Как упоминалось ранее, многоинстансовая задача не является отдельным типом задач, а представляет собой стандартную пакетную задачу, настроенную с параметрами для множества экземпляров.
// Create the multi-instance task. Its command line is the "application command"
// and will be executed *only* by the primary, and only after the primary and
// subtasks execute the CoordinationCommandLine.
BatchTaskCreateOptions myMultiInstanceTask = new BatchTaskCreateOptions(
id: "mymultiinstancetask",
commandLine: "cmd /c mpiexec.exe -wdir %AZ_BATCH_TASK_SHARED_DIR% MyMPIApplication.exe")
{
// Configure the task's MultiInstanceSettings. The CoordinationCommandLine will be executed by
// the primary and all subtasks.
MultiInstanceSettings = new MultiInstanceSettings(
@"cmd /c start cmd /c ""%MSMPI_BIN%\smpd.exe"" -d")
{
NumberOfInstances = numberOfNodes
}
};
myMultiInstanceTask.MultiInstanceSettings.CommonResourceFiles.Add(new ResourceFile()
{
HttpUri = new Uri("https://mystorageaccount.blob.core.windows.net/mycontainer/MyMPIApplication.exe"),
FilePath = "MyMPIApplication.exe"
});
// Submit the task to the job. Batch will take care of splitting it into subtasks and
// scheduling them for execution on the nodes.
await myBatchClient.CreateTaskAsync("mybatchjob", myMultiInstanceTask);
Основная задача и подзадачи
При создании параметров для множественных экземпляров для задачи нужно указать число вычислительных узлов, которые должны выполнять задачу. При отправке задачи в задание пакетная служба создает одну основную задачу и такое количество подзадач, которое вместе с основной задачей совпадает с указанным количеством узлов.
Этим задачам назначается целочисленный идентификатор в диапазоне от 0 до numberOfInstances – 1. Задача с идентификатором 0 — это основная задача, а все остальные идентификаторы назначаются подзадачам. Например, если вы создаете следующие параметры нескольких экземпляров для задачи, основная задача будет иметь идентификатор 0, а подзадачи будут иметь идентификаторы 1–9.
int numberOfNodes = 10;
myMultiInstanceTask.MultiInstanceSettings = new MultiInstanceSettings("coord-cmd")
{
NumberOfInstances = numberOfNodes
};
Главный узел
Когда вы отправляете многоэкземплярную задачу, пакетная служба назначает один из вычислительных узлов главным и планирует выполнение основной задачи на нем. Подзадачи запланированы к выполнению на остальных узлах, выделенных для многоэкземплярной задачи.
команду координации
Команду координации выполняют основная задача и подзадачи.
Вызов команды координации выполняется в блокирующем режиме — Batch не выполняет команду приложения до тех пор, пока команда координации не завершится успешно для всех подзадач. ** Команда координации должна запустить все необходимые фоновые службы, убедиться, что они готовы к использованию, а затем завершить работу. К примеру, эта команда координации для решения с использованием MS-MPI версии 7 запускает службу SMPD на узле, а затем завершает работу:
cmd /c start cmd /c ""%MSMPI_BIN%\smpd.exe"" -d
Обратите внимание, что в этой команде координации используется start . Это необходимо, так как приложение smpd.exe не возвращается сразу после выполнения. Если не использовать команду start, то команда координации не возвращается и выполнение команды приложения блокируется.
Команда приложения
Если основная задача и все подзадачи выполнили команду координации, командную строку многоэкземплярной задачи выполняет толькоосновная задача. Назовем эту командную строку командой приложения , чтобы отличать ее от команды координации.
Для приложений MS-MPI используйте команду приложения, чтобы выполнить приложение с поддержкой MPI с использованием mpiexec.exe. В качестве примера ниже приведена команда приложения для решения с использованием MS-MPI версии 7:
cmd /c ""%MSMPI_BIN%\mpiexec.exe"" -c 1 -wdir %AZ_BATCH_TASK_SHARED_DIR% MyMPIApplication.exe
Примечание.
Так как команда mpiexec.exe приложений MS-MPI использует переменную CCP_NODES по умолчанию (см. раздел Переменные среды), в примере командной строки приложения выше она исключена.
Переменные среды
Batch создает несколько переменных среды, специфичных для задач с несколькими экземплярами, на вычислительных узлах, выделенных для такой задачи. Командные строки координации и приложения могут ссылаться на эти переменные среды, как и сценарии и программы, выполняемые с их помощью.
Следующие переменные среды создаются службой Batch для использования в задачах с несколькими экземплярами:
CCP_NODESAZ_BATCH_NODE_LISTAZ_BATCH_HOST_LISTAZ_BATCH_MASTER_NODEAZ_BATCH_TASK_SHARED_DIRAZ_BATCH_IS_CURRENT_NODE_MASTER
Полную информацию об этих и других переменных среды вычислительных узлов, включая их содержимое и видимость, см. в разделе Переменные среды вычислительных узлов.
Tip
Пример кода Batch Linux MPI содержит пример использования некоторых из этих переменных среды.
Файлы ресурсов
Для многоэкземплярных задач есть два набора файлов ресурсов: общие файлы ресурсов, которые скачивают все задачи (основная задача и подзадачи), и файлы ресурсов, указанные непосредственно для многоэкземплярной задачи, которые скачивает только основная задача.
Можно указать один или несколько распространенных файлов ресурсов в параметрах нескольких экземпляров для задачи. Основная задача и все подзадачи скачивают эти общие файлы ресурсов из службы хранилища Azure в общий каталог задач каждого узла. Доступ к общему каталогу задач можно получить из командных строк приложения и координации с помощью переменной среды AZ_BATCH_TASK_SHARED_DIR. Путь AZ_BATCH_TASK_SHARED_DIR идентичен на каждом узле, выделенном для задачи с несколькими экземплярами, поэтому между основной задачей и всеми подзадачами можно использовать одну общую команду координации. Batch не «предоставляет общий доступ» к каталогу в смысле предоставления удалённого доступа, но его можно использовать как точку монтирования или общего доступа, как уже упоминалось в совете о переменных среды.
Файлы ресурсов, которые вы указали для самой задачи с несколькими экземплярами, по умолчанию загружаются в рабочий каталог задачи, AZ_BATCH_TASK_WORKING_DIR. Как упоминалось, в отличие от общих файлов ресурсов, только основная задача скачивает файлы ресурсов, указанные для самой задачи с несколькими экземплярами.
Внимание
Для создания ссылок на эти каталоги в командной строке всегда используйте переменные среды AZ_BATCH_TASK_SHARED_DIR и AZ_BATCH_TASK_WORKING_DIR. Не пытайтесь создать пути вручную.
Срок действия задачи
Жизненный цикл основной задачи определяет продолжительность всей многоэкземплярной задачи. Когда основная задача завершается, все подзадачи прекращаются. Код завершения основного процесса является кодом завершения задачи и поэтому используется для определения того, завершилась ли задача успешно или неуспешно, при принятии решения о повторных попытках.
Если какая-либо из подзадач завершается ошибкой, например, с ненулевым кодом возврата, то завершается ошибкой и вся задача с несколькими экземплярами. Затем многоэкземплярная задача завершается и выполняется повторно до достижения предела повторных попыток.
Когда вы удаляете задачу с несколькими экземплярами, служба пакетной обработки также удаляет основную задачу и все подзадачи. Все каталоги и файлы подзадач удаляются из вычислительных узлов также, как и при стандартной задаче.
Свойства BatchTaskConstraints для задачи с несколькими экземплярами, такие как MaxTaskRetryCount, MaxWallClockTime и RetentionTime, учитываются так же, как и для стандартной задачи, и применяются к основной задаче и всем подзадачам. Однако при изменении свойства RetentionTime после добавления задачи с несколькими экземплярами в задание это изменение будет применено только к основной задаче, а все подзадачи продолжат использовать исходное значение RetentionTime.
Если последняя задача является частью многоэкземплярной задачи, в списке последних задач вычислительного узла отображается идентификатор подзадачи.
Получение сведений о подзадачах
Чтобы получить сведения о подзадачах с помощью библиотеки Azure.Compute.Batch, вызовите метод BatchClient.GetTaskSubTasks. Этот метод возвращает сведения о всех подзадачах и вычислительном узле, на котором выполняются задачи. Руководствуясь полученной информацией, можно определить корневой каталог каждой подзадачи, идентификатор пула, его текущее состояние, код выхода и многое другое. Эти сведения можно использовать в сочетании с методом BatchClient.GetNodeFile для получения файлов подзадачки. Обратите внимание, что этот метод не возвращает сведения для основной задачи (идентификатор — 0).
Примечание.
Если не указано иное, методы Azure.Compute.Batch, которые применяются к самому многоэкземплярному BatchTask, применяются только к основной задаче. Например, при вызове GetTaskFiles метода для задачи с несколькими экземплярами возвращаются только файлы основной задачи.
В следующем фрагменте кода показано, как получить сведения о подзадачах, а также запросить содержимое файла из узлов, на которых выполняются эти подзадачи.
// Obtain the multi-instance task from the Batch service
BatchTask myMultiInstanceTask = await batchClient.GetTaskAsync("mybatchjob", "mymultiinstancetask");
_ = myMultiInstanceTask;
// Now iterate over the subtasks for the task and print their stdout and stderr
// output if the subtask has completed
await foreach (BatchSubtask subtask in batchClient.GetSubTasksAsync("mybatchjob", "mymultiinstancetask"))
{
Console.WriteLine("subtask: {0}", subtask.Id);
Console.WriteLine("exit code: {0}", subtask.ExitCode);
if (subtask.State == BatchSubtaskState.Completed)
{
BatchNode node = await batchClient.GetNodeAsync(
subtask.NodeInfo.PoolId,
subtask.NodeInfo.NodeId);
BinaryData stdOut = await batchClient.GetNodeFileAsync(
subtask.NodeInfo.PoolId, node.Id, $"{subtask.NodeInfo.TaskRootDirectory}/stdout.txt");
BinaryData stdErr = await batchClient.GetNodeFileAsync(
subtask.NodeInfo.PoolId, node.Id, $"{subtask.NodeInfo.TaskRootDirectory}/stderr.txt");
Console.WriteLine("node: {0}:", node.Id);
Console.WriteLine("stdout.txt: {0}", stdOut);
Console.WriteLine("stderr.txt: {0}", stdErr);
}
else
{
Console.WriteLine("\tSubtask {0} is in state {1}", subtask.Id, subtask.State);
}
}
Пример кода
В примере кода MultiInstanceTasks на GitHub демонстрируется использование задачи с несколькими экземплярами для запуска приложения MS-MPI на вычислительных узлах службы Batch. Чтобы запустить пример кода, выполните указанные ниже действия.
Подготовка
- Скачайте установщики пакета SDK для MS-MPI и Redist и установите их. После установки можно проверить, настроены ли переменные среды MS-MPI.
- Создайте релизную сборку программы-примера MPI MPIHelloWorld. Это программа, которую многоэкземплярная задача будет запускать на вычислительных узлах.
- Создайте ZIP-файл, содержащий файл
MPIHelloWorld.exe(созданный на шаге 2) иMSMpiSetup.exe(скачанный на шаге 1). Вы отправите этот ZIP-файл как пакет приложения на следующем шаге. - Используйте портал Azure для создания приложения пакетной службы с именем "MPIHelloWorld" и укажите ZIP-файл, созданный на предыдущем шаге, в качестве версии 1.0 пакета приложения. Дополнительные сведения см. в разделе Передача приложений и управление ими.
Tip
Создание версии Release для MPIHelloWorld.exe обеспечивает отсутствие необходимости включать любые дополнительные зависимости (например, msvcp140d.dll или vcruntime140d.dll) в пакет вашего приложения.
Execution
Скачайте файл ZIP-файл azure-batch-samples с GitHub.
Откройте решение MultiInstanceTasks в Visual Studio 2019. Файл решения
MultiInstanceTasks.slnнаходится в следующем расположении:azure-batch-samples\CSharp\ArticleProjects\MultiInstanceTasks\Введите учетные данные учетных записей Batch и Storage в
AccountSettings.settingsв проекте Microsoft.Azure.Batch.Samples.Common.Создайте и запустите решение MultiInstanceTasks, чтобы выполнить пример приложения MPI на вычислительных узлах в пуле пакетной службы.
Необязательно. Используйте портал Azure или Batch Explorer, чтобы проверить пример пула, задания и задачи ("MultiInstanceSamplePool", "MultiInstanceSampleJob", "MultiInstanceSampleTask"), а затем удалить ресурсы.
Tip
Вы можете скачать Visual Studio Community бесплатно, если у вас нет Visual Studio.
Результат из MultiInstanceTasks.exe выглядит примерно так:
Creating pool [MultiInstanceSamplePool]...
Creating job [MultiInstanceSampleJob]...
Adding task [MultiInstanceSampleTask] to job [MultiInstanceSampleJob]...
Awaiting task completion, timeout in 00:30:00...
Main task [MultiInstanceSampleTask] is in state [Completed] and ran on compute node [tvm-1219235766_1-20161017t162002z]:
---- stdout.txt ----
Rank 2 received string "Hello world" from Rank 0
Rank 1 received string "Hello world" from Rank 0
---- stderr.txt ----
Main task completed, waiting 00:00:10 for subtasks to complete...
---- Subtask information ----
subtask: 1
exit code: 0
node: tvm-1219235766_3-20161017t162002z
stdout.txt:
stderr.txt:
subtask: 2
exit code: 0
node: tvm-1219235766_2-20161017t162002z
stdout.txt:
stderr.txt:
Delete job? [yes] no: yes
Delete pool? [yes] no: yes
Sample complete, hit ENTER to exit...
Следующие шаги
- Узнайте больше о поддержке MPI для пакетной службы Linux в Azure.
- Узнайте, как создавать пулы на вычислительных узлах Linux для использования в решениях MPI пакетной службы Azure.