ADG Оставить заявку
Блог Данные и аналитика 5 мин чтения

Elastic Stack 5.x в продакшне: Kibana 5, pipeline-workers и боль mapping-миграции

Мигрировали с ELK 2.x на Elastic Stack 5: новый UI Kibana 5, pipeline.workers в Logstash, Beats вместо logstash-forwarder - и всё это с маппингом, который надо пересоздавать.

Контекст момента

Elastic Stack 5.0 GA вышел в октябре 2016 - унифицированное версионирование всех компонентов, новый Kibana 5 и Logstash с multi-worker pipeline

Elastic Stack 5.0 вышел в октябре, и мы несколько месяцев смотрели на него как на «интересно, но трогать не сейчас». В январе трогать пришлось - один из клиентов на managed-сопровождении упёрся в ограничения 2.x, и миграция перестала быть вопросом выбора.

Почему именно сейчас

ELK 2.x у нас работал стабильно с 2015-го. Kibana 4, Logstash 2.4, Elasticsearch 2.4 - связка отлаженная, без сюрпризов. Но накопилось несколько раздражителей: Logstash на высоком потоке создавал очередь на одном потоке выполнения, logstash-forwarder (он же lumberjack) вёл себя странно при сетевых проблемах, а Kibana 4 начала показывать возраст - некоторые агрегации тормозили без очевидной причины.

Elastic с версии 5.0 сделал единое версионирование всего стека: Elasticsearch 5.0, Logstash 5.0, Kibana 5.0, Beats 5.0. Технически это означало, что logstash-forwarder официально объявлен deprecated и его место занял Filebeat. Что ж.

Что менялось в стеке

Перечень изменений, которые реально затронули нашу конфигурацию:

  • pipeline.workers в Logstash. Logstash 5 запускает filter и output в несколько потоков. Параметр pipeline.workers в logstash.yml - по умолчанию равен числу CPU. На нагруженных инстансах это дало ощутимый прирост пропускной способности без изменения конфигурации фильтров. Очередь перестала расти при всплесках.
  • Filebeat вместо logstash-forwarder. Filebeat - это отдельный проект из семейства Beats, написан на Go. Он умеет читать файлы с позиции (registry), обрабатывает ротацию логов, и в отличие от logstash-forwarder не теряет события при кратковременных обрывах соединения. Плюс можно читать несколько путей в одном конфиге с разными тегами.
  • Kibana 5 - новый интерфейс. Левое боковое меню сменилось на иконки-вкладки, Timelion появился как встроенный инструмент, Console заменил старый Sense-плагин. Первые два часа после обновления команда клиента звонила с вопросами «а где теперь Dashboard?» - но это привыкание, а не регресс.
  • Mapping strict mode. Elasticsearch 5 ужесточил обработку маппингов. Несколько полей, которые в 2.x молча конвертировались или игнорировались, теперь вызывали ошибки индексации. Вот это нас и накрыло.

Маппинг: самая неприятная часть

In-place обновление с 2.x на 5.x для Elasticsearch не поддерживается - нужен либо reindex, либо новые индексы с нуля. Мы выбрали новые индексы: переименовали старый шаблон, запустили Logstash 5 с новым шаблоном, старые данные остались в старых индексах под Elasticsearch 2.4 (параллельно крутили оба кластера недолго).

Проблема вскрылась через несколько часов после запуска: часть событий переставала попадать в индекс, Logstash писал в лог MapperParsingException. Разбор показал три кейса:

Первый - поле с разными типами. В 2.x одно из полей приходило то как строка, то как число, и Elasticsearch это переваривал в dynamic mapping. В 5.x - нет. Пришлось зафиксировать тип в шаблоне и добавить в Logstash mutate { convert } для нормализации.

Второй - точки в именах полей. В 2.x поле user.name в JSON трактовалось как строка с точкой. В 5.x точка в имени поля - это вложенный объект. Несколько источников слали события с полями вида http.status, http.method - это неожиданно превратилось в nested структуру, и старые Kibana-визуализации перестали работать. Решили через mutate { rename } в Logstash - заменили точки на подчёркивания на уровне pipeline.

Третий - string тип исчез. В ES 5.x тип string заменён на text и keyword. В старом шаблоне у нас были явные "type": "string" - ES 5 их не понимает. Переписали шаблон, заодно разобрались какие поля нужны для полнотекстового поиска (text), а какие только для агрегаций и точного матчинга (keyword). До этого всё было string, и полнотекстовые индексы ели лишнее место.

Beats: первый реальный опыт

До этого мы использовали Filebeat в небольших пилотах, но Metricbeat не трогали - метрики шли через collectd и Zabbix. В этой миграции добавили Filebeat на все хосты вместо logstash-forwarder.

Конфиг Filebeat проще чем logstash-forwarder: один YAML, filebeat.prospectors, каждый prospector - путь и набор полей. Отправляем напрямую в Logstash через Beats input (порт 5044), там input { beats { port => 5044 } }. Работает.

Один нюанс: Filebeat добавляет в событие свои поля - beat.hostname, beat.name, input_type, offset. В старых grok-паттернах этих полей не было, и несколько визуализаций в Kibana ссылались на поля которых больше нет или которые переехали. Пришлось поправить руками.

Где сейчас

Две недели на продакшне - стек стабилен. Logstash 5 с pipeline.workers: 4 держит пик без накопления очереди там, где Logstash 2.4 начинал захлёбываться. Filebeat на 30 хостах ведёт себя предсказуемо: registry сохраняется, после перезапуска сервера события не дублируются и не теряются.

Kibana 5 показывает данные быстрее на сложных агрегациях - субъективно, но заметно. Timelion интересен для time-series анализа, но это отдельная история.

Главный вывод из миграции: mapping-проблемы не видны пока вы не запустите реальный трафик. Тестовый стенд с синтетическими данными их не поймает - нужен представительный срез продакшн-событий. Мы нашли все три кейса уже в проде, что доставило примерно те самые ощущения.

Ещё один вывод: параллельный запуск двух кластеров на период миграции - это правильно, но дорого. Неделю держали обе версии ES, потом накатили retention и старые индексы ушли естественным путём.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.