Esercizio: Creare un pool di nodi di calcolo per eseguire i processi
Per eseguire un processo batch, è necessario aggiungere un pool all'account Batch. Un pool contiene nodi di calcolo, vale a dire motori che eseguono il processo batch. Al momento della creazione, è necessario specificare il numero, le dimensioni e il sistema operativo dei nodi. In questo esercizio si modificherà l'app console compilata nell'esercizio precedente per aggiungere un pool all'account Batch.
L'azienda vuole tenere sotto controllo i costi dell'app e ha pertanto richiesto di usare un numero fisso di nodi.
Importante
Per eseguire questo esercizio è necessario disporre di una propria sottoscrizione di Azure e questo potrebbe comportare dei costi. Se non hai ancora una sottoscrizione di Azure, crea un account gratuito prima di iniziare.
Aggiungere le impostazioni per il nuovo pool
In Cloud Shell modificare il file
Program.cs
nell'editor:code Program.cs
Aggiungere le proprietà seguenti alla classe Program in 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";
Le impostazioni precedenti vengono usate nel codice per creare il pool. È possibile esaminare ogni variabile nel modo seguente:
- PoolId: Il nome che il codice usa per fare riferimento al pool in altre chiamate client al batch.
- LowPriorityNodeCount: Il pool che si creerà avrà tre macchine virtuali con priorità bassa (VM).
- PoolVMSize: Le macchine virtuali saranno di tipo STANDARD_A1_v2. I nodi avranno quindi 1 CPU, 2 GB di RAM e 10 GB di archiviazione SSD.
- appPackageId: Il nome del pacchetto dell'applicazione da usare nei nodi creati.
- appPackageVersion: La versione dell'applicazione da usare nei nodi creati.
Aggiornare il metodo Main() per supportare le chiamate asincrone
Le chiamate asincrone a servizi cloud saranno frequenti, quindi è prima di tutto necessario rendere Main
asincrono. In C# .NET versione 7.1 e versioni successive i metodi Main
asincroni sono supportati nelle applicazioni console.
Modificare l'app console per consentire le chiamate al metodo asincrono aggiungendo prima di tutto la libreria
System.Threading.Tasks
.using System.Threading.Tasks; using System.Collections.Generic; // Also add generics to allow the app to use Lists
A questo punto, aggiornare la firma del metodo
Main
nel modo seguente:static async Task Main(string[] args)
Creare un pool
Aggiungere il nuovo metodo seguente alla classe Program per creare un pool di Batch. Il metodo si comporta come di seguito:
- Creare un oggetto di riferimento all'immagine per archiviare le impostazioni dei nodi da aggiungere al pool.
- Usa il riferimento all'immagine per creare un oggetto
VirtualMachineConfiguration
. - Crea un pool non associato usando le proprietà dichiarate in precedenza e
VirtualMachineConfiguration
. - Aggiunge al pool un riferimento al pacchetto dell'applicazione.
- Crea il pool in Azure.
- Accetta due parametri,
batchClient
ePoolId
.
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 } } }
Chiamare
CreateBatchPoolAsync
dal metodoMain
. Il metodo Main deve avere la struttura seguente: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); }
Testare l'app
Nell'editor di codice fare clic con il pulsante destro del mouse e scegliere Salva, quindi fare clic con il pulsante destro del mouse e scegliere Esci.
Compilare ed eseguire l'app con il comando seguente in Cloud Shell:
dotnet run
L'esecuzione dell'app richiederà alcuni minuti e si dovrebbe ottenere l'output seguente:
URL: <your batch account url, Name: <your batch name>, Key: <your batch key> Creating pool [WinFFmpegPool]...
Tenere presente che ogni nodo è un macchina virtuale che esegue Windows Server 2012, con solo 1 CPU e 2 GB di RAM. Batch richiede tempo per trasferire le immagini delle macchine virtuali di Windows dal Marketplace delle macchine virtuali di Azure, creare l'infrastruttura e la rete delle macchini virtuali e infine avviare ogni nodo. Si tratta della parte più lunga nella maggior parte delle soluzioni di Batch. In genere un flusso di lavoro di Batch non esegue la pulizia del pool e dei relativi nodi.