This is a file preview. Join to view the original file.
Estudo sobre quedas do ElasticSearch [SITE-1468] Descobrir o motivo do ElasticSearch estar caindo Introdução O ElasticSearch do ambiente de produção (site) estava apresentando muito instablidade, travando várias vezes ao dia por motivo desconhecido. Esse problema existia há meses, ficando mais frequente recentemente. Quando ocorre o problema, o servidor continua respondendo, porém nenhuma query funciona mais (retornam um código de erro). Em alguns casos extremos, o servidor para de responder. Investigação Comecei a investigação estudando mais a fundo o funcionamento do ElasticSearch. Encontrei alguns artigos bons que discutem como otimizar / escalar o ES: http://gibrown.wordpress.com/2014/01/09/scaling-elasticsearch-part-1-overview/ http://gibrown.wordpress.com/2014/02/06/scaling-elasticsearch-part-2-indexing/ e http://blog.trifork.com/2013/09/26/maximum-shard-size-in-elasticsearch/ http://blog.trifork.com/2013/11/05/maximum-shard-size-in-elasticsearch-revisited/ http://blog.trifork.com/2014/01/07/elasticsearch-how-many-shards/ Sobre algumas configurações básicas: http://asquera.de/opensource/2012/11/25/elasticsearch-pre-flight-checklist/ http://stackoverflow.com/questions/18132719/how-to-change-elasticsearch-max-size/ Em seguida, peguei os logs de produção e ativei o “Slowlog” (feature do ES que permite logar queries demoradas) com o Beildeck. - Vários erros no log ocorreram por conta de caracteres inválidos (user input) em algumas buscas - A maioria dos erros eram exceções que indicavam que o request foi abortado por conta do limite de threads. O ElasticSearch possui threadpools para realizar as buscas. Quando o pool fica cheio, ele adiciona as threads em uma fila. Quando chega no limite dessa fila, os novos requests são simplesmente abortados. - A maioria das queries que apareceram no Slowlog ocorreram em horários próximos aos momentos em que o ES travou. Começam a aparecer cerca de 1 hora antes e vão aumentando até o momento em que tudo para. Por fim, tentei reproduzir o problema, primeiro em dev e depois em produção mesmo. A estratégia foi usar o JMeter para fazer muitos requests simultâneos ao ES. Nos dois ambientes o comportamento foi semelhante. Após atingir determinado número de requests por segundo, o ES passa a retornar status code 503 (serviço indisponível), devido ao limite do número de threads na fila. Isso é semelhante ao erro que estava derrubando o ES em produção. A diferença é que nessa simulação de testes, após cessarem os requests, o ES volta a funcionar normalmente. Quando o erro acontece em produção, o ES não volta a funcionar sozinho (é preciso reiniciar o serviço). Não consegui reproduzir o cenário real do erro. Resultados a) O problema de queda foi aparentemente resolvido alocando mais memória para o processo do ES, através da variável de ambiente ES_HEAP_SIZE. Antes estava sendo alocado apenas 1.75GB, agora está com 6.0GB. A recomendação é deixar 50% da memória da máquina para o ES. Essa solução é imediatista, provavelmente com crescimento dos índices e aumento da demanda o erro voltará a se manifestar. b) Para escalar, é preciso montar um cluster. Parece ser simples de configurar o cluster, mas devemos fazer testes antes de precisar de fato. Testes constantes de configuração (dos nós e dos índices) são importantes para aprender a otimizar o cluster também. c) Ainda assim, não consegui reproduzir o problema como ele ocorria em produção (parar de responder e só voltar ao reiniciar o serviço). Pode ser algum bug do próprio ES ativado por alguma query que fazemos. Ou pode ser qualquer outra coisa... d) O desempenho do nosso ES está muito ruim. Para uma query testada no índice de arquivos, o ES não passou de 70 responses/s e rapidamente cada request chegou a demorar mais de 1s. É preciso fazer mais testes de carga com outras queries. O problema pode ser de configuração ou pode ser que nossas queries sejam complexas demais. É preciso investigar. e) Analisando os logs, identifiquei um bug. Em muitos casos passamos caracteres inválidos (que os usuários digitam) para as queries o que gera um ParseError e a busca do usuário retorna erro. f) Os logs do ES são muito úteis. O log padrão mostra os erros que acontecem. Com isso podemos verificar as queries bugadas. É também um ponto de partida para tentar descobrir o que aconteceu quando o servidor trava. O “Slowlog” loga as queries (de indexação e de busca) mais lentas, de forma que podemos verificar os pontos que precisam ser mais otimizados. g) Artigo que encontrei e pode ser útil, relacionado à fila de threads, porém não testei: http://jontai.me/blog/2013/06/esrejectedexecutionexception-rejected-execution-of-messagechannelhandler-requesthandler/ 12/05/2014