연습 - 작업을 실행할 컴퓨팅 노드 풀 만들기
일괄 작업을 실행하려면 Batch 계정에 풀을 추가해야 합니다. 풀은 일괄 작업을 실행하는 엔진인 컴퓨팅 노드를 포함합니다. 생성 시 노드의 수, 크기 및 운영 체제를 지정합니다. 이 연습에서는 이전 연습에서 만든 콘솔 앱을 수정하여 Batch 계정에 풀을 추가하겠습니다.
회사에서 앱의 비용을 제어하려고 하며 고정된 수의 노드를 사용하도록 요청했습니다.
Important
이 연습을 수행하려면 사용자의 Azure 구독이 필요하며 요금이 발생할 수 있습니다. Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.
새 풀의 설정 추가
다음과 같이 Cloud Shell에서 편집기를 사용하여
Program.cs
파일을 편집합니다.code Program.cs
Program.cs의 Program 클래스에 다음 속성을 추가합니다.
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: 우선 순위가 낮은 3개의 VM(가상 머신)이 있는 풀을 만듭니다.
- PoolVMSize: VM은 STANDARD_A1_v2 노드에 1 CPU, 2GB RAM 및 10GB의 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 } } }
Main
메서드에서CreateBatchPoolAsync
를 호출합니다. 이제 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 2012 서버를 실행하는 VM이며, CPU 1개와 2GB RAM을 갖고 있습니다. Batch가 Azure Virtual Machine Marketplace에서 이러한 Windows VM 이미지를 전송하고, VM 인프라 및 네트워킹을 만들고, 마지막으로 각 노드를 시작할 때까지 시간이 걸립니다. 대부분의 Batch 솔루션에서 이 부분에 가장 많은 시간이 소요됩니다. 일반적인 Batch 워크플로에서는 풀과 노드를 정리하지 않습니다.