Elasticsearch In Production - Melhores práticas de implantação

O Elasticsearch é um mecanismo de pesquisa altamente otimizado para análises de dados modernas.

O Elasticsearch é um incrível mecanismo de pesquisa e análise em tempo real. É construído no Apache Lucene. É distribuído, RESTful, fácil de começar a usar e altamente disponível. Os casos de uso do Elasticsearch incluem alimentar a pesquisa, o monitoramento de transações e a detecção de erros, descoberta de conteúdo, análise de log, pesquisa difusa, agregação de dados de eventos, visualização de dados. O Elasticsearch e o restante da Elastic Stack provaram ser extremamente versáteis e, como você pode ver nos casos de uso acima, existem várias maneiras de integrar o Elasticsearch ao que o seu produto está entregando hoje e adicionar informações adicionais a ele.

Nós o usamos intensamente para pesquisa e análise na Botmetric, indexamos cerca de um bilhão de documentos por dia e usamos agregações muito complexas para visualização de dados em tempo real.

Dito isto, a inicialização de um aplicativo versus sua execução na produção e manutenção são totalmente diferentes. Esse artigo abrange muitos desses fatores de experiências da vida real e são os itens comuns básicos que você deve considerar para executar o Elasticsearch na produção.

Memória:

Elasticsearch e Lucene são escritos em Java, o que significa que você deve observar as estatísticas de heapspace e JVM. Quanto mais heap disponível para o Elasticsearch, mais memória ele pode usar para filtro e outro cache para aumentar o desempenho da consulta. Mas observe que muita pilha pode sujeitá-lo a longas pausas na coleta de lixo. Não defina Xmx acima do ponto de corte que a JVM usa para ponteiros de objetos compactados (oops compactados); o ponto de corte exato varia, mas está próximo de 32 GB.

Um problema comum é configurar um heap muito grande. Você tem uma máquina de 64 GB - e, pelo amor de Deus, deseja fornecer ao Elasticsearch todos os 64 GB de memória. Mais é melhor! Heap é definitivamente importante para o Elasticsearch. É usado por muitas estruturas de dados na memória para fornecer operação rápida. Mas com isso dito, há outro usuário importante de memória que está fora do heap: cache de arquivos do SO.

O Lucene foi projetado para aproveitar o SO subjacente para armazenar em cache estruturas de dados na memória. Os segmentos Lucene são armazenados em arquivos individuais. Como os segmentos são imutáveis, esses arquivos nunca são alterados. Isso os torna muito amigáveis ​​ao cache, e o sistema operacional subjacente manterá felizes os segmentos quentes residentes na memória para acesso mais rápido. Esses segmentos incluem o índice invertido (para pesquisa de texto completo) e os valores de documentos (para agregações). O desempenho do Lucene depende dessa interação com o sistema operacional. Mas se você der toda a memória disponível para o heap do Elasticsearch, não haverá mais sobra para o cache de arquivos do SO. Isso pode afetar seriamente o desempenho. A recomendação padrão é fornecer 50% da memória disponível ao heap do Elasticsearch, deixando os outros 50% livres. Não será usado; Lucene consumirá com alegria o que resta para o cache de arquivos. O heap do Elasticsearch pode ser configurado das seguintes maneiras,

exportar ES_HEAP_SIZE = 10g

ou

ES_JAVA_OPTS = "- Xms10g -Xmx10g" ./bin/elasticsearch

CPU:

O Elasticsearch suporta agregações e consultas filtradas. A execução de consultas filtradas complexas, indexação intensiva, percolação e consultas em índices precisa de uma CPU pesada, portanto, escolher a correta é fundamental. É preciso entender as especificações da CPU e como elas se comportam com Java à medida que as consultas são executadas na JVM.

Cada pool executa um número de threads, que podem ser configurados e tem uma fila. Alterar isso não é recomendado, a menos que você tenha requisitos muito específicos, pois o Elasticsearch faz alocação de núcleos dinamicamente.

Tipos de pool de encadeamentos:

O Elasticsearch possui 3 tipos de conjuntos de threads.

  1. Em cache: o conjunto de encadeamentos em cache é um conjunto de encadeamentos ilimitados que gerará um encadeamento se houver solicitações pendentes. Esse conjunto de encadeamentos é usado para impedir que solicitações enviadas a esse conjunto sejam bloqueadas ou rejeitadas. Os encadeamentos não utilizados nesse conjunto de encadeamentos serão encerrados depois que um keep alive expirar (o padrão é cinco minutos). O conjunto de encadeamentos em cache é reservado para o conjunto de encadeamentos genérico.
  2. Fixo: o conjunto de encadeamentos fixos mantém um tamanho fixo de encadeamentos para manipular as solicitações com uma fila (opcionalmente limitada) para solicitações pendentes que não possuem encadeamentos para atendê-las. O parâmetro size controla o número de threads e o padrão é o número de núcleos vezes 5.
  3. Dimensionamento: o conjunto de encadeamentos de dimensionamento contém um número dinâmico de encadeamentos. Esse número é proporcional à carga de trabalho e varia entre 1 e o valor do parâmetro size.

O Elasticsearch divide o uso da CPU em conjuntos de encadeamentos de vários tipos:

  • genérico: para operações padrão, como descoberta e tipo de conjunto de encadeamentos, é armazenado em cache.
  • índice: para operações de indexação / exclusão. O tipo de pool de threads é fixo.
  • search: para operações de contagem / pesquisa. O tipo de pool de threads é fixo.
  • get: para obter operações. O tipo de pool de threads é fixo.
  • bulk: para operações em massa, como indexação em massa. O tipo de pool de threads é fixo. A melhor configuração de documentos em massa depende da configuração do cluster. Isso pode ser identificado tentando vários valores.
  • percolar: para percolar. O tipo de pool de threads é fixo.
  • refresh: Para operações de atualização. O tipo de conjunto de encadeamentos está em escala.

A alteração de um conjunto de encadeamentos específico pode ser feita configurando seus parâmetros específicos de tipo.

Leia mais https://www.elastic.co/guide/en/elasticsearch/reference/2.2/modules-threadpool.html#types

Tamanho do fragmento:

O shard é a unidade na qual o Elasticsearch distribui dados dentro do cluster. A velocidade com que o Elasticsearch pode mover shards ao reequilibrar dados, por exemplo após uma falha, dependerá do tamanho e número de shards, além do desempenho da rede e do disco.

No Elasticsearch, cada consulta é executada em um único encadeamento por shard. No entanto, vários shards podem ser processados ​​em paralelo, assim como várias consultas e agregações no mesmo shard.

Isso significa que a latência mínima da consulta, quando não houver armazenamento em cache, dependerá dos dados, do tipo de consulta e do tamanho do shard. A consulta a vários fragmentos pequenos tornará o processamento por fragmento mais rápido, mas, como muitas outras tarefas precisam ser enfileiradas e processadas em sequência, não será necessariamente mais rápido do que consultar um número menor de fragmentos maiores. Ter muitos shards pequenos também pode reduzir a taxa de transferência da consulta se houver várias consultas simultâneas.

Cada shard possui dados que precisam ser mantidos na memória e usam espaço de heap. Isso inclui estruturas de dados que mantêm informações no nível do fragmento e também no nível do segmento para definir onde os dados residem no disco. O tamanho dessas estruturas de dados não é fixo e irá variar dependendo do caso de uso. Uma característica importante da sobrecarga relacionada ao segmento é, no entanto, que ela não é estritamente proporcional ao tamanho do segmento. Isso significa que segmentos maiores têm menos sobrecarga por volume de dados em comparação com segmentos menores. A diferença pode ser substancial. Escolher o número certo de shards é complicado porque você nunca sabe quantos documentos receberá antes de começar. Ter muitos fragmentos pode ser bom e terrível para um cluster. O gerenciamento de índices e shards pode sobrecarregar o nó principal, que pode não responder, levando a um comportamento estranho e desagradável. Aloque seus nós principais recursos suficientes para lidar com o tamanho do cluster.

O ruim é que o número de shards é imutável e é definido quando você cria o índice. Depois que o índice é criado, a única maneira de alterar o número de shards é excluir seus índices, criá-los novamente e reindexar.

Replicação

O Elasticsearch suporta replicação, os dados são replicados entre os nós de dados, de modo que uma perda de nós não levaria à perda de dados. Por padrão, o fator de replicação é 1, mas, dependendo dos requisitos do produto, ele pode ser aumentado. Quanto mais réplicas, mais resistentes a desastres serão os seus dados. Outra vantagem de ter mais réplicas é que cada nó possui um fragmento de réplica, o que melhora o desempenho da consulta, pois as réplicas também são usadas para consulta.

A fórmula de replicação usada pelo Elasticsearch para consistência é,

(principal + número_de_replicas) / 2 + 1

Otimizando alocação

Com base nos requisitos de dados do produto, podemos classificar os dados em quente e frio. Os índices que são acessados ​​com mais frequência do que outros, podem receber mais nós de dados, enquanto os índices que são acessados ​​com menos frequência podem ter menos recursos alocados. Essa estratégia é especialmente útil para armazenar dados de séries temporais, como logs de aplicativos (por exemplo: ELK).

Isso pode ser conseguido executando um cronjob que move os índices para diferentes nós em intervalos regulares.

O nó ativo é um tipo de nó de dados que executa toda a indexação no cluster. Eles também possuem os índices mais recentes, pois esses geralmente tendem a ser consultados com mais frequência. Como a indexação é uma operação intensiva de CPU e E / S, esses servidores precisam ser poderosos e suportados pelo armazenamento SSD conectado. Recomendamos a execução de no mínimo 3 nós quentes para alta disponibilidade. Porém, dependendo da quantidade de dados recentes que você deseja coletar e consultar, pode ser necessário aumentar esse número para atingir suas metas de desempenho.

O nó quente é o tipo de nó de dados projetado para lidar com uma grande quantidade de índices somente leitura que não têm tanta probabilidade de serem consultados com frequência. Como esses índices são somente leitura, o nó quente tende a utilizar grandes discos conectados (geralmente discos giratórios) em vez de SSDs. Assim como no nó ativo, recomendamos um mínimo de 3 nós quentes para alta disponibilidade. E, como antes, com a ressalva de que grandes quantidades de dados podem exigir nós adicionais para atender aos requisitos de desempenho. Observe também que as configurações de CPU e memória geralmente precisam espelhar as de seus nós quentes. Isso só pode ser determinado testando com consultas semelhantes às que você experimentaria em uma situação de produção.

Para mais detalhes sobre o nó quente e quente, consulte aqui.

Outra estratégia que você pode adaptar é arquivar os índices em s3 e restaurar quando precisar de dados desses índices. Você pode ler mais sobre isso aqui.

Topologia do nó:

Os nós do Elasticsearch podem ser divididos em três categorias: nó principal, nó de dados e nó do cliente.

  1. Nó mestre: o nó mestre pode ser pequeno se também não for um nó Dados, pois não armazena nenhum índice / shards. Sua responsabilidade é armazenar o estado detalhado do cluster e ajudar dados e outros nós na pesquisa de metadados de índices / shards. A pesquisa elástica deve ter vários nós principais para evitar problemas no cérebro dividido.
  2. Nó de dados: o nó de dados é responsável por armazenar / consultar os dados reais do índice.
  3. Nó do cliente: o nó do cliente é usado como um proxy para indexação e pesquisa. Isso é altamente recomendado se as agregações forem muito usadas. Esses são nós especiais do ElasticSearch que não são elegíveis para dados ou mestre. Os nós do cliente têm reconhecimento de cluster e, portanto, podem atuar como balanceadores de carga inteligentes. Você pode enviar suas consultas aos nós do cliente, que podem assumir a dispendiosa tarefa de reunir respostas aos resultados da consulta de cada um dos nós de dados.

adicione essas configurações ao arquivo elasticsearch.yml para os respectivos nós.

Nó mestre: node.master: true node.data:false
Nó de dados: node.master: false node.data:true
Nó do cliente: node.master: false node.data:false

Dicas de soluções de problemas:

O desempenho do Elasticsearch depende muito da máquina em que está instalado. CPU, uso de memória e E / S de disco são métricas básicas do sistema operacional para cada nó do Elasticsearch. É recomendável que você analise as métricas da Java Virtual Machine (JVM) quando o uso da CPU aumentar. No exemplo a seguir, o motivo do aumento foi maior atividade de coleta de lixo.

  1. Pressão da pilha: A alta pressão da memória funciona contra o desempenho do cluster de duas maneiras: como a pressão da memória aumenta para 75% e acima, resta menos memória disponível, e agora o cluster também precisa gastar alguns recursos da CPU para recuperar a memória através da coleta de lixo. Esses ciclos da CPU não estão disponíveis para manipular solicitações do usuário enquanto a coleta de lixo está ativada. Como resultado, o tempo de resposta para solicitações do usuário aumenta à medida que o sistema se torna cada vez mais restrito a recursos. Se a pressão da memória continuar a subir e atingir quase 100%, será usada uma forma muito mais agressiva de coleta de lixo, o que afetará drasticamente os tempos de resposta do cluster. A métrica de tempos de resposta do índice mostra que a alta pressão da memória leva a um impacto significativo no desempenho.
  2. Crescimento da memória não heap da JVM, consumindo a memória destinada ao cache da página e possivelmente causando a colheita de OOM no nível do kernel.
  3. Evite problemas no cérebro dividido. Cérebro dividido é um cenário em que o cluster se divide. Por exemplo, você tem um cluster de 6 nós. 2 nós desconectam-se do cluster, mas ainda podem se ver. Esses 2 nós criam outro cluster. Eles até elegerão um novo mestre entre si. Agora temos dois clusters com o mesmo nome, um com 4 nós e outro com 2 nós. Cada um também possui um nó mestre. Isso é chamado de problema de cérebro dividido com clusters ES.Para evitar isso, defina o parâmetro discovery.zen.minimum_master_nodes do ES como metade do número de nós + 1.
  4. Como o Elasticsearch utiliza muito dispositivos de armazenamento, o monitoramento da E / S do disco garante que essa necessidade básica seja atendida. Há muitas razões para a E / S reduzida de disco, considerada uma métrica chave para prever muitos tipos de problemas. É uma boa métrica verificar a eficácia do desempenho da indexação e da consulta. A análise das operações de leitura e gravação indica diretamente o que o sistema mais precisa no caso de uso específico. As configurações do sistema operacional para E / S de disco são uma base para todas as outras otimizações. O ajuste de E / S de disco pode evitar possíveis problemas. Se a E / S do disco ainda não for suficiente, contramedidas como otimizar o número de shards e seu tamanho, limitar a fusão, substituir discos lentos, mudar para SSDs ou adicionar mais nós devem ser avaliados de acordo com as circunstâncias que causam a E / S gargalos.
  5. Para os aplicativos que dependem da pesquisa, a experiência do usuário está altamente correlacionada à latência das solicitações de pesquisa. Há muitas coisas que podem afetar o desempenho da consulta, como consultas construídas, cluster Elasticsearch configurado incorretamente, problemas de memória e coleta de lixo da JVM, E / S de disco e assim por diante. Latência de consulta é a métrica que afeta diretamente os usuários; portanto, certifique-se de colocar alguns alertas nela.
  6. A maioria dos filtros no Elasticsearch é armazenada em cache por padrão. Isso significa que, durante a primeira execução de uma consulta filtrada, o Elasticsearch encontrará documentos correspondentes ao filtro e criará uma estrutura chamada "conjunto de bits" usando essas informações. Os dados armazenados no conjunto de bits contêm um identificador de documento e se um determinado documento corresponde ao filtro. Execuções subseqüentes de consultas com o mesmo filtro reutilizarão as informações armazenadas no conjunto de bits, agilizando a execução da consulta, salvando operações de E / S e ciclos de CPU. É recomendável usar o filtro na consulta. Para mais detalhes, consulte aqui.
  7. O tempo de atualização e o tempo de mesclagem estão intimamente relacionados ao desempenho da indexação, além de afetar o desempenho geral do cluster. O tempo de atualização aumenta com o número de operações de arquivo do índice Lucene (shard).
  8. A ativação do log lento de consultas ajudará a identificar quais consultas são lentas e o que pode ser feito para melhorá-las, especialmente útil para consultas curinga.
  9. Aumente o tamanho do ulimit para permitir o máximo de arquivos.
  10. O desempenho do ElasticSearch pode sofrer quando o sistema operacional decide trocar a memória não utilizada do aplicativo. Desative a troca definindo as configurações no nível do SO ou defina o seguinte em ElasticSearch config bootstrap.mlockall: true
  11. Desative a exclusão de todos os índices por consulta curinga. Para garantir que alguém não emita uma operação DELETE em todos os índices (* ou _all), defina action.destructive_requires_name como true.

Antes de terminar, aqui está a lista de URLs úteis para assistir às métricas.

  • / _cluster / health? pretty: Para o indicador de integridade do cluster.
  • / _status? pretty: Para todas as informações sobre todos os índices.
  • / _nodes? pretty: Para todas as informações sobre os nós.
  • / _cat / master? pretty: Para nó principal.
  • / _stats? pretty: para alocação de shard, estatísticas de índices.
  • / _nodes / stats? pretty: Para estatísticas de nós individuais, isso inclui estatísticas jvm, http, io para o nó.

A agregação de métricas do Elasticsearch é suportada pela maioria das ferramentas de monitoramento do sistema, como Datadog, TICK. O uso dessas ferramentas é recomendado e a criação de funil é altamente recomendada para o monitoramento contínuo do Elasticsearch.

Conclusão:

O Elasticsearch é um mecanismo de pesquisa e análise de texto completo distribuído, que permite a vários inquilinos pesquisar em todo o conjunto de dados, independentemente do tamanho, em velocidades sem precedentes. Além de seus recursos de pesquisa de texto completo, o ElasticSearch funciona como um sistema de análise e banco de dados distribuído. O ElasticSearch possui ótimos padrões para começar. Porém, após o estágio inicial de experimentação, você deve dedicar algum tempo para ajustar as configurações de acordo com suas necessidades. É recomendável revisitar sua configuração posteriormente, juntamente com a documentação oficial, para garantir que seu cluster esteja configurado para atender às suas necessidades.