Boas práticas e recomendações (Elasticsearch)

Este artigo faz parte de uma série de publicações que estou incluindo no repositório go-ELK no Github. Acesse o material completo na raiz: http://github.com/fabiojaniolima/go-ELK

No escopo deste documento considere o uso dos termos abaixo para declaração de importância e relevância:

As palavras-chave “DEVE”, “NÃO DEVE”, “REQUER”, “DEVERIA”, “NÃO DEVERIA”, “PODERIA”, “NÃO PODERIA”, “RECOMENDÁVEL”, “PODE”, e “OPCIONAL” neste documento devem ser interpretadas como descritas no [RFC 2119](http://tools.ietf.org/html/rfc2119). Tradução livre [RFC 2119 pt-br](http://rfc.pt.webiwg.org/rfc2119).

Heap

Arquivo de configuração: ./config/jvm.options

Xmx e Xms:

  • DEVEM possuir o mesmo valor
  • DEVERIAM corresponder a 50% da memória RAM total
  • O valor máximo ideal considerando as condições anterior DEVERIA ser 26GB
  • O valor máximo NÃO DEVE ser superior a 32GB

Referênciahttps://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html

Shards

Não existe um valor ideal para o tamanho dos shards ou quantidade, mas existem algumas recomendações feitas pela Elastic, sendo elas:

  • O número de shards que u nó pode conter é proporcional ao espaço de heap reservado. Como regra geral o número de shards por GB de espaço de head DEVE ser menor que 20
  • Não existe um tamanho máximo ou mínimo exato de um shard, porém, é recomendado que este valor esteja entre 20GB a 40GB. Muitas literaturas inclusive recomenda o valor de 50GB

Atenção: cada shard é naturalmente uma instância do Apache Lucene, logo shards muito pequenos podem gerar muita sobrecarga (overhead), por outro lado shards muito grandes podem dificultar os processos de realocação e balanceamento do cluster.

Referênciahttps://www.elastic.co/guide/en/elasticsearch/reference/current/scalability.html

Mapeamento de dados

Dados submetidos ao Elastic sem mapeamento predefinido serão automaticamente mapeados e indexados com base em um conjunto genérico. Strings normalmente serão indexadas duas vezes, uma para o tipo `text` e outra para `keyword`, já números inteiros receberão o maior tipo inteiro disponível, neste caso `long`.

Realizar o mapeamento dos dados via uso de templates é uma abordagem que orienta o Elastic a como tratar e indexar os dados submetidos, garantindo assim melhor performance e alocação de recursos.

Exemplo: ao submeter quatro campos, sendo eles nomemensagememail e idade o Elastic fará o seguinte mapeamento:

nome: [“text”, “keyword”]
mensagem: [“text”, “keyword”]
email: [“text”, “keyword”]
idade: [“long”]
  • text: tipo para indexação de texto completo, como o corpo de um email, notícia, memorando e outros;
  • keyword: tipo para indexação de dados estruturados como email, códigos, status, tags e outros.

Considerando os campos citados anteriormente, em meu contexto (lembre-se, cada caso é um caso) o ideal seria que os dados fossem mapeados da seguinte forma:

nome: [“keyword”]
mensagem: [“keyword”]
email: [“keyword”]
idade: [“byte”]

Essa abordagem irá evitar indexações de tipos desnecessários e inferência inadequada de tipo. Agora imagine isso para casos onde temos milhões ou bilhões de registros com dezenas ou centenas de campos.

Consideração final:

  • Você DEVERIA definir sempre que possível seu mapeamento de dados via uso de templates

Referência: https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html

Stop / kill

Considerando que normalmente após start o processo é jogado para background, para realizar o stop é necessário basicamente matar o processo.

No Linux ou MacOS é comum ser utilizada a instrução:

kill -9 ELASTIC-PID

Mas é muito importante que você dê a chance dos subprocessos serem encerrados ao invés de simplesmente “matá-los”. Para isso você DEVERIA considerar utilizar:

kill -15 ELASTIC-PID

Essa abordagem evita corromper arquivos e até mesmo evita que processos filhos virem órfãos (zumbis).

refresh_interval

Por padrão, o Elasticsearch atualiza periodicamente os índices a cada segundo, mas apenas nos índices que receberam uma solicitação de pesquisa ou mais nos últimos 30 segundos.

Caso não necessite dos dados em períodos tão curtos após a inserção, você DEVERIA considerar valores adequados a realidade do cenário, ou seja, se estes dados podem ser aguardados por 1 minuto, 1 hora ou se forem necessários para um relatório dia+1, então configure seu valor de atualização baseado neste cenário. Exemplo:

PUT /NOME_DO_INDICE/_settings
{
"index": {
"refresh_interval": "30s"
}
}

Referência: https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html