Analisar o desempenho na Pesquisa de IA do Azure

Este artigo descreve as ferramentas, comportamentos e abordagens para analisar o desempenho da consulta e da indexação no Azure AI Search.

Desenvolver números de linha de base

Em qualquer implementação grande, é fundamental fazer um teste de benchmarking de desempenho do seu serviço Azure AI Search antes de colocá-lo em produção. Você deve testar a carga de consulta de pesquisa esperada, mas também as cargas de trabalho de ingestão de dados esperadas (se possível, execute ambas as cargas de trabalho simultaneamente). Ter números de referência ajuda a validar a camada de pesquisa adequada, a configuração do serviço e a latência de consulta esperada.

Para desenvolver benchmarks, recomendamos a ferramenta azure-search-performance-testing (GitHub).

Para isolar os efeitos de uma arquitetura de serviço distribuído, tente testar as configurações de serviço de uma réplica e uma partição.

Nota

Para os níveis otimizados para armazenamento (L1 e L2), você deve esperar uma taxa de transferência de consulta menor e latência mais alta do que os níveis Standard.

Usar o log de recursos

A ferramenta de diagnóstico mais importante à disposição de um administrador é o registro de recursos. O registo de recursos é a recolha de dados operacionais e métricas sobre o seu serviço de pesquisa. O registo de recursos está ativado através do Azure Monitor. Há custos associados ao uso do Azure Monitor e ao armazenamento de dados, mas se você habilitá-lo para seu serviço, ele poderá ser fundamental na investigação de problemas de desempenho.

A imagem a seguir mostra a cadeia de eventos em uma solicitação e resposta de consulta. A latência pode ocorrer em qualquer um deles, seja durante uma transferência de rede, processamento de conteúdo na camada de serviços de aplicativo ou em um serviço de pesquisa. Um dos principais benefícios do log de recursos é que as atividades são registradas da perspetiva do serviço de pesquisa, o que significa que o log pode ajudá-lo a determinar se o problema de desempenho é devido a problemas com a consulta ou indexação, ou algum outro ponto de falha.

Chain of logged events

O registo de recursos dá-lhe opções para armazenar informações registadas. Recomendamos o uso do Log Analytics para que você possa executar consultas Kusto avançadas em relação aos dados para responder a muitas perguntas sobre uso e desempenho.

Nas páginas do portal do serviço de pesquisa, você pode habilitar o registro em log por meio das configurações de diagnóstico e, em seguida, emitir consultas Kusto no Log Analytics escolhendo Logs. Para obter mais informações sobre como configurar, consulte Coletar e analisar dados de log.

Logging menu options

Comportamentos de limitação

A limitação ocorre quando o serviço de pesquisa está na capacidade. A limitação pode ocorrer durante consultas ou indexação. Do lado do cliente, uma chamada de API resulta em uma resposta HTTP 503 quando ela foi limitada. Durante a indexação, há também a possibilidade de receber uma resposta HTTP 207, que indica que um ou mais itens não foram indexados. Este erro é um indicador de que o serviço de pesquisa está a aproximar-se da capacidade.

Como regra geral, tente quantificar a quantidade de limitação e quaisquer padrões. Por exemplo, se uma consulta de pesquisa de 500.000 for limitada, talvez não valha a pena investigar. No entanto, se uma grande percentagem de consultas for limitada ao longo de um período, esta seria uma preocupação maior. Ao analisar a limitação ao longo de um período, também ajuda a identificar períodos de tempo em que a limitação pode ocorrer mais provavelmente e ajuda a decidir a melhor forma de acomodar isso.

Uma correção simples para a maioria dos problemas de limitação é lançar mais recursos no serviço de pesquisa (normalmente réplicas para limitação baseada em consulta ou partições para limitação baseada em indexação). No entanto, aumentar réplicas ou partições aumenta o custo, e é por isso que é importante saber o motivo pelo qual a limitação está ocorrendo. A investigação das condições que causam a limitação será explicada nas próximas seções.

Abaixo está um exemplo de uma consulta Kusto que pode identificar o detalhamento de respostas HTTP do serviço de pesquisa que esteve sob carga. Durante um período de 7 dias, o gráfico de barras renderizado mostra que uma porcentagem relativamente grande das consultas de pesquisa foram limitadas, em comparação com o número de respostas bem-sucedidas (200).

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

Bar chart of http error counts

Examinar a limitação durante um período de tempo específico pode ajudá-lo a identificar os momentos em que a limitação pode ocorrer com mais frequência. No exemplo abaixo, um gráfico de séries temporais é usado para mostrar o número de consultas limitadas que ocorreram em um período de tempo especificado. Neste caso, as consultas limitadas correlacionaram-se com os tempos em que o benchmarking de desempenho foi realizado.

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

Medir consultas individuais

Em alguns casos, pode ser útil testar consultas individuais para ver o seu desempenho. Para fazer isso, é importante ser capaz de ver quanto tempo o serviço de pesquisa leva para concluir o trabalho, bem como quanto tempo leva para fazer o pedido de ida e volta do cliente e voltar para o cliente. Os logs de diagnóstico podem ser usados para procurar operações individuais, mas pode ser mais fácil fazer tudo isso a partir de um cliente REST.

No exemplo abaixo, uma consulta de pesquisa baseada em REST foi executada. O Azure AI Search inclui em cada resposta o número de milissegundos necessários para concluir a consulta, visível na guia Cabeçalhos, em "tempo decorrido". Ao lado de Status na parte superior da resposta, você encontrará a duração da viagem de ida e volta, neste caso, 418 milissegundos (ms). Na seção de resultados, a guia "Cabeçalhos" foi escolhida. Usando esses dois valores, destacados com uma caixa vermelha na imagem abaixo, vemos que o serviço de pesquisa levou 21 ms para concluir a consulta de pesquisa e toda a solicitação de ida e volta do cliente levou 125 ms. Subtraindo estes dois números, podemos determinar que demorou 104 ms de tempo adicional para transmitir a consulta de pesquisa para o serviço de pesquisa e transferir os resultados da pesquisa de volta para o cliente.

Essa técnica ajuda a isolar as latências de rede de outros fatores que afetam o desempenho da consulta.

Query duration metrics

Taxas de consulta

Uma razão potencial para o seu serviço de pesquisa limitar as solicitações é devido ao grande número de consultas que estão sendo realizadas onde o volume é capturado como consultas por segundo (QPS) ou consultas por minuto (QPM). À medida que seu serviço de pesquisa recebe mais QPS, normalmente levará cada vez mais tempo para responder a essas consultas até que não possa mais acompanhar, pois enviará de volta uma resposta HTTP 503 limitada.

A consulta Kusto a seguir mostra o volume de consulta medido no QPM, juntamente com a duração média de uma consulta em milissegundos (AvgDurationMS) e o número médio de documentos (AvgDocCountReturned) retornados em cada um.

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

Gorjeta

Para revelar os dados por trás desse gráfico, remova a linha | render timechart e execute novamente a consulta.

Impacto da indexação nas consultas

Um fator importante a considerar ao analisar o desempenho é que a indexação usa os mesmos recursos que as consultas de pesquisa. Se você estiver indexando uma grande quantidade de conteúdo, pode esperar ver a latência aumentar à medida que o serviço tenta acomodar ambas as cargas de trabalho.

Se as consultas estiverem ficando mais lentas, observe o tempo da atividade de indexação para ver se ela coincide com a degradação da consulta. Por exemplo, talvez um indexador esteja executando um trabalho diário ou por hora que se correlaciona com a diminuição do desempenho das consultas de pesquisa.

Esta seção fornece um conjunto de consultas que podem ajudá-lo a visualizar as taxas de pesquisa e indexação. Para esses exemplos, o intervalo de tempo é definido na consulta. Certifique-se de indicar Definir na consulta ao executar as consultas no portal do Azure.

Setting time ranges in the query tool

Latência média da consulta

Na consulta abaixo, um tamanho de intervalo de 1 minuto é usado para mostrar a latência média das consultas de pesquisa. Pelo gráfico, podemos ver que a latência média foi baixa até as 17h45 e durou até as 17h53.

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

Média de consultas por minuto (QPM)

A consulta a seguir examina o número médio de consultas por minuto para garantir que não houve um pico nas solicitações de pesquisa que possa ter afetado a latência. No gráfico, podemos ver que há alguma variância, mas nada que indique um pico na contagem de solicitações.

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

Operações de indexação por minuto (OPM)

Aqui veremos o número de operações de indexação por minuto. Pelo gráfico, podemos ver que uma grande quantidade de dados foi indexada começou às 17h42 e terminou às 17h50. Esta indexação começou 3 minutos antes de as consultas de pesquisa começarem a ficar latentes e terminou 3 minutos antes de as consultas de pesquisa deixarem de estar latentes.

A partir dessa perceção, podemos ver que levou cerca de 3 minutos para que o serviço de pesquisa ficasse ocupado o suficiente para que a indexação afetasse a latência da consulta. Também podemos ver que, após a conclusão da indexação, levou mais 3 minutos para que o serviço de pesquisa concluísse todo o trabalho do conteúdo recém-indexado e para que a latência da consulta fosse resolvida.

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

Processamento de serviço em segundo plano

Não é incomum ver picos periódicos na latência de consulta ou indexação. Os picos podem ocorrer em resposta à indexação ou a altas taxas de consulta, mas também podem ocorrer durante operações de mesclagem. Os índices de pesquisa são armazenados em partes - ou fragmentos. Periodicamente, o sistema mescla fragmentos menores em fragmentos grandes, o que pode ajudar a otimizar o desempenho do serviço. Esse processo de mesclagem também limpa documentos que foram marcados anteriormente para exclusão do índice, resultando na recuperação de espaço de armazenamento.

A fusão de fragmentos é rápida, mas também consome muitos recursos e, portanto, tem o potencial de degradar o desempenho do serviço. Se você notar pequenas explosões de latência de consulta e essas intermitências coincidirem com alterações recentes no conteúdo indexado, poderá presumir que a latência se deve a operações de mesclagem de estilhaços.

Próximos passos

Analise estes artigos relacionados à análise do desempenho do serviço.