Creare query per elencare le risorse di Batch in modo efficiente

Viene illustrato come migliorare le prestazioni dell'applicazione Azure Batch, riducendo la quantità di dati restituiti dal servizio quando si eseguono query su processi, attività e nodi di calcolo con la libreria Batch .NET.

Quasi tutte le applicazioni Batch devono eseguire un tipo di monitoraggio o un'altra operazione che esegue query sul servizio Batch, spesso a intervalli regolari. Per determinare ad esempio se sono ancora presenti attività in coda in un processo, è necessario ottenere dati per ogni attività nel processo. Per determinare lo stato dei nodi nel pool è necessario ottenere dati in ogni nodo nel pool. Questo articolo illustra come eseguire queste query nel modo più efficiente.

Nota

Il servizio Batch fornisce supporto speciale delle API per lo scenario comune di conteggio delle attività in un processo. Invece di usare una query di tipo elenco a questo scopo, è possibile chiamare l'operazione di recupero del conteggio delle attività. Questa operazione restituisce il numero di attività in sospeso, in esecuzione o completate, nonché di quelle riuscite e non riuscite. L'operazione di recupero dei conteggi delle attività è più efficiente di una query di tipo elenco. Per altre informazioni, vedere Conteggiare le attività per un processo in base allo stato (anteprima).

Questa operazione non è disponibile nelle versioni del servizio Batch precedenti alla 2017-06-01.5.1. Se si usa una versione meno recente del servizio, usare una query di tipo elenco per conteggiare le attività in un processo.

Definire livelli di dettaglio

In un'applicazione Batch di produzione, le entità da elaborare, ad esempio processi, attività e nodi di calcolo, possono essere migliaia. Quando si richiedono informazioni su queste risorse, una grande quantità di dati deve "transitare" dal servizio Batch all'applicazione in ogni query. Limitando il numero di elementi e il tipo di informazioni restituiti da una query, è possibile aumentarne la velocità e quindi migliorare le prestazioni dell'applicazione.

Questo frammento di codice dell'API Batch .NET elenca ogni attività associata a un processo, insieme a tutte le proprietà dell'attività:

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

È possibile eseguire una query di tipo elenco molto più efficiente, tuttavia, applicando un "livello di dettaglio" alla query. A questo scopo, indicare un oggetto ODATADetailLevel al metodo JobOperations.ListTasks. Questo frammento restituisce solo l'ID, la riga di comando e informazioni sulle proprietà del nodo di calcolo delle attività completate:

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

Se in questo scenario di esempio il processo include migliaia di attività, il risultato della seconda query viene in genere restituito molto più rapidamente della prima. Di seguitosono disponibili altre informazioni sull'uso di ODATADetailLevel quando si elencano elementi con l'API Batch .NET.

Importante

È consigliabile specificare sempre un oggetto ODATADetailLevel per le chiamate di tipo elenco all'API .NET, per assicurare il massimo livello di efficienza e prestazioni dell'applicazione. Specificando un livello di dettaglio è possibile ridurre i tempi di risposta del servizio Batch, migliorare l'utilizzo della rete e ridurre l'utilizzo di memoria da parte delle applicazioni client.

Filtro, selezione ed espansione

Le API Batch .NET e Batch REST consentono di ridurre sia il numero di elementi restituiti in un elenco sia la quantità di informazioni restituite per ogni elemento. A questo scopo, specificare stringhe di filtro, selezione ed espansione quando si eseguono query di tipo elenco.

Filtro

La stringa di filtro è un'espressione che riduce il numero di elementi restituiti. Ad esempio, elencare solo le attività in esecuzione per un processo o solo i nodi di calcolo pronti per eseguire attività.

  • Una stringa di filtro è costituita da una o più espressioni, ciascuna delle quali è composta da un nome di proprietà, un operatore e un valore. Le proprietà che è possibile immettere sono specifiche di ogni tipo di entità su cui viene eseguita la query, come lo sono gli operatori supportati per ogni proprietà.
  • È possibile combinare più espressioni usando gli operatori logici and e or.
  • Questo esempio di stringa di filtro indica solo le attività di "rendering" in esecuzione: (state eq 'running') and startswith(id, 'renderTask').

Selezionare

La stringa di selezione limita i valori della proprietà restituiti per ogni elemento. Si specifica un elenco di nomi di proprietà e vengono restituiti solo i valori di quelle proprietà per gli elementi nei risultati della query.

  • La stringa di selezione è costituita da un elenco con valori delimitati da virgole di nomi di proprietà. È possibile specificare qualsiasi proprietà per il tipo di entità su cui si esegue la query.
  • Questa stringa di selezione di esempio specifica che dovranno essere restituiti solo i valori di tre proprietà per ogni attività: id, state, stateTransitionTime.

Espandere

La stringa di espansione riduce il numero di chiamate API richieste per ottenere determinate informazioni. Quando si usa una stringa di espansione, si possono ottenere altre informazioni su ogni elemento con una singola chiamata API. Invece di ottenere prima l'elenco delle entità e quindi richiedere informazioni per ogni elemento nell'elenco, usare una stringa di espansione per ottenere le stesse informazioni in una singola chiamata API. Meno chiamate API significano prestazioni migliori.

  • Analogamente alla stringa di selezione, la stringa di espansione controlla se determinati dati sono inclusi nei risultati di una query di tipo elenco.
  • La stringa di espansione è supportata solo quando viene usata nell'elenco di processi, pianificazioni di processi, attività e pool. Attualmente supporta solo informazioni statistiche.
  • Quando tutte le proprietà sono obbligatorie e non è stata specificata alcuna stringa di selezione, è necessario usare la stringa di espansione per ottenere informazioni statistiche. Se si usa una stringa di selezione per ottenere un subset di proprietà, è possibile specificare stats nella stringa di selezione e non è necessario specificare la stringa di espansione.
  • Questo esempio di stringa di espansione specifica che dovranno essere restituite informazioni statistiche per ogni elemento nell'elenco: stats.

Nota

Quando si costruisce uno qualsiasi dei tre tipi di stringhe di query, ovvero filtro, selezione ed espansione, è necessario assicurarsi che i nomi delle proprietà e le lettere maiuscole/minuscole corrispondano alle relative controparti nell'API REST. Ad esempio, quando si usa la classe CloudTask .NET, è necessario specificare state invece di State, anche se la proprietà .NET è CloudTask.State. Per i mapping delle proprietà tra le API .NET e REST, vedere le tabelle seguenti.

Regole per le stringhe di filtro, selezione ed espansione

  • I nomi delle proprietà nelle stringhe di filtro, selezione ed espansione devono corrispondere a quelli presenti nell'API Batch REST anche quando si usa Batch .NET o uno degli altri SDK di Batch.
  • Per tutti i nomi di proprietà viene fatta distinzione tra maiuscole e minuscole, al contrario di quanto avviene per i valori delle proprietà.
  • Le stringhe relative a data/ora possono essere indicate in uno dei due formati seguenti e devono essere precedute da DateTime.

    • Esempio di formato W3C-DTF: creationTime gt DateTime'2011-05-08T08:49:37Z'
    • Esempio di formato RFC 1123: creationTime gt DateTime'Sun, 08 May 2011 08:49:37 GMT'
  • Le stringhe booleane sono true o false.
  • Se si specifica una proprietà o un operatore non valido, viene generato un errore 400 (Bad Request) .

Esecuzione efficiente di query in Batch .NET

Nell'API Batch .NET viene usata la classe ODATADetailLevel per specificare le stringhe di filtro, selezione ed espansione alle operazioni di tipo elenco. La classe ODataDetailLevel presenta tre proprietà pubbliche di tipo stringa che possono essere specificate nel costruttore o impostate direttamente: L'oggetto ODataDetailLevel viene quindi passato come parametro alle diverse operazioni di tipo elenco, ad esempio ListPools, ListJobs e ListTasks.

Il frammento di codice seguente usa l'API Batch .NET per eseguire query efficienti sul servizio Batch per ottenere le statistiche di un set di pool specificato. In questo scenario l'utente Batch ha pool di test e di produzione. Gli ID del pool di test sono preceduti da "test", mentre quelli del pool di produzione sono preceduti da "prod". Nel frammento di codice myBatchClient è un'istanza della classe BatchClient inizializzata correttamente.

// 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();

Suggerimento

È anche possibile passare un'istanza di ODATADetailLevel configurata con le clausole Select ed Expand ai metodi Get appropriati, ad esempio PoolOperations.GetPool, per limitare la quantità di dati restituiti.

Mapping di API Batch REST a API .NET

I nomi delle proprietà nelle stringhe di filtro, selezione ed espansione devono riflettere le rispettive controparti dell'API REST, sia a livello di nome che di lettere maiuscole/minuscole. Le tabelle seguenti forniscono i mapping tra l'API .NET e le relative controparti dell'API REST.

Mapping per le stringhe di filtro

  • Metodi list .NET: ogni metodo dell'API .NET in questa colonna accetta un oggetto ODATADetailLevel come parametro.
  • Richieste list REST: ogni pagina dell'API REST collegata in questa colonna contiene una tabella che specifica le proprietà e le operazioni consentite nelle stringhe di filtro . Questi nomi di proprietà e queste operazioni verranno usati per costruire una stringa ODATADetailLevel.FilterClause.
Metodi list .NET Richieste list REST
CertificateOperations.ListCertificates Elencare i certificati in un account
CloudTask.ListNodeFiles Elencare i file associati a un'attività
JobOperations.ListJobPreparationAndReleaseTaskStatus Elencare lo stato della preparazione e le attività di rilascio per un processo specifico
JobOperations.ListJobs Elencare i processi in un account
JobOperations.ListNodeFiles Elencare i file in un nodo
JobOperations.ListTasks Elencare le attività associate a un processo
JobScheduleOperations.ListJobSchedules Elencare le pianificazioni di processi in un account
JobScheduleOperations.ListJobs Elencare i processi associati a una pianificazione di processi
PoolOperations.ListComputeNodes Elencare i nodi di calcolo in un pool
PoolOperations.ListPools Elencare i pool in un account

Mapping per le stringhe di selezione

  • Tipi di Batch .NET: tipi di API Batch .NET.
  • Entità di API REST: ogni pagina di questa colonna contiene una o più tabelle che indicano i nomi delle proprietà dell'API REST per il tipo. Questi nomi di proprietà vengono usati per la costruzione di stringhe di selezione . Questi stessi nomi di proprietà verranno usati per costruire una stringa ODATADetailLevel.SelectClause.
Tipi di Batch .NET Entità di API REST
Certificate Ottenere informazioni su un certificato
CloudJob Ottenere informazioni su un processo
CloudJobSchedule Ottenere informazioni su una pianificazione di processi
ComputeNode Ottenere informazioni su un nodo
CloudPool Ottenere informazioni su un pool
CloudTask Ottenere informazioni su un'attività

Esempio: costruire una stringa di filtro

Quando si costruisce una stringa di filtro per un oggetto ODATADetailLevel.FilterClause, vedere la tabella in "Mapping per le stringhe di filtro" per trovare la pagina di documentazione dell'API REST corrispondente all'operazione di tipo elenco da eseguire. Le proprietà filtrabili e gli operatori supportati sono disponibili nella prima tabella con più righe in quella pagina. Per recuperare ad esempio tutte le attività il cui codice di uscita non è pari a zero, questa riga in Elencare le attività associate a un processo specifica la stringa della proprietà applicabile e gli operatori consentiti:

Proprietà Operazioni consentite Tipo
executionInfo/exitCode eq, ge, gt, le , lt Int

La stringa di filtro per elencare tutte le attività con un codice di uscita non pari a zero sarà:

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

Esempio: costruire una stringa di selezione

Per costruire una stringa ODATADetailLevel.SelectClause, vedere la tabella in "Mapping per le stringhe di selezione" e passare alla pagina dell'API REST che corrisponde al tipo di entità da specificare. Le proprietà selezionabili e gli operatori supportati sono disponibili nella prima tabella con più righe in quella pagina. Se ad esempio si desidera recuperare solo l'ID e la riga di comando per ogni attività in un elenco, queste righe si trovano nella tabella applicabile in Ottenere informazioni su un'attività:

Proprietà Tipo Note
id String The ID of the task.
commandLine String The command line of the task.

La stringa di selezione per includere solo l'ID e la riga di comando con ogni attività elencata sarà:

id, commandLine

Esempi di codice

Esempio di codice per query di elenco efficienti

Per verificare il modo in cui una query di tipo elenco può influire efficacemente sulle prestazioni in un'applicazione, vedere il progetto di esempio EfficientListQueries in GitHub. Questa applicazione console C# crea e aggiunge un numero elevato di attività a un processo. Esegue quindi più chiamate al metodo JobOperations.ListTasks e passa gli oggetti ODATADetailLevel configurati con valori di proprietà diversi per variare la quantità di dati da restituire. L'output generato sarà simile al seguente:

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...

Come illustrato nelle informazioni sul tempo trascorso, è possibile ridurre notevolmente i tempi di risposta della query limitando le proprietà e il numero di elementi restituiti. Questo e altri progetti di esempio sono disponibili nel repository azure-batch-samples in GitHub.

Libreria BatchMetrics ed esempio di codice

Oltre all'esempio di codice EfficientListQueries precedente, è possibile trovare il progetto BatchMetrics nel repository azure-batch-samples in GitHub. Il progetto di esempio BatchMetrics illustra come monitorare in modo efficiente lo stato dei processi di Azure Batch con l'API di Batch.

L'esempio BatchMetrics include un progetto di libreria di classi .NET che è possibile incorporare nei propri progetti e un semplice programma della riga di comando per apprendere l'uso della libreria.

L'applicazione di esempio nel progetto illustra le operazioni seguenti:

  1. Selezione degli attributi specifici per scaricare solo le proprietà necessarie
  2. Filtro delle ore di transizione allo stato per scaricare solo le modifiche apportate dopo l'ultima query

Ad esempio, il metodo seguente è presente nella libreria BatchMetrics. Restituisce un elemento ODATADetailLevel che specifica che dovranno essere ottenute solo le proprietà id e state per le entità sulle quali viene eseguita una query. Specifica anche che dovranno essere restituite solo le entità il cui stato è stato modificato dopo il parametro DateTime specificato.

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

Passaggi successivi

Attività parallele sui nodi

Ottimizzare l'utilizzo delle risorse di calcolo di Azure Batch con attività dei nodi simultanee è un altro articolo correlato alle prestazioni per l'applicazione Batch. Alcuni tipi di carichi di lavoro possono trarre vantaggio dall'esecuzione di attività in parallelo su nodi di calcolo più grandi, ma in numero inferiore. Vedere lo scenario di esempio nell'articolo per informazioni dettagliate su questo scenario.

Forum di Batch

Il forum di Azure Batch su MSDN consente di seguire discussioni su Batch e inviare domande sul servizio. Leggere i post contrassegnati e inviare domande durante le procedure di sviluppo delle soluzioni Batch.