Crie consultas para listar recursos em lote de forma eficiente

A maioria dos aplicativos de Lote do Azure faz monitoramento ou outras operações que consultam o serviço de Lote. Essas consultas de lista geralmente acontecem em intervalos regulares. Por exemplo, antes de verificar se há tarefas em fila em um trabalho, você deve obter dados sobre cada tarefa nesse trabalho. Reduzir a quantidade de dados que o serviço em lote retorna para consultas melhora o desempenho do seu aplicativo. Este artigo explica como criar e executar essas consultas de forma eficiente. Você pode criar consultas filtradas para trabalhos em lote, tarefas, nós de computação e outros recursos com a biblioteca .NET em lote.

Nota

O serviço Batch fornece suporte de API para os cenários comuns de contagem de tarefas em um trabalho e contagem de nós de computação no pool de lotes. Você pode chamar as operações Get Task Counts e List Pool Node Counts em vez de usar uma consulta de lista. No entanto, essas operações mais eficientes retornam informações mais limitadas que podem não estar atualizadas. Para obter mais informações, consulte Contar tarefas e calcular nós por estado.

Especificar um nível de detalhe

Pode haver milhares de entidades, como trabalhos, tarefas e nós de computação em um aplicativo de lote de produção. Para cada consulta feita sobre os recursos, uma quantidade potencialmente grande de dados vai do serviço Batch para seu aplicativo. Limite quantos itens e quais informações sua consulta retorna para melhorar o desempenho.

Este trecho de código da API .NET em lote lista todas as tarefas associadas a um trabalho, juntamente com todas as propriedades de cada tarefa.

// Get a collection of all of the tasks and all of their properties for job-001
IPagedEnumerable<CloudTask> allTasks =
    batchClient.JobOperations.ListTasks("job-001");

Aplique um nível de detalhe à sua consulta para listar informações de forma mais eficiente. Forneça um objeto ODATADetailLevel para o método JobOperations.ListTasks . Esse trecho retorna apenas as propriedades de ID, linha de comando e informações de nó de computação de tarefas concluídas.

// Configure an ODATADetailLevel specifying a subset of tasks and
// their properties to return
ODATADetailLevel detailLevel = new ODATADetailLevel();
detailLevel.FilterClause = "state eq 'completed'";
detailLevel.SelectClause = "id,commandLine,nodeInfo";

// Supply the ODATADetailLevel to the ListTasks method
IPagedEnumerable<CloudTask> completedTasks =
    batchClient.JobOperations.ListTasks("job-001", detailLevel);

Neste cenário de exemplo, se houver milhares de tarefas no trabalho, os resultados da segunda consulta normalmente são retornados mais rapidamente do que da primeira consulta. Para obter mais informações sobre como usar ODATADetailLevel quando você lista itens com a API .NET em lote, consulte a seção Consulta eficiente no .NET em lote.

Importante

É altamente recomendável que você sempre forneça um ODATADetailLevel objeto para sua lista de API do .NET para obter a máxima eficiência e desempenho do seu aplicativo. Ao especificar um nível de detalhe, você pode ajudar a reduzir os tempos de resposta do serviço em lote, melhorar a utilização da rede e minimizar o uso de memória pelos aplicativos cliente.

Usar cadeias de caracteres de consulta

Você pode usar as APIs Batch .NET e Batch REST para reduzir quantos itens uma consulta retorna e quantas informações a consulta retorna para cada item. Há três tipos de cadeia de caracteres de consulta que você pode usar para restringir sua consulta: $filter, $select e $expand.

Para a API .NET em lote, consulte as propriedades da classe ODATADetailLevel. Consulte também a seção Consulta eficiente no Batch .NET.

Para a API REST em lote, consulte a referência da API REST em lote. Localize a referência Lista para o recurso que você deseja consultar. Em seguida, revise a seção Parâmetros de URI para obter detalhes sobre $filter, $selecte $expand. Por exemplo, consulte os parâmetros de URI para Pool - List. Veja também como fazer consultas em lote eficientes com a CLI do Azure.

Nota

Ao construir qualquer um dos três tipos de cadeia de caracteres de consulta, você deve garantir que os nomes de propriedade e maiúsculas e minúsculas correspondam aos de suas contrapartes de elementos da API REST. Por exemplo, ao trabalhar com a classe .NET CloudTask , você deve especificar estado em vez de Estado, mesmo que a propriedade .NET seja CloudTask.State. Para obter mais informações, consulte os mapeamentos de propriedade entre as APIs .NET e REST.

Filtro

A $filter cadeia de caracteres de expressão reduz o número de itens retornados. Por exemplo, você pode listar apenas as tarefas em execução para um trabalho ou listar apenas os nós de computação que estão prontos para executar tarefas.

Essa cadeia de caracteres consiste em uma ou mais expressões, com uma expressão que consiste em um nome de propriedade, operador e valor. As propriedades que podem ser especificadas são específicas para cada tipo de entidade que você consulta, assim como os operadores com suporte para cada propriedade. Várias expressões podem ser combinadas usando os operadores and lógicos e or.

Este exemplo lista apenas as tarefas de renderização em execução: (state eq 'running') and startswith(id, 'renderTask').

Selecione

A $select cadeia de caracteres de expressão limita os valores de propriedade que são retornados para cada item. Você especifica uma lista de nomes de propriedades separados por vírgulas e somente esses valores de propriedade são retornados para os itens nos resultados da consulta. Você pode especificar qualquer uma das propriedades para o tipo de entidade que está consultando.

Este exemplo especifica que apenas três valores de propriedade devem ser retornados para cada tarefa: id, state, stateTransitionTime.

Expandir

A $expand cadeia de caracteres de expressão reduz o número de chamadas de API necessárias para obter determinadas informações. Você pode usar essa cadeia de caracteres para obter mais informações sobre cada item com uma única chamada de API. Esse método ajuda a melhorar o desempenho reduzindo as chamadas de API. Use uma $expand cadeia de caracteres em vez de obter a lista de entidades e solicitar informações sobre cada item de lista.

Semelhante ao , $expand controla $selectse determinados dados são incluídos nos resultados da consulta de lista. Quando todas as propriedades são necessárias e nenhuma string de seleção é especificada, $expand deve ser usado para obter informações estatísticas. Se uma string select for usada para obter um subconjunto de propriedades, ela stats poderá ser especificada na string select e $expand não precisará ser especificada.

Os usos suportados dessa cadeia de caracteres incluem a listagem de trabalhos, agendas de trabalho, tarefas e pools. Atualmente, a cadeia de caracteres suporta apenas informações estatísticas.

Este exemplo especifica que as informações estatísticas devem ser retornadas para cada item da lista: stats.

Regras para filtrar, selecionar e expandir cadeias de caracteres

  • Certifique-se de que os nomes das propriedades em filtrar, selecionar e expandir cadeias de caracteres apareçam como aparecem na API REST em lote. Esta regra se aplica mesmo quando você usa o Batch .NET ou um dos outros SDKs de lote.
  • Todos os nomes de propriedade diferenciam maiúsculas de minúsculas, mas os valores de propriedade não diferenciam maiúsculas de minúsculas.
  • As cadeias de caracteres de data/hora podem ser um de dois formatos e devem ser precedidas de DateTime.
    • Exemplo de formato W3C-DTF: creationTime gt DateTime'2011-05-08T08:49:37Z'
    • Exemplo de formato RFC 1123: creationTime gt DateTime'Sun, 08 May 2011 08:49:37 GMT'
  • As cordas booleanas são ou true false.
  • Se uma propriedade ou operador inválido for especificado, ocorrerá um 400 (Bad Request) erro.

Consulta eficiente no Batch .NET

Na API .NET em lote, a classe ODATADetailLevel fornece filtro, seleção e expansão de cadeias de caracteres para listar operações. A ODataDetailLevel classe tem três propriedades de cadeia de caracteres públicas. Você pode especificar essas propriedades no construtor ou definir as propriedades diretamente no objeto. Em seguida, passe o ODataDetailLevel objeto como um parâmetro para as várias operações de lista, como ListPools, ListJobs e ListTasks.

O trecho de código a seguir usa a API .NET de lote para consultar o serviço de lote de forma eficiente para obter as estatísticas de um conjunto específico de pools. O usuário do lote tem pools de teste e produção. Os IDs do pool de testes são prefixados com "test" e os IDs do pool de produção são prefixados com "prod". myBatchClient é uma instância inicializada corretamente da classe BatchClient .

// First we need an ODATADetailLevel instance on which to set the filter, select,
// and expand clause strings
ODATADetailLevel detailLevel = new ODATADetailLevel();

// We want to pull only the "test" pools, so we limit the number of items returned
// by using a FilterClause and specifying that the pool IDs must start with "test"
detailLevel.FilterClause = "startswith(id, 'test')";

// To further limit the data that crosses the wire, configure the SelectClause to
// limit the properties that are returned on each CloudPool object to only
// CloudPool.Id and CloudPool.Statistics
detailLevel.SelectClause = "id, stats";

// Specify the ExpandClause so that the .NET API pulls the statistics for the
// CloudPools in a single underlying REST API call. Note that we use the pool's
// REST API element name "stats" here as opposed to "Statistics" as it appears in
// the .NET API (CloudPool.Statistics)
detailLevel.ExpandClause = "stats";

// Now get our collection of pools, minimizing the amount of data that is returned
// by specifying the detail level that we configured above
List<CloudPool> testPools =
    await myBatchClient.PoolOperations.ListPools(detailLevel).ToListAsync();

Gorjeta

Uma instância de ODATADetailLevel configurada com cláusulas Select e Expand também pode ser passada para métodos Get apropriados, como PoolOperations.GetPool, para limitar a quantidade de dados retornados.

Mapeamentos de REST em lote para API .NET

Os nomes de propriedade em cadeias de caracteres de filtro, seleção e expansão devem refletir suas contrapartes da API REST, tanto em nome quanto em maiúsculas e minúsculas. As tabelas abaixo fornecem mapeamentos entre as contrapartes da API .NET e REST.

Mapeamentos para cadeias de caracteres de filtro

  • Métodos de lista do .NET: Cada um dos métodos da API do .NET nesta coluna aceita um objeto ODATADetailLevel como parâmetro.
  • Solicitações de lista REST: cada página da API REST listada nesta coluna contém uma tabela com as propriedades e operações permitidas em cadeias de caracteres de filtro. Você pode usar esses nomes de propriedade e operações ao construir uma cadeia de caracteres ODATADetailLevel.FilterClause .
Métodos de lista .NET Solicitações de lista REST
CertificateOperations.ListCertificates Listar os certificados em uma conta
CloudTask.ListNodeFiles Listar os arquivos associados a uma tarefa
JobOperations.ListJobPreparationAndReleaseTaskStatus Listar o status das tarefas de preparação e liberação de trabalho para um trabalho
JobOperations.ListJobs Listar os trabalhos em uma conta
JobOperations.ListNodeFiles Listar os arquivos em um nó
JobOperations.ListTasks Listar as tarefas associadas a um trabalho
JobScheduleOperations.ListJobSchedules Listar as agendas de trabalho em uma conta
JobScheduleOperations.ListJobs Listar os trabalhos associados a uma agenda de trabalhos
PoolOperations.ListComputeNodes Listar os nós de computação em um pool
PoolOperations.ListPools Listar os pools em uma conta

Mapeamentos para cadeias de caracteres selecionadas

  • Tipos .NET em lote: tipos de API .NET em lote.
  • Entidades da API REST: cada página nesta coluna contém uma ou mais tabelas que listam os nomes das propriedades da API REST para o tipo. Esses nomes de propriedade são usados quando você constrói cadeias de caracteres de seleção . Você usa esses mesmos nomes de propriedade quando constrói uma cadeia de caracteres ODATADetailLevel.SelectClause .
Tipos .NET em lote Entidades da API REST
Certificado Obter informações sobre um certificado
CloudJob Obter informações sobre uma vaga
CloudJobSchedule Obter informações sobre um cronograma de trabalho
ComputeNode Obter informações sobre um nó
CloudPool Obter informações sobre uma piscina
CloudTask Obter informações sobre uma tarefa

Exemplo: construir uma cadeia de caracteres de filtro

Para construir uma cadeia de caracteres de filtro para ODATADetailLevel.FilterClause, localize a página REST API correspondente. As propriedades selecionáveis e seus operadores suportados estão na primeira tabela de várias linhas. Por exemplo, para recuperar todas as tarefas cujo código de saída era diferente de zero, marque Listar as tarefas associadas a um trabalho para a cadeia de caracteres de propriedade aplicável e operadores permitidos:

Property Operações permitidas Type
executionInfo/exitCode eq, ge, gt, le , lt Int

A cadeia de caracteres de filtro relacionada é:

(executionInfo/exitCode lt 0) or (executionInfo/exitCode gt 0)

Exemplo: construir uma string de seleção

Para construir ODATADetailLevel.SelectClause, localize a página da API REST correspondente para a entidade que você está listando. As propriedades selecionáveis e seus operadores suportados estão na primeira tabela de várias linhas. Por exemplo, para recuperar apenas a ID e a linha de comando de cada tarefa em uma lista, marque Obter informações sobre uma tarefa:

Propriedade Type Notas
id String The ID of the task.
commandLine String The command line of the task.

A seqüência de seleção relacionada é:

id, commandLine

Amostras de código

Consultas de lista eficientes

O projeto de exemplo EfficientListQueries mostra como a consulta de lista eficiente afeta o desempenho do aplicativo. Este aplicativo de console C# cria e adiciona um grande número de tarefas a um trabalho. Em seguida, o aplicativo faz várias chamadas para o método JobOperations.ListTasks e passa objetos ODATADetailLevel . Esses objetos são configurados com diferentes valores de propriedade para variar a quantidade de dados a serem retornados. Este exemplo produz resultados semelhantes a:

Adding 5000 tasks to job jobEffQuery...
5000 tasks added in 00:00:47.3467587, hit ENTER to query tasks...

4943 tasks retrieved in 00:00:04.3408081 (ExpandClause:  | FilterClause: state eq 'active' | SelectClause: id,state)
0 tasks retrieved in 00:00:00.2662920 (ExpandClause:  | FilterClause: state eq 'running' | SelectClause: id,state)
59 tasks retrieved in 00:00:00.3337760 (ExpandClause:  | FilterClause: state eq 'completed' | SelectClause: id,state)
5000 tasks retrieved in 00:00:04.1429881 (ExpandClause:  | FilterClause:  | SelectClause: id,state)
5000 tasks retrieved in 00:00:15.1016127 (ExpandClause:  | FilterClause:  | SelectClause: id,state,environmentSettings)
5000 tasks retrieved in 00:00:17.0548145 (ExpandClause: stats | FilterClause:  | SelectClause: )

Sample complete, hit ENTER to continue...

O exemplo mostra que você pode reduzir muito os tempos de resposta da consulta limitando as propriedades e o número de itens retornados. Você pode encontrar este e outros projetos de exemplo no repositório azure-batch-samples no GitHub.

Biblioteca BatchMetrics

O projeto de exemplo BatchMetrics a seguir demonstra como monitorar com eficiência o progresso do trabalho do Azure Batch usando a API Batch.

Este exemplo inclui um projeto de biblioteca de classes .NET, que você pode incorporar em seus próprios projetos. Há também um programa de linha de comando simples para exercitar e demonstrar o uso da biblioteca.

O aplicativo de exemplo dentro do projeto demonstra estas operações:

  • Seleção de atributos específicos para baixar apenas as propriedades necessárias
  • Filtrar os tempos de transição de estado para baixar apenas as alterações desde a última consulta

Por exemplo, o método a seguir aparece na biblioteca BatchMetrics. Ele retorna um ODATADetailLevel que especifica que somente as id propriedades e state devem ser obtidas para as entidades consultadas. Também especifica que apenas as entidades cujo estado foi alterado desde o parâmetro especificado DateTime devem ser retornadas.

internal static ODATADetailLevel OnlyChangedAfter(DateTime time)
{
    return new ODATADetailLevel(
        selectClause: "id, state",
        filterClause: string.Format("stateTransitionTime gt DateTime'{0:o}'", time)
    );
}

Próximos passos