Guia de Desempenho de Indexação no Elasticsearch: Melhores Práticas Reveladas
Melhore a indexação do Elasticsearch com solicitações em lote, ajuste de refresh e réplicas, escolhas de mapeamento, verificações de hardware e planejamento de shards.
Guia de Desempenho de Indexação no Elasticsearch: Melhores Práticas Reveladas
O desempenho da indexação no Elasticsearch torna-se visível quando seu pipeline de ingestão começa a acumular, solicitações em lote são rejeitadas ou as buscas ficam lentas durante gravações pesadas. A correção raramente é uma configuração mágica; você precisa ajustar o tamanho da solicitação, o comportamento de refresh, os mapeamentos, o layout dos shards e o hardware em conjunto.
Este guia foca em verificações práticas de desempenho de indexação no Elasticsearch que você pode aplicar antes e durante um grande trabalho de ingestão. Use-as com métricas do seu próprio cluster, pois o tamanho do documento, analisadores, armazenamento e número de réplicas podem alterar o resultado.
Entendendo o Processo de Indexação
Antes de mergulhar na otimização, é essencial entender como o Elasticsearch lida com a indexação. Quando um documento é indexado, o Elasticsearch realiza várias operações: análise do documento, análise dos campos (tokenização, stemming, etc.) e, em seguida, armazenamento do índice invertido e outras estruturas de dados. Essas operações, especialmente análise e I/O de disco, são intensivas em CPU e I/O. Em um ambiente distribuído, essas operações são tratadas por nós individuais, tornando a configuração em todo o cluster e os recursos do nó críticos.
Fatores Chave que Influenciam a Velocidade de Indexação
Vários fatores podem impactar significativamente a rapidez com que o Elasticsearch pode indexar documentos:
- Recursos de Hardware: CPU, RAM e, especialmente, a velocidade de I/O do disco são primordiais. SSDs são altamente recomendados em vez de HDDs por seu desempenho superior de leitura/gravação.
- Configuração do Cluster: A alocação de shards, as configurações de replicação e as funções dos nós desempenham um papel.
- Estratégia de Indexação: O método usado para enviar dados (por exemplo, solicitações de documento único vs. API em lote).
- Mapeamento e Tipos de Dados: Como seus campos são definidos e seus tipos de dados correspondentes.
- Intervalo de Refresh: Com que frequência os dados se tornam visíveis para pesquisa.
- Configurações do Translog: Configurações de durabilidade para gravações confirmadas.
Otimizando o Desempenho da Indexação: Melhores Práticas
Esta seção cobre estratégias acionáveis para melhorar sua taxa de transferência de indexação no Elasticsearch.
1. Aproveite a API Bulk
A otimização mais fundamental para indexação é usar a API Bulk. Em vez de enviar solicitações de indexação individuais, que incorrem em sobrecarga de rede e custo de processamento por solicitação, a API Bulk permite que você envie uma lista de operações (indexar, criar, atualizar, excluir) em uma única solicitação HTTP. Isso reduz significativamente a latência da rede e melhora a taxa de transferência geral.
Melhores Práticas para a API Bulk:
- Tamanho do Lote: Experimente com tamanhos de lote. Comece com cargas úteis modestas e aumente enquanto observa a latência de indexação, pressão de memória e rejeições
429. A contagem de documentos sozinha não é suficiente porque um documento pode ser minúsculo e outro pode ter vários megabytes. - Concorrência: Use múltiplas threads ou clientes assíncronos para enviar solicitações em lote simultaneamente. No entanto, evite sobrecarregar seu cluster. Monitore o uso de CPU e I/O para encontrar o ponto ideal.
- Tratamento de Erros: Implemente um tratamento de erros robusto. A API Bulk retorna um array de respostas, e você precisa verificar o status de cada operação.
Exemplo de Solicitação Bulk:
{ "index": { "_index": "my-index", "_id": "1" } }
{ "field1": "value1", "field2": "value2" }
{ "index": { "_index": "my-index", "_id": "2" } }
{ "field1": "value3", "field2": "value4" }
2. Ajuste as Configurações de Indexação
O Elasticsearch fornece várias configurações que podem ser ajustadas para otimizar o processo de indexação. Elas são normalmente definidas por índice.
Intervalo de Refresh (index.refresh_interval)
O intervalo de refresh controla com que frequência os dados se tornam visíveis para pesquisa. Comumente, índices ativos são atualizados cerca de uma vez por segundo quando estão sendo pesquisados, mas os padrões podem variar por versão e tipo de índice. Durante a indexação pesada, você pode aumentar esse intervalo para reduzir o trabalho de refresh. Definir como -1 desativa os refreshes automáticos, significando que os dados não se tornarão pesquisáveis até que você faça um refresh manual ou restaure os refreshes automáticos.
- Recomendação: Para operações de indexação em lote, aumente temporariamente
index.refresh_intervalou defina como-1quando a atualidade da pesquisa não for necessária. Após a operação em lote ser concluída, restaure a configuração que você usa para o comportamento normal de pesquisa e execute um refresh manual, se necessário.
Exemplo usando a API de Configurações do Índice:
# Desabilitar refresh temporariamente
PUT /my-index/_settings
{
"index" : {
"refresh_interval" : "-1"
}
}
# ... realizar indexação em lote ...
# Reabilitar refresh
PUT /my-index/_settings
{
"index" : {
"refresh_interval" : "1s"
}
}
Durabilidade do Translog (index.translog.durability)
O translog é um log de write-ahead que garante a durabilidade dos dados. Pode ser definido como request (padrão) ou async. Definir como async libera o translog de forma assíncrona, o que pode melhorar a velocidade de indexação, mas carrega um pequeno risco de perda de dados se um nó falhar antes que o translog seja gravado no disco.
- Recomendação: Para cenários de importação em lote onde a durabilidade é menos crítica que a velocidade,
asyncpode ser benéfico. Sempre considere a tolerância do seu aplicativo à perda de dados.
Número de Réplicas (index.number_of_replicas)
As réplicas são cópias de seus shards primários, usadas para alta disponibilidade e escalabilidade de leitura. No entanto, cada réplica precisa processar cada operação de indexação. Durante cargas de dados iniciais grandes, definir index.number_of_replicas como 0 pode acelerar significativamente a indexação. Após os dados serem carregados, você pode aumentar o número de réplicas.
Exemplo durante carga em lote:
# Definir réplicas temporariamente para 0
PUT /my-index/_settings
{
"index" : {
"number_of_replicas" : "0"
}
}
# ... realizar indexação em lote ...
# Restaurar réplicas (por exemplo, para 1)
PUT /my-index/_settings
{
"index" : {
"number_of_replicas" : "1"
}
}
3. Otimize Mapeamentos
Os mapeamentos definem como os documentos e seus campos são armazenados e indexados. Mapeamentos mal projetados podem levar a problemas de desempenho.
- Evite Mapeamento Dinâmico para Grandes Conjuntos de Dados: Embora conveniente, o mapeamento dinâmico pode levar a explosões de mapeamento e tipos de campo inesperados. Defina mapeamentos explícitos para seus índices, especialmente para dados de alto volume.
- Escolha Tipos de Dados Apropriados: Use os tipos de dados mais eficientes. Por exemplo,
keywordé mais eficiente para correspondência de valor exato do quetextse a pesquisa de texto completo não for necessária. - Desabilite Recursos Desnecessários: Se você não precisar de recursos como
normspara um campo específico (por exemplo, para correspondências exatas ou agregações), desabilitá-los pode economizar espaço e melhorar a velocidade de indexação (norms: false). Da mesma forma, desabilitedoc_valuesse não for necessário para ordenação ou agregações em um campo. No entanto,doc_valuessão geralmente benéficos para agregações e ordenação, então esta é uma decisão sutil. - Campo
_source: Se você não precisar do documento JSON original, desabilitar_sourcepode economizar espaço em disco e algum I/O, mas impede a reindexação e torna a depuração mais difícil. Considere a compressão de_sourcese você mantê-lo habilitado.
Exemplo de Mapeamento (com tipos explícitos e normas desabilitadas):
PUT /my-index
{
"mappings": {
"properties": {
"timestamp": {"type": "date"},
"message": {"type": "text", "norms": false},
"user_id": {"type": "keyword"}
}
}
}
4. Considerações de Hardware e Infraestrutura
Mesmo com configurações de software perfeitas, hardware inadequado limitará a velocidade de indexação.
- I/O de Disco: Use SSDs rápidos. SSDs NVMe oferecem o melhor desempenho. Evite armazenamento conectado à rede (NAS) para nós de indexação, se possível.
- CPU e RAM: Núcleos de CPU suficientes são necessários para análise, e RAM abundante ajuda com cache e desempenho geral da JVM.
- Capacidade de Ingestão e Coordenação: Para taxas de ingestão muito altas, considere nós de ingestão dedicados para pipelines ou nós de coordenação para tráfego bulk do cliente. Os nós de dados ainda realizam o trabalho real de indexação, então não os prive de CPU, memória ou I/O de disco.
- Rede: Garanta largura de banda suficiente e baixa latência entre seus clientes e nós do Elasticsearch, e entre nós no cluster.
5. Dimensionamento e Contagem de Shards
Embora não seja diretamente uma configuração de indexação, o número e o tamanho dos shards impactam o desempenho. Muitos shards pequenos podem aumentar a sobrecarga. Por outro lado, um único shard massivo pode ser difícil de gerenciar e pode não escalar bem. Mire em tamanhos de shard entre 10 GB e 50 GB para desempenho ideal, mas isso pode variar.
- Recomendação: Planeje sua contagem de shards primários antes de indexar grandes quantidades de dados. Geralmente não é recomendado alterar o número de shards primários em um índice existente sem reindexar.
6. Gerenciamento do Ciclo de Vida do Índice (ILM)
Para dados de séries temporais, usar o Gerenciamento do Ciclo de Vida do Índice (ILM) é crucial. Embora o ILM ajude principalmente a gerenciar índices ao longo do tempo (rollover, shrink, delete), a ação de rollover pode ser configurada para criar novos índices com base no tamanho ou idade. Isso garante que os índices permaneçam dentro de faixas de tamanho ideais, o que indiretamente beneficia o desempenho da indexação.
- Rollover: Quando um índice atinge um certo tamanho ou idade, o ILM pode criar automaticamente um novo índice vazio e alternar o alias do fluxo de dados para ele. Isso permite que você otimize as configurações para o novo índice (por exemplo, réplicas mais baixas durante a carga em lote inicial) e mantenha os índices ativos gerenciáveis.
Conclusão Prática
Comece com indexação em lote, mapeamentos explícitos e I/O de disco suficiente. Para cargas únicas, relaxe refreshes e réplicas apenas enquanto você puder tolerar atualidade de pesquisa reduzida ou redundância, depois restaure as configurações normais e verifique a saúde do cluster. Continue testando com seus documentos reais; tamanhos de lote e contagens de shard genéricos são apenas pontos de partida.