cloudformation + lambda

Недавно столкнулись с проблемой - при больших нагрузках, количество логов генерируемое приложениями, перестали доствляться в AWS ElasticSearch. Проблема оказалась вовсе не проблемой, а особенностью AWS

The issue

В чем собственно было дело?

  • Во первых, перестали появляться записи в Kibana
  • Во вторых, в логах Logstash появились сообщения вот такого содержания:
[2017-04-05T17:12:34,453][ERROR][logstash.outputs.amazones] Attempted to send a bulk request to Elasticsearch configured at '["https://domain.eu-central-1.es.amazonaws.com:443"]', but an error occurred and it failed! Are you sure you can reach elasticsearch from this machine using the configuration provided?
{:client_config=>{:hosts=>["https://domain.eu-central-1.es.amazonaws.com:443"], :region=>"eu-central-1", :transport_options=>{:request=>{:open_timeout=>0, :timeout=>60}, :proxy=>nil}, :transport_class=>Elasticsearch::Transport::Transport::HTTP::AWS}, :error_message=>"[413] {\"Message\":\"Request size exceeded 10485760 bytes\"}", :error_class=>"Elasticsearch::Transport::Transport::Errors::RequestEntityTooLarge"

С одной стороны Logstash сомневается в доступности AWS ElasticSearch Domain, а с другой явно говорит, что проблема в нашем реквесте, а именно - RequestEntityTooLarge.

После непродолжительного поиска, оказалось, что у ElasticSearch есть параметр отвечающий за размер входящего запроса http.max_content_length. Но, к сожалению, в AWS этот параметр изменить не так просто.

Проблема в том, что он устанавливается AWS и его можно изменить только изменив instance type используемый для AWS ES Domain. Выглядит это примерно так:

Service Request Limit
Maximum Size of HTTP Request Payloads Each supported instance type has a maximum supported payload for HTTP requests:
  - t2.micro.elasticsearch: 10 MB
  - t2.medium.elasticsearch: 10 MB
  - m3.large.elasticsearch: 10 MB
  - m3.xlarge.elasticsearch: 100 MB
  - m4.large.elasticsearch: 10 MB
  - m4.xlarge.elasticsearch: 100 MB
  - c4.large.elasticsearch: 10 MB
  - c4.xlarge.elasticsearch: 100 MB
 

Полный список доступен в разделе Network Limits.

Solution

С учетом исходных данных у нас были следующие варианты:

  • Масштабировать ElasticSearch Domain вертикально, изменив instance type;
  • Изменить конфигурацию Logstash, чтобы на выходе было меньше данных.

На первом варианте останавливаться не буду, так как это подробно описано в документации.

Второй вариант может варьироваться от плагина, но в данном случае мы использовали стандартный плагин от AWS - logstash-output-amazon_es.

У этого плагина есть параметр, который отвечает за количество событий, которые будут буферизироваться перед отправкой в ES.

flush_size (number , default => 500) - This setting controls how many events will be buffered before sending a batch of events in bulk API

Значение по умолчанию - 500. К сожалению, времени на глубокий анализ у нас не было, поэтому мы его подбирали опытным путем. После снижения его до 100, проблема решилась.

Из побочных эффектов, немного увеличилась нагрузка на сам Logstash и сеть. В целом эта проблема проявлялась у нас на тестовых окружениях, во время тестирования производительности, поэтому масштабировать ES вертикально для нас было не самый экономически приемлимый вариант.

Summary

В итоге у нас вренулись сообщения в Kibana и мы смогли решить проблему без дополнительных инвестиций в инфраструктуру.