Övning – Skapa en pool med beräkningsnoder för att köra jobben

Slutförd

För att köra ett batchjobb behöver vi lägga till en pool i Batch-kontot. En pool innehåller beräkningsnoder som är den motor som kör ditt batchjobb. Du kan ange antal, storlek och operativsystem för noder när vid skapandet. I den här övningen ändrar du den konsolapp som du skapade i föregående övning för att lägga till en pool i Batch-kontot.

Ditt företag vill kontrollera kostnaderna för appen och har bett dig att använda ett fast antal noder.

Viktigt!

Du behöver en egen Azure-prenumeration för att utföra den här övningen, och avgifter kan tillkomma. Om du inte redan har en Azure-prenumeration kan du skapa ett kostnadsfritt konto innan du börjar.

Lägga till inställningar för den nya poolen

  1. I Cloud Shell redigerar du filen Program.cs i redigeringsprogrammet:

    code Program.cs
    
  2. Lägg till följande egenskaper i klassen Program i 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";
    

    Föregående inställningar används i koden för att skapa poolen. Om vi tittar på varje variabel kan vi förklara dem på följande sätt:

    • PoolId: Namnet som vår kod använder för att referera till poolen i andra batchklientanrop.
    • LowPriorityNodeCount: Du ska skapa en pool med tre virtuella datorer med låg prioritet (VM).
    • PoolVMSize: De virtuella datorerna kommer att STANDARD_A1_v2, vilket ger noderna 1 CPU, 2 GB RAM-minne och 10 GB SSD-lagring.
    • appPackageId: Namnet på det programpaket som ska användas på de noder som du skapar.
    • appPackageVersion: Den version av programmet som ska användas på de noder som du skapar.

Uppdatera Main()-metoden för att stödja asynkrona anrop

Vi kommer att göra flera asynkrona anrop till molntjänster, så det första blir att göra Main asynkron. Med C# .NET version 7.1 och senare stöds asynkrona Main-metoder i konsolprogram.

  1. Ändra konsolappen så att den tillåter asynkrona metodanrop genom att först lägga till System.Threading.Tasks biblioteket.

    using System.Threading.Tasks;
    using System.Collections.Generic; // Also add generics to allow the app to use Lists
    
  2. Uppdatera sedan signaturen för metoden Main på följande sätt:

    static async Task Main(string[] args)
    

Skapa en pool

  1. Lägg till följande nya metod i klassen Program för att skapa en Batch-pool. Metoden:

    • Skapar ett bildreferensobjekt för att lagra inställningarna för noderna som ska läggas till i poolen.
    • Använder avbildningsreferensen för att skapa ett VirtualMachineConfiguration objekt.
    • Skapar en obundet pool med de egenskaper som deklarerats tidigare och VirtualMachineConfiguration.
    • Lägger till en programpaketreferens till poolen.
    • Skapar poolen i Azure.
    • Tar två parametrar: batchClient och 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
                }
            }
        }  
    
  2. Anropa CreateBatchPoolAsync från vår Main metod. Metoden Main bör nu vara följande:

    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);
    }
    

Testa appen

  1. Högerklicka i kodredigeraren och välj Spara. Högerklicka sedan och välj Avsluta.

  2. Kompilera och kör appen i Cloud Shell med följande kommando:

    dotnet run
    
  3. Det tar några minuter att köra appen och du bör få följande utdata:

    URL: <your batch account url, Name: <your batch name>, Key: <your batch key>
    Creating pool [WinFFmpegPool]...
    

Kom ihåg att varje nod är en virtuell dator som kör Windows 2012 Server, med endast en CPU och 2 GB RAM. Det tar tid för batchen att överföra dessa avbildningar av virtuella Windows-datorer från Azure Virtual Machine Marketplace, skapa VM-infrastrukturen och nätverk samt slutligen starta varje nod. Det här är den mest tidskrävande delen av de flesta Batch-lösningar. Ett typiskt Batch-arbetsflöde rensar inte poolen och dess noder.