Analizzare le prestazioni in Ricerca di intelligenza artificiale di Azure

Questo articolo descrive gli strumenti, i comportamenti e gli approcci per l'analisi delle prestazioni di query e indicizzazione in Ricerca di intelligenza artificiale di Azure.

Sviluppare numeri di base

In qualsiasi implementazione di grandi dimensioni, è fondamentale eseguire un test di benchmarking delle prestazioni del servizio di ricerca di intelligenza artificiale di Azure prima di eseguirne il rollback nell'ambiente di produzione. È consigliabile testare il carico delle query di ricerca previsto, ma anche i carichi di lavoro di inserimento dati previsti (se possibile, eseguire entrambi i carichi di lavoro contemporaneamente). La presenza di numeri di benchmark consente di convalidare il livello di ricerca, la configurazione del servizio e la latenza di query prevista.

Per sviluppare benchmark, è consigliabile usare lo strumento azure-search-performance-testing (GitHub).

Per isolare gli effetti di un'architettura del servizio distribuita, provare a testare le configurazioni del servizio di una replica e una partizione.

Nota

Per i livelli Ottimizzato per l'archiviazione (L1 e L2), sono previste una velocità effettiva delle query inferiore e una latenza superiore rispetto ai livelli Standard.

Usare la registrazione delle risorse

Lo strumento di diagnostica più importante a disposizione di un amministratore è la registrazione delle risorse. La registrazione delle risorse è la raccolta di dati operativi e metriche sul servizio di ricerca. La registrazione delle risorse è abilitata tramite Monitoraggio di Azure. Esistono costi associati all'uso di Monitoraggio di Azure e all'archiviazione dei dati, ma se si abilita per il servizio, può essere fondamentale per analizzare i problemi di prestazioni.

L'immagine seguente mostra la catena di eventi in una richiesta di query e una risposta. La latenza può verificarsi in uno qualsiasi di essi, sia durante un trasferimento di rete, l'elaborazione del contenuto nel livello dei servizi app o in un servizio di ricerca. Un vantaggio fondamentale della registrazione delle risorse è che le attività vengono registrate dal punto di vista del servizio di ricerca, il che significa che il log può essere utile per determinare se il problema di prestazioni è dovuto a problemi con la query o l'indicizzazione o un altro punto di errore.

Chain of logged events

La registrazione delle risorse offre opzioni per l'archiviazione delle informazioni registrate. È consigliabile usare Log Analytics in modo da poter eseguire query Kusto avanzate sui dati per rispondere a molte domande sull'utilizzo e sulle prestazioni.

Nelle pagine del portale del servizio di ricerca è possibile abilitare la registrazione tramite le impostazioni di diagnostica e quindi eseguire query Kusto su Log Analytics scegliendo Log. Per altre informazioni sulla configurazione, vedere Raccogliere e analizzare i dati di log.

Logging menu options

Comportamenti di limitazione

La limitazione si verifica quando il servizio di ricerca è alla capacità. La limitazione può verificarsi durante le query o l'indicizzazione. Dal lato client, una chiamata API genera una risposta HTTP 503 quando è stata limitata. Durante l'indicizzazione, è anche possibile ricevere una risposta HTTP 207, che indica che uno o più elementi non sono stati indicizzati. Questo errore è un indicatore che indica che il servizio di ricerca sta per raggiungere la capacità.

Come regola generale, cercare di quantificare la quantità di limitazione e qualsiasi modello. Ad esempio, se una query di ricerca su 500.000 è limitata, potrebbe non essere utile analizzare. Tuttavia, se una grande percentuale di query viene limitata per un periodo, si tratta di un problema maggiore. Esaminando la limitazione nel corso di un periodo, consente anche di identificare gli intervalli di tempo in cui la limitazione potrebbe verificarsi più probabilmente e aiutare a decidere come soddisfare al meglio tale problema.

Una semplice correzione alla maggior parte dei problemi di limitazione consiste nell'generare più risorse nel servizio di ricerca (in genere repliche per la limitazione basata su query o partizioni per la limitazione basata sull'indicizzazione). Tuttavia, l'aumento delle repliche o delle partizioni aggiunge costi, motivo per cui è importante conoscere il motivo per cui la limitazione si verifica affatto. L'analisi delle condizioni che causano la limitazione verrà illustrata nelle sezioni successive.

Di seguito è riportato un esempio di query Kusto che consente di identificare la suddivisione delle risposte HTTP dal servizio di ricerca sottoposto a caricamento. In un periodo di 7 giorni, il grafico a barre sottoposto a rendering mostra che una percentuale relativamente elevata delle query di ricerca è stata limitata, rispetto al numero di risposte riuscite (200).

AzureDiagnostics
| where TimeGenerated > ago(7d)
| summarize count() by resultSignature_d 
| render barchart 

Bar chart of http error counts

L'analisi della limitazione in un periodo di tempo specifico consente di identificare i tempi in cui la limitazione potrebbe verificarsi più frequentemente. Nell'esempio seguente viene usato un grafico time series per mostrare il numero di query limitate che si sono verificate in un intervallo di tempo specificato. In questo caso, le query limitate correlate ai tempi in cui è stato eseguito il benchmarking delle prestazioni.

let ['_startTime']=datetime('2021-02-25T20:45:07Z');
let ['_endTime']=datetime('2021-03-03T20:45:07Z');
let intervalsize = 1m; 
AzureDiagnostics 
| where TimeGenerated > ago(7d)
| where resultSignature_d != 403 and resultSignature_d != 404 and OperationName in ("Query.Search", "Query.Suggest", "Query.Lookup", "Query.Autocomplete")
| summarize 
  ThrottledQueriesPerMinute=bin(countif(OperationName in ("Query.Search", "Query.Suggest", "Query.Lookup", "Query.Autocomplete") and resultSignature_d == 503)/(intervalsize/1m), 0.01)
  by bin(TimeGenerated, intervalsize)
| render timechart   

Line chart of throttled queries

Misurare le singole query

In alcuni casi, può essere utile testare le singole query per vedere come vengono eseguite. A tale scopo, è importante essere in grado di vedere quanto tempo il servizio di ricerca richiede per completare il lavoro, nonché il tempo necessario per effettuare la richiesta di round trip dal client e tornare al client. I log di diagnostica possono essere usati per cercare le singole operazioni, ma potrebbe essere più semplice eseguire questa operazione da un client REST.

Nell'esempio seguente è stata eseguita una query di ricerca basata su REST. Ricerca di intelligenza artificiale di Azure include in ogni risposta il numero di millisecondi necessari per completare la query, visibile nella scheda Intestazioni, in "tempo trascorso". Accanto a Stato nella parte superiore della risposta, si troverà la durata del round trip, in questo caso 418 millisecondi (ms). Nella sezione risultati è stata scelta la scheda "Intestazioni". Usando questi due valori, evidenziati con una casella rossa nell'immagine seguente, si noterà che il servizio di ricerca ha richiesto 21 ms per completare la query di ricerca e l'intera richiesta di round trip del client ha richiesto 125 ms. Sottraendo questi due numeri è possibile determinare che sono necessari 104 ms di tempo aggiuntivo per trasmettere la query di ricerca al servizio di ricerca e per trasferire i risultati della ricerca al client.

Questa tecnica consente di isolare le latenze di rete da altri fattori che influiscono sulle prestazioni delle query.

Query duration metrics

Frequenze query

Un potenziale motivo per cui il servizio di ricerca limita le richieste è dovuto al numero maggiore di query eseguite in cui il volume viene acquisito come query al secondo (QPS) o query al minuto (QPM). Man mano che il servizio di ricerca riceve più QPS, in genere richiederà più tempo e più tempo per rispondere a tali query fino a quando non può più rimanere aggiornato, in quanto in quanto invierà una risposta HTTP di limitazione 503.

La query Kusto seguente mostra il volume di query misurato in QPM, insieme alla durata media di una query in millisecondi (AvgDurationMS) e al numero medio di documenti (AvgDocCountReturned) restituiti in ognuno di essi.

AzureDiagnostics
| where OperationName == "Query.Search" and TimeGenerated > ago(1d)
| extend MinuteOfDay = substring(TimeGenerated, 0, 16) 
| project MinuteOfDay, DurationMs, Documents_d, IndexName_s
| summarize QPM=count(), AvgDuractionMs=avg(DurationMs), AvgDocCountReturned=avg(Documents_d)  by MinuteOfDay
| order by MinuteOfDay desc 
| render timechart

Chart showing queries per minute

Suggerimento

Per visualizzare i dati dietro questo grafico, rimuovere la riga | render timechart e quindi eseguire di nuovo la query.

Impatto dell'indicizzazione sulle query

Un fattore importante da considerare quando si esaminano le prestazioni è che l'indicizzazione usa le stesse risorse delle query di ricerca. Se si esegue l'indicizzazione di una grande quantità di contenuto, è possibile prevedere un aumento della latenza man mano che il servizio tenta di gestire entrambi i carichi di lavoro.

Se le query rallentano, esaminare la tempistica dell'attività di indicizzazione per verificare se coincide con la riduzione delle prestazioni delle query. Ad esempio, un indicizzatore esegue un processo giornaliero o orario correlato alle prestazioni ridotte delle query di ricerca.

Questa sezione fornisce un set di query che consentono di visualizzare le frequenze di ricerca e indicizzazione. Per questi esempi, l'intervallo di tempo viene impostato nella query. Assicurarsi di indicare Imposta nella query durante l'esecuzione delle query in portale di Azure.

Setting time ranges in the query tool

Latenza media query

Nella query seguente viene usata una dimensione di intervallo di 1 minuto per mostrare la latenza media delle query di ricerca. Dal grafico è possibile osservare che la latenza media è stata bassa fino alle 17:45 e fino alle 17:53.

let intervalsize = 1m; 
let _startTime = datetime('2021-02-23 17:40');
let _endTime = datetime('2021-02-23 18:00');
AzureDiagnostics
| where TimeGenerated between(['_startTime']..['_endTime']) // Time range filtering
| summarize AverageQueryLatency = avgif(DurationMs, OperationName in ("Query.Search", "Query.Suggest", "Query.Lookup", "Query.Autocomplete"))
    by bin(TimeGenerated, intervalsize)
| render timechart

Chart showing average query latency

Numero medio di query al minuto

La query seguente esamina il numero medio di query al minuto per assicurarsi che non si sia verificato un picco nelle richieste di ricerca che potrebbero avere influenzato la latenza. Dal grafico è possibile osservare che c'è una varianza, ma nulla per indicare un picco nel conteggio delle richieste.

let intervalsize = 1m; 
let _startTime = datetime('2021-02-23 17:40');
let _endTime = datetime('2021-02-23 18:00');
AzureDiagnostics
| where TimeGenerated between(['_startTime'] .. ['_endTime']) // Time range filtering
| summarize QueriesPerMinute=bin(countif(OperationName in ("Query.Search", "Query.Suggest", "Query.Lookup", "Query.Autocomplete"))/(intervalsize/1m), 0.01)
  by bin(TimeGenerated, intervalsize)
| render timechart

Chart showing average queries per minute

Operazioni di indicizzazione al minuto

Di seguito verrà esaminato il numero di operazioni di indicizzazione al minuto. Dal grafico è possibile notare che una grande quantità di dati è stata indicizzata alle 17:42 e terminata alle 17:50. L'indicizzazione è iniziata 3 minuti prima che le query di ricerca iniziassero a diventare latenti e terminassero 3 minuti prima che le query di ricerca non fossero più latenti.

Da queste informazioni dettagliate è possibile notare che sono trascorsi circa 3 minuti prima che il servizio di ricerca diventi sufficientemente occupato per l'indicizzazione per influire sulla latenza delle query. È anche possibile notare che, dopo aver completato l'indicizzazione, il servizio di ricerca ha richiesto altri 3 minuti per completare tutto il lavoro dal contenuto appena indicizzato e per la latenza delle query da risolvere.

let intervalsize = 1m; 
let _startTime = datetime('2021-02-23 17:40');
let _endTime = datetime('2021-02-23 18:00');
AzureDiagnostics
| where TimeGenerated between(['_startTime'] .. ['_endTime']) // Time range filtering
| summarize IndexingOperationsPerSecond=bin(countif(OperationName == "Indexing.Index")/ (intervalsize/1m), 0.01)
  by bin(TimeGenerated, intervalsize)
| render timechart 

Chart showing indexing operations per minute

Elaborazione del servizio in background

Non è insolito vedere picchi periodici nella latenza di query o indicizzazione. I picchi possono verificarsi in risposta all'indicizzazione o a frequenze di query elevate, ma possono verificarsi anche durante le operazioni di merge. Gli indici di ricerca vengono archiviati in blocchi o partizioni. Periodicamente, il sistema unisce partizioni più piccole in partizioni di grandi dimensioni, che consentono di ottimizzare le prestazioni del servizio. Questo processo di merge pulisce anche i documenti contrassegnati in precedenza per l'eliminazione dall'indice, con conseguente ripristino dello spazio di archiviazione.

L'unione di partizioni è veloce, ma anche un uso intensivo delle risorse e quindi può compromettere le prestazioni del servizio. Se si notano brevi picchi di latenza di query e tali burst coincidono con le modifiche recenti al contenuto indicizzato, è possibile presupporre che la latenza sia dovuta a operazioni di merge partizioni.

Passaggi successivi

Esaminare questi articoli relativi all'analisi delle prestazioni del servizio.