Comments 42
Про количество логов:
У вас монолит или SOA. 1-10 «юнитов» которые сыпят логи. Логично что при переходе на микросервисы уникальное количество «юнитов» — возрастёт, минимум в 3 раза. Плюс горизонтальное маштабирование каждого юнита. Плюс distributed(request) tracing.
Ну это реально очевидно, если просто подумать.
Не надо читать про «классные переходы» на микросервисы. Надо думать надо оно вам или нет, какая выгода для бизнеса и команды будет от этого перехода. И «рост издержек» от увеличения трафика логов — поверьте, это 1% от того, с чем можно столкнуться если не правильно провести анализ. Не надо работать по статьям. Надо работать головой.
По вашим комментариям сформировывается образ человека который отвергает новые технологии/альтернативные пути. Могу предположить что докер для вас был занозой в одном месте, а когда все заговорили про kubernetes и микросервисы — вообще наступила депрессия. «опять эти новые тренды и хипстеры». Вот по этому я и написал немного с токсичностью.
Кстати оценку IQ по комментариям я не провожу, Вам показалось.
Тюнинг Elasticsearch не настолько крут, что бы об этом писать. Вся кастомизация заключается в настройке кластера и индексов под профиль нагрузки, с указанием удобный watermark'ов, threshold'ов и отключением автоматической балансировки.
Logstash — был изначально, на переправе решили коней не менять, так как на нем достаточно большой уровень логики в части обогащения и упрощения логов. Если съезжать, то это отдельный проект на несколько месяцев, профита от которого, с точки зрения бизнеса, не будет вообще.
На fluentd смотрели, когда начинали модернизацию, оценили трудозатраты на переделку всего и поняли, что овчинка выделки не стоит. Возможно пересмотрим еще в будущем, так как сейчас уже вернули rsyslog вместо filebeat по некоторым направлениям.
Но раз нет кубера, я бы тоже не стал заморачиваться с переходом на Fluentd.
1. Микросервисы пишут логи в формате json в stdout (написана общая библиотека под наши платформы, которая занимается генерацией json, — Node.js, Java, Python, .NET Core).
2. Docker демон настроен слать логи в 172.17.0.1 по протоколу Gelf по UDP без сжатия (показал себя с лучшей стороны в части производительности).
3. На каждом сервере запущен Logstash (Shipper), который слушает Gelf/UDP трафик и принимает логи от Docker демона. Понимаю, что Logstash выглядит как оверкилл, но в нашем случае хосты достаточно большие (по 130+ контейнеров на хост, Nx64GB RAM), время его запуска мало, а буферизировать в себе он может достаточное для нас количество логов (это если логгинг кластер недоступен).
4. Эти инстансы Logstash (Shippers, из #3) никак логи не модифицируют, только добавляют пару тэгов и отправляют в кластер логгирования, в Redis в различные Redis Lists в зависимости от тегов.
5. На стороне логгинг кластера логи приезжают в Redis (используем standalone инстансы).
6. Далее инстансы Logstash (Indexer) забирают логи из Redis, обрабатывают их (фильтры Json, Grok) и складывают в различные индексы кластера Elasticsearch.
7. Дополнительно есть Elastalert, который имеет кучу правил и если что не так — шлет нам сообщения.
Несколько замечаний:
1. Идея писать логи сразу в формате Json оказалась очень удачной — с одной стороны, используя глобальные общие библиотеки для логгирования, мы можем достаточно хорошо стандартизировать основную часть логов (у нас более 550 различных микросервисов), а с другой стороны — дать гибкость в добавлении любого количества кастомных полей к лог-записям.
2. Через Redis мы также пропускаем логи из различных Filebeat.
3. Все компоненты системы логгирования (да и вообще всё у нас) запущены в Docker контейнерах
4. У нас нет Kubernetes/etc. Старый добрый (на самом деле нет) Swarm (это который ещё до Docker Swarm Mode).
— возможность накапливать логи какое-то продолжительное время в случае проблем с лог-кластером
— возможность повторно направить логи, если индекс по какой-то причине умер (ни разу не пользовались правда еще)
У нас сейчас 1.5Тб логово во временном хранилище. Нам это обходится в 3000 рублей в месяц (аренда серверов, дополнительные диски для кафки). Поэтому redis вообще не вариант.
Теперь по пунктам.
1. Аналогично. У нас на уровне платформы реализовано аналогично. И да, это очень удобно когда все логи в едином формате. У нас еще есть небольшие проблемы с логами монолита, но это временно.
2. У нас за логи отвечает Nomad, он их складывает в определенном месте, где их filebeat по маске отправляет в кафку
4. Тэги в зависимости от хоста или от контейнера?
5. А сколько у вас инстансов Redis? Какой объем памяти? Если падает редис, поток логов переключается на другой инстанс? Сколько логов (по времени) может 1 инстанс продержать и какая политика по удалению старых?
7. Elastalert так и не попробовали. Хватает Prometheus+AlertManager его родной + слерты из графаны бэкапом.
4. Тэги в зависимости от хоста или от контейнера?
У нас в локальный Logstash (Shipper) данные входят не только от Docker демона, но и, к примеру, от HAProxy (он не умеет в stdout, так что наш Logstash слушает отдельный порт — Syslog/UDP). То есть, тэги присваиваются в зависимости от того, откуда пришел эвент.
А сколько у вас инстансов Redis?
В проде — 4. Средний объем входящих логов в день — 100-150ГБ. Храним в Эластике последний месяц, но индексы старше недели закрываем.
Какой объем памяти?
Redis контейнеры у нас запущены на тех же хостах, что и некоторые остальные компоненты логгинг платформы, так что им не вся память отдана. Но большую часть времени они пустые и в них задерживается не больше сотни эвентов — остальное выгребается Logstash.
Если падает редис, поток логов переключается на другой инстанс?
По умолчанию, Losgtash (Shipper) шлёт логи в Redis по принципу Round robin, так что нагрузка сразу распределяется. Если инстанс Redis отгнивает по какой-то причине, Logstash очень быстро это обнаруживает и перестает слать в этот инстанс логи.
Сколько логов (по времени) может 1 инстанс продержать?
Наш практический опыт — чуть более часа с недоступным Elasticsearch. Прошло всё нормально — после включения кластера, естественно, был большой всплеск нагрузки, но, насколько мы разобрались, мы ничего не потеряли.
у нас есть метрики для инфраструктурного кластера и скрипты для полуавтоматической починки типичных проблем.Рассмешили. То есть действовать так, чтобы типичных проблем не возникало — это даже рассматривается. А вот чинить в полуручном режиме — к этому готовы.
Ну, в принципе понятно. Если админу не надо ничего периодически чинить, то он как бы и не нужен. Да и тысячи тонн логов в одной большой компостной куче тоже становятся не очень нужны.
Поэтому я бы не был бы так категоричен в своих высказываниях, потому что по моему опыту категоричные люди делятся на две категории: супер-боги-знающие-всё и те, кто просто ещё не встретил свой «пистолет с большой мушкой» на своём профессиональном пути.
А были какие-то мысли, как уменьшить количество записываемых и сохраняемых логов?
Первая мысль, которая приходит ко мне в голову — сэмплирование трассировок для проверки производительности. Раз логи проходят через кафку, то можно большую часть успешно выполненных запросов просто выкидывать (выкинуть всё межсервисное взаимодействие, логи БД итд, оставляя только запись на входящий nginx), не записывая никуда, они не очень нужны.
У меня идея такая, что если запрос успешно завершился, то это можно понять, вычитав логи по данному запросу из кафки максимум за минуту после запроса, ведь так? Соответственно можно написать относительно простой фильтр-консьюмер, который будет фильтровать логи трассировок из входящей очереди (фильтры можно легко пошардить по reqid, чтоб можно было масштабировать по числу ядер) и перекладывать уже в очередь из которой вычитывает логстеш. Если попало под паттерн семплирования (500я ошибка/время выполнения большое/req_id кратен 1000, итд) — оставляем весь трейс, не попало — выкидываем в мусорку. ЕМНИП Cloudflare про что-то подобное рассказывали.
С другой стороны — это лишнее копирование трейсов из очереди в очередь, и я не знаю, есть ли готовые кирпичики, чтоб это быстро сделать.
По сути, имея такой объем, можно интересные штуки делать. К примеру, всевозможные штуки по юзерам считать, используя логи с фронта, или по логам внутренних сервисов отслеживать проблемы ранее, чем это покажет мониторинг по пороговым значениям?
Мы сейчас начинаем развивать направление по предсказания завершения капасити кластеров на основе метрик node_exporter'а.
А в чем сложность обрабатывать 50 мегабайт текстовых данных в секунду? Я в однопотоке парсю и валидирую (tsv) данные быстрее чем ссд (400МБ/с +-) может предоставить. Если замасштабировать на типичные 10-20 потоков то процессор уже не будет узким горлышком. Серверная часть тоже не должна вносить много оверхеда если даже на asio делать.
Обработка по запросу — оно и по-запросу, это запрос событие раз в неделю судя по статье, поэтому скоростью можно пренебречь (да и выборка скорее всего будет небольшая исходя из даты и времени).
Фильтрация — штука дешевая если все правила плюс одна сточка из лога помещаются в кэш L1 процессора, а они скорее всего поместятся, если не будет дополнительных фоновых процессов жадных к кэшу процессора.
Однопоточная архивация это около 1ГБ\с, в зависимости от данных, но можно поискать алгоритмы и побыстрее, например с предварительно обученными на логах словарями.
Вобщем можно свелосипедить экономически выгодное решение решение для замены 10 сетевых нод на 1 (Кажется подобный велосипед делал Антон Полухин antoshkka в яндексе для эффективной замены logstash, гдето в сети была презентация).
Типичный пример из моей практики: примерно 50 ТБ логов на одной машинке (это несколько месяцев). И часто нужно искать за фиг знает какое число и по какому-то ключу и куче условий быстро, т.к. разработчики не хотят ждать дольше единиц секунд. А легкие запросы — сотни миллисекунд. И вот тут все упирается далеко не в процессор (хотя и он нагружен тоже нормально так).
И вот тут все упирается далеко не в процессор (хотя и он нагружен тоже нормально так).
Так и я о том же. Не ясно зачем нужен кластер на 10 нод (плюс сеть и балансер для них) уж лучше raid на 10 NVME.
Одной машины (+еще одну хотя бы как можно дальше для отказоустойчивости) вполне может хватить, но тут вопрос по сложности нагрузки читающих запросов. Мы несколько лет назад пробовали эти данные на ELK положить, он не смог на ~20-40 где-то серваках. А тут справляется 1 (+1 реплика) (но там железо разное, нельзя 1к1 сравнивать в штуках).
Вообще, я в чём-то с вами согласен — мне тоже давно кажется, что logstash не сильно оптимально написан (хотя, опять же, у нас там кое-где скрипты предобработки выполняются — к примеру, для классификации страниц для просчёта SLA по их типам). Но elasitc corp пилять во всю новые версии со всякими улучшениями производительности и планы по обновлению на последние версии у нас есть.
Как мы в ЦИАН укрощали терабайты логов