練習 - 建立計算節點的集區以執行我們的作業
若要執行 Batch 作業,我們需要將集區新增至我們的 Batch 帳戶。 集區包含計算節點,也就是執行 Batch 作業的引擎。 您要在建立時指定節點的數目、大小和作業系統。 在此練習中,您將修改在上一個練習中建立的主控台應用程式,以將集區新增至您的 Batch 帳戶。
公司想要控制應用程式的成本,並要求您使用固定的節點數目。
重要
您必須有自己的 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:我們的程式碼會用來參考其他 Batch 用戶端呼叫中集區的名稱。
- LowPriorityNodeCount:您將建立一個具有三個低優先順序虛擬機器 (VM) 的集區。
- PoolVMSize:VM 將為 STANDARD_A1_v2,這會提供節點 1 顆 CPU、2 GB RAM 和 10 GB 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 Server 的 VM,且只配置一個 CPU 和 2 GB RAM。 Batch 需要時間,從 Azure Virtual Machine Marketplace 傳送那些 Windows VM 映像、建立 VM 基礎結構和網路功能,最後啟動每個節點。 這是大部分 Batch 解決方案最耗時的部分。 典型的 Batch 工作流程不會清除集區及其節點。