Упражнение. Создание пула вычислительных узлов для выполнения заданий
Чтобы запустить пакетное задание, необходимо добавить пул в учетную запись Batch. Пул содержит вычислительные узлы, которые являются движками для выполнения задания Batch. Вы указываете количество, размер и операционную систему узлов во время создания. В этом упражнении вы измените консольное приложение, созданное в предыдущем упражнении, чтобы добавить пул в вашу учетную запись Batch.
Ваша компания хочет контролировать затраты на приложение и попросила вас использовать фиксированное количество узлов.
Важный
Для выполнения этого упражнения вам потребуется собственная подписка Azure, и возможно, вы понесете расходы. Если у вас еще нет подписки Azure, создайте бесплатную учетную запись перед началом.
Добавление параметров для нового пула
В Cloud Shell измените файл
Program.cs
в редакторе:code Program.cs
Добавьте следующие свойства в класс Program в Program.cs:
private const string PoolId = "WinFFmpegPool"; private const int DedicatedNodeCount = 0; private const int LowPriorityNodeCount = 3; private const string PoolVMSize = "STANDARD_D2_v2"; private const string appPackageId = "ffmpeg"; private const string appPackageVersion = "3.4";
Предыдущие параметры используются в коде для создания пула. Рассмотрим каждую переменную, мы можем объяснить их следующим образом:
- PoolId: имя, которое наш код использует для ссылки на пул в других вызовах клиентской пакетной службы.
- LowPriorityNodeCount: вы собираетесь создать пул из трёх виртуальных машин с низким приоритетом.
- PoolVMSize: виртуальные машины будут STANDARD_A1_v2, что дает узлам 1 ЦП, 2 ГБ ОЗУ и 10 ГБ хранилища SSD.
- appPackageId: имя пакета приложения, используемого на создаваемых узлах.
- appPackageVersion: версия приложения, используемая на создаваемых узлах.
Обновление метода Main() для поддержки асинхронных вызовов
Мы будем выполнять несколько асинхронных вызовов к облачным службам, поэтому первое, что необходимо сделать, — сделать Main
асинхронными. В C# .NET версии 7.1 и более поздних версиях поддерживаются асинхронные Main
методы в консольных приложениях.
Измените консольное приложение, чтобы разрешить асинхронные вызовы метода, сначала добавив библиотеку
System.Threading.Tasks
.using System.Threading.Tasks; using System.Collections.Generic; // Also add generics to allow the app to use Lists
Затем обновите сигнатуру метода
Main
следующим образом:static async Task Main(string[] args)
Создание пула
Добавьте следующий новый метод в класс Program для создания пула Batch. Метод:
- Создает объект ссылки на образ для хранения параметров для добавляемых узлов в пул.
- Использует ссылку на изображение для создания объекта
VirtualMachineConfiguration
. - Создает несвязанный пул с помощью свойств, объявленных ранее, и
VirtualMachineConfiguration
. - Добавляет ссылку на пакет приложения в пул.
- Создает пул в Azure.
- Принимает два параметра,
batchClient
иPoolId
.
private static async Task CreateBatchPoolAsync(BatchClient batchClient, string poolId) { CloudPool pool = null; Console.WriteLine("Creating pool [{0}]...", poolId); // Create an image reference object to store the settings for the nodes to be added to the pool ImageReference imageReference = new ImageReference( publisher: "MicrosoftWindowsServer", offer: "WindowsServer", sku: "2012-R2-Datacenter-smalldisk", version: "latest"); // Use the image reference to create a VirtualMachineConfiguration object VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration( imageReference: imageReference, nodeAgentSkuId: "batch.node.windows amd64"); try { // Create an unbound pool. No pool is actually created in the Batch service until we call // CloudPool.CommitAsync(). This CloudPool instance is therefore considered "unbound," and we can // modify its properties. pool = batchClient.PoolOperations.CreatePool( poolId: poolId, targetDedicatedComputeNodes: DedicatedNodeCount, targetLowPriorityComputeNodes: LowPriorityNodeCount, virtualMachineSize: PoolVMSize, virtualMachineConfiguration: virtualMachineConfiguration); // Specify the application and version to install on the compute nodes pool.ApplicationPackageReferences = new List<ApplicationPackageReference> { new ApplicationPackageReference { ApplicationId = appPackageId, Version = appPackageVersion } }; // Create the pool await pool.CommitAsync(); } catch (BatchException be) { // Accept the specific error code PoolExists as that is expected if the pool already exists if (be.RequestInformation?.BatchError?.Code == BatchErrorCodeStrings.PoolExists) { Console.WriteLine("The pool [{0}] already existed when we tried to create it", poolId); } else { throw; // Any other exception is unexpected } } }
Вызов
CreateBatchPoolAsync
из нашего методаMain
. Теперь метод Main должен быть следующим:static async Task Main(string[] args) { // Read the environment variables to allow the app to connect to the Azure Batch account batchAccountUrl = Environment.GetEnvironmentVariable(envVarBatchURI); batchAccountName = Environment.GetEnvironmentVariable(envVarBatchName); batchAccountKey = Environment.GetEnvironmentVariable(envVarKey); // Show the user the batch the app is attaching to Console.WriteLine("URL: {0}, Name: {1}, Key: {2}", batchAccountUrl, batchAccountName, batchAccountKey); // The batch client requires a BatchSharedKeyCredentials object to open a connection var sharedKeyCredentials = new BatchSharedKeyCredentials(batchAccountUrl, batchAccountName, batchAccountKey); var batchClient = BatchClient.Open(sharedKeyCredentials); // Create the Batch pool, which contains the compute nodes that execute tasks. await CreateBatchPoolAsync(batchClient, PoolId); }
Тестирование приложения
В редакторе кода щелкните правой кнопкой мыши и выберите Сохранить, а затем щелкните правой кнопкой мыши и выберите Выйти.
В Cloud Shell скомпилируйте и запустите приложение с помощью следующей команды:
dotnet run
Приложение займет несколько минут, и вы должны получить следующие выходные данные:
URL: <your batch account url, Name: <your batch name>, Key: <your batch key> Creating pool [WinFFmpegPool]...
Помните, что каждый узел — это виртуальная машина под управлением Windows Server 2012 с одним ЦП и 2 ГБ ОЗУ. Передача образов виртуальных машин Windows из Azure Virtual Machine Marketplace, создание сетевой и инфраструктуры виртуальной машины и последующий запуск каждого узла через Azure Batch требуют времени. Это наиболее времязатратная часть большинства пакетных решений. Типичный рабочий процесс пакетной службы не очищает пул и его узлы.