Início rápido: usar o .NET para criar um pool do Lote e executar um trabalho

Esse início rápido mostra como começar a usar o Lote do Azure executando um aplicativo C# que usa a API .NET do Lote do Azure. O aplicativo .NET:

  • Carrega vários arquivos de dados de entrada em um contêiner de blob do Armazenamento do Azure a ser usado para processamento de tarefas do Lote.
  • Cria um pool de duas máquinas virtuais (VMs) ou nós de computação, executando o Windows Server.
  • Cria um trabalho que executa tarefas nos nós para processar cada arquivo de entrada usando uma linha de comando do Windows.
  • Exibe os arquivos de saída retornados pelas tarefas.

Depois de concluir este início rápido, você entenderá os principais conceitos do serviço Lote e estará pronto para experimentá-lo com cargas de trabalho mais realistas em maior escala.

Pré-requisitos

Executar o aplicativo

Para concluir esse início rápido, baixe ou clone o aplicativo, forneça os valores da sua conta, compile e execute o aplicativo e verifique a saída.

Baixar ou clonar o aplicativo

Baixe ou clone o aplicativo de Início rápido do .NET no Lote do Azure do GitHub. Use o seguinte comando para clonar o repositório do aplicativo com um cliente Git:

git clone https://github.com/Azure-Samples/batch-dotnet-quickstart.git

Forneça as informações da sua conta

O aplicativo precisa usar seus nomes de conta do Lote e do Armazenamento, valores de chave de conta e ponto de extremidade da conta do Lote. Você pode obter essas informações do portal do Azure, APIs do Azure ou ferramentas de linha de comando.

Para obter as informações da sua conta do portal do Azure:

  1. Na barra do Azure Search, pesquise e selecione o nome da conta do Lote.
  2. Na página da Conta do Lote, selecione Chaves na navegação à esquerda.
  3. Na página Chaves, copie os seguintes valores:
  • conta do Lote
  • Ponto de extremidade da conta
  • Chave de acesso primária
  • Nome da conta de armazenamento
  • Key1

Navegue até a pasta batch-dotnet-quickstart baixada e edite as cadeias de caracteres de credencial em Program.cs para fornecer os valores que você copiou:

// Batch account credentials
private const string BatchAccountName = "<batch account>";
private const string BatchAccountKey  = "<primary access key>";
private const string BatchAccountUrl  = "<account endpoint>";

// Storage account credentials
private const string StorageAccountName = "<storage account name>";
private const string StorageAccountKey  = "<key1>

Importante

A exposição de chaves de conta na origem do aplicativo não é recomendada para uso em produção. Você deve restringir o acesso às credenciais e consultá-las em seu código, usando variáveis ou um arquivo de configuração. É melhor armazenar chaves de conta do Lote e do Armazenamento no Azure Key Vault.

Compilar e executar o aplicativo e exibir a saída

Para ver o fluxo de trabalho do Lote em ação, compile e execute o aplicativo no Visual Studio. Você também pode usar a linha de comando dotnet build e os comandos dotnet run.

No Visual Studio:

  1. Abra o arquivo BatchDotNetQuickstart.sln, clique com o botão direito do mouse na solução no Gerenciador de Soluções e selecione Compilar. Se solicitado, use o Gerenciador de Pacotes NuGet para atualizar ou restaurar os pacotes NuGet.

  2. Depois que a compilação for concluída, selecione BatchDotNetQuickstart na barra de menus superior para executar o aplicativo.

O tempo de execução típico com a configuração padrão é de aproximadamente cinco minutos. A instalação inicial do pool leva mais tempo. Para executar novamente o trabalho, exclua o trabalho da execução anterior, mas não exclua o pool. Em um pool pré-configurado, o trabalho é concluído em alguns segundos.

O aplicativo retorna saídas semelhantes ao seguinte exemplo:

Sample start: 11/16/2022 4:02:54 PM

Container [input] created.
Uploading file taskdata0.txt to container [input]...
Uploading file taskdata1.txt to container [input]...
Uploading file taskdata2.txt to container [input]...
Creating pool [DotNetQuickstartPool]...
Creating job [DotNetQuickstartJob]...
Adding 3 tasks to job [DotNetQuickstartJob]...
Monitoring all tasks for 'Completed' state, timeout in 00:30:00...

Há uma pausa em Monitoring all tasks for 'Completed' state, timeout in 00:30:00... enquanto os nós de computação do pool são iniciados. À medida que as tarefas são criadas, o Lote as enfileira para serem executadas no pool. Assim que o primeiro nó de computação estiver disponível, a primeira tarefa será executada no nó. Você pode monitorar status de nó, tarefa e trabalho na página da conta do Lote no portal do Azure.

Após a conclusão de cada tarefa, você verá uma saída semelhante ao seguinte exemplo:

Printing task output.
Task: Task0
Node: tvm-2850684224_3-20171205t000401z
Standard out:
Batch processing began with mainframe computers and punch cards. Today it still plays a central role...
stderr:
...

Examine o código

Examine o código para entender as etapas no Início rápido do .NET no Lote do Azure.

Criar clientes de serviço e carregar arquivos de recurso

  1. Para interagir com a conta de armazenamento, o aplicativo usa a biblioteca de clientes de Blobs de Armazenamento do Azure para .NET para criar um BlobServiceClient.

    var sharedKeyCredential = new StorageSharedKeyCredential(storageAccountName, storageAccountKey);
    string blobUri = "https://" + storageAccountName + ".blob.core.windows.net";
    
    var blobServiceClient = new BlobServiceClient(new Uri(blobUri), sharedKeyCredential);
    return blobServiceClient;
    
  2. O aplicativo usa a referência blobServiceClient para criar um contêiner na conta de armazenamento e carregar os arquivos de dados no contêiner. Os arquivos no armazenamento são definidos como objetos ResourceFile do Lote que ele pode baixar mais tarde para os nós de computação.

    List<string> inputFilePaths = new()
    {
        "taskdata0.txt",
        "taskdata1.txt",
        "taskdata2.txt"
    };
    
    var inputFiles = new List<ResourceFile>();
    
    foreach (var filePath in inputFilePaths)
    {
        inputFiles.Add(UploadFileToContainer(containerClient, inputContainerName, filePath));
    }
    
  3. O aplicativo cria um objeto BatchClient para criar e gerenciar pools, trabalhos e tarefas do Lote. O cliente do Lote no exemplo usa a autenticação de chave compartilhada. O Lote também dá suporte à autenticação do Microsoft Entra.

    var cred = new BatchSharedKeyCredentials(BatchAccountUrl, BatchAccountName, BatchAccountKey);
    
     using BatchClient batchClient = BatchClient.Open(cred);
    ...
    

Criar um pool de nós de computação

Para criar um pool do Lote, o aplicativo usa o método BatchClient.PoolOperations.CreatePool para definir o número de nós, o tamanho da VM e a configuração do pool. O seguinte objeto VirtualMachineConfiguration especifica um ImageReference para uma imagem do Windows Server Marketplace. O Lote oferece suporte a uma ampla variedade de imagens do sistema operacional do Windows Server e Linux Marketplace e também oferece suporte a imagens de VM personalizadas.

O PoolNodeCount e o tamanho da VM PoolVMSize são constantes definidas. O aplicativo cria um pool de dois nós Standard_A1_v2. Esse tamanho oferece um bom equilíbrio entre desempenho e custo para este exemplo de início rápido.

O método Commit envia o pool para o serviço Lote.


private static VirtualMachineConfiguration CreateVirtualMachineConfiguration(ImageReference imageReference)
{
    return new VirtualMachineConfiguration(
        imageReference: imageReference,
        nodeAgentSkuId: "batch.node.windows amd64");
}

private static ImageReference CreateImageReference()
{
    return new ImageReference(
        publisher: "MicrosoftWindowsServer",
        offer: "WindowsServer",
        sku: "2016-datacenter-smalldisk",
        version: "latest");
}

private static void CreateBatchPool(BatchClient batchClient, VirtualMachineConfiguration vmConfiguration)
{
    try
    {
        CloudPool pool = batchClient.PoolOperations.CreatePool(
            poolId: PoolId,
            targetDedicatedComputeNodes: PoolNodeCount,
            virtualMachineSize: PoolVMSize,
            virtualMachineConfiguration: vmConfiguration);

        pool.Commit();
    }
...

Criar um trabalho do Lote

Um trabalho do Lote é um agrupamento lógico de uma ou mais tarefas. O trabalho inclui configurações comuns às tarefas, como prioridade e o pool onde elas devem ser executadas.

O aplicativo usa o método BatchClient.JobOperations.CreateJob para criar um trabalho em seu pool. O método Commit envia o trabalho para o serviço Lote. Inicialmente, o trabalho não tem nenhuma tarefa.

try
{
    CloudJob job = batchClient.JobOperations.CreateJob();
    job.Id = JobId;
    job.PoolInformation = new PoolInformation { PoolId = PoolId };

    job.Commit();
}
...

Criar tarefas

O Lote fornece várias maneiras para implantar aplicativos e scripts em nós de computação. Esse aplicativo cria uma lista de objetos de entrada CloudTaskResourceFile Cada tarefa processa um arquivo de entrada usando uma propriedade CommandLine. A linha de comando do Lote é onde você especifica seu aplicativo ou script.

A linha de comando no código a seguir executa o comando type do Windows para exibir os arquivos de entrada. Em seguida, o aplicativo adiciona cada tarefa ao trabalho com o método AddTask, que enfileira a tarefa para execução nos nós de computação.

for (int i = 0; i < inputFiles.Count; i++)
{
    string taskId = String.Format("Task{0}", i);
    string inputFilename = inputFiles[i].FilePath;
    string taskCommandLine = String.Format("cmd /c type {0}", inputFilename);

    var task = new CloudTask(taskId, taskCommandLine)
    {
        ResourceFiles = new List<ResourceFile> { inputFiles[i] }
    };
    tasks.Add(task);
}

batchClient.JobOperations.AddTask(JobId, tasks);

Exibir saída da tarefa

O aplicativo cria um TaskStateMonitor para monitorar as tarefas e fazer com que sejam concluídas. Quando cada tarefa é executada com êxito, sua saída é gravada em stdout.txt. O aplicativo então usa a propriedade CloudTask.ComputeNodeInformation para exibir o arquivo stdout.txt para cada tarefa concluída.

foreach (CloudTask task in completedtasks)
{
    string nodeId = String.Format(task.ComputeNodeInformation.ComputeNodeId);
    Console.WriteLine("Task: {0}", task.Id);
    Console.WriteLine("Node: {0}", nodeId);
    Console.WriteLine("Standard out:");
    Console.WriteLine(task.GetNodeFile(Constants.StandardOutFileName).ReadAsString());
}

Limpar os recursos

O aplicativo exclui automaticamente o contêiner de armazenamento que cria e oferece a opção para excluir o pool e o trabalho do Lote. Pools e nós incorrem em encargos enquanto os nós estão em execução, mesmo que não estejam executando trabalhos. Se você não precisa mais do pool, exclua-o.

Quando você não precisar mais da conta do Lote e da conta de armazenamento, poderá excluir o grupo de recursos que as contém. Na portal do Azure, selecione Excluir grupo de recursos na parte superior da página do grupo de recursos. Na tela Excluir um grupo de recursos, insira o nome do grupo de recursos e selecione Excluir.

Próximas etapas

Nesse início rápido, você executou um aplicativo que usa a API .NET do Lote para criar um pool, nós, trabalho e tarefas do Lote. O trabalho carregou arquivos de recurso em um contêiner de armazenamento, executou tarefas nos nós e exibiu a saída dos nós.

Agora que você conhece os conceitos principais do serviço do Lote, está pronto para usá-lo com cargas de trabalho mais realistas em maior escala. Para saber mais sobre o Lote do Azure e percorrer uma carga de trabalho paralela com um aplicativo real, continue com o tutorial de .NET do Lote.