Комментарии 18
Также, по-моему, у вас в описании неточность
It's nodejs-based Logstash witch suddenly stops processing logs in some conditions.
Logstash написан на Ruby, который запускается на JRuby, т.е. на JVM. А вот Kibana, да — на node.js.
Ну а вообще, респект, конечно!
Конечно, доля задора определенно была, и не маленькая. Однако всё-таки мы проводили эксперименты с ELK в связке с RabbitMQ. За двое суток синтетических тестов Logstash воткнул дважды намертво, похоже что вместе с ElasticSearch. Кроме того, скорость вставки на одной машине была подозрительно низкой, так что для планируемой нагрузки потребовался бы небольшой кластер. Кластер для логов, представляете! А еще дисковое пространство уменьшалось ну очень быстро…
Итого, вкупе с отсутствием знаний технологий, используемых внутри всех частей стека, и опыта эксплуатации, мы решили все-таки попробовать сделать своё.
Небольшое уточнение: это было примерно год назад, плюс дальше чем quickstart по настройке всего в сборе мы не копали. Так что вполне возможно, что у кого-то сбор логов работает быстро, эффективно и без глюков.
http://blog.getsentry.com/2016/05/04/breadcrumbs.html
Нагрузочные тесты проводились на персоналке, причем 90% CPU было задействовано python-процессами разбора логов.
Но давайте посчитаем :)
RabbitMQ: В статье авторов RabbitMQ описывается достижение 60К messages per second с одного двухпроцессорного сервера, так что прикидочно понадобится кластер из 8 серверов RabbitMQ.
SphinxSearch: авторы sphinxsearch пару лет назад добились сферической скорости вставки в вакууме порядка 5K строк в секунду, но это в пересчете на ядро, да и на персоналке у нас вышло быстрее. Взяв в расчет 10К инсертов в секунду, получим 40 ядер sphinxsearch, каждое ядро льет данные в свой индекс. Это 5 слабеньких таких серверов поиска.
Python(ALCO): имея примерную производительность процессов питона в 2К сообщений в секунду с одного ядра, получим 200 ядер, или 25 машин на только на предобработку данных.
Хранение: среднюю длину сообщения у нас не подскажу, а вот сфинкс на диске хранит примерно 350 байт на строку лога (в среднем). За 7 дней набегает 85ТБ индексированных данных. 5 серверов сфинкса плавно превращаются в дисковые полки, но это не самое неприятное.
Поиск: в синтетических 60млн записей full-scan фильтрация выполнялась примерно за 40 секунд (прочитать с диска все данные, отфильтровать, отобразить), это примерно 500МБайт/c в пересчете на 350-байтовые записи. В наихудшем случае с 85ТБ "поднять" всё с диска — это какие-то дикие цифры, примерно как дважды сходить пообедать, пока 40 индексов будут считываться со скоростью 500МБайт/c — в результате получим только первую страницу результатов. За второй можно приходить на следующий день :)
Не уверен, что существуют настолько большие инсталляции sphinxsearch, но тем не менее: полнотекстовый поиск теоретически должен успевать отрабатывать за обозримое время.
Кстати, можете поделиться, что Вам хотелось бы искать в этой огромной куче логов? Быть может, разбив на много-много независимых установок, Вы получите приемлемый по производительности инструмент?
Я давно и безуспешно пытаюсь построить инфрастркутуру для логирования на базе ELK, вот здесь детали:
https://habrahabr.ru/post/282866/#comment_8881108
https://habrahabr.ru/company/uteam/blog/278729/#comment_8799489
https://habrahabr.ru/post/275815/#comment_8751947
Задача была поставлена именно искать по всем логам всех сервисов, чтобы в случае проблем можно было по session_id проследить как шел запрос и где именно возникли неполадки.
чтобы в случае проблем можно было по session_id проследить как шел запрос и где именно возникли неполадки.
Эту информацию должно генерировать само приложение. Восстанавливать дерево вызовов по логам — жопа. Это неправильно.
Вам нужно искать решение из области Application performance management
И пусть вас не смущает слово performance. Там есть не только это.
Например, для Java приложений море коммерческих и свободных инструментов, которые позволяют посмотреть дерево вызовов для бизнес-транзакций. Легко понять, в каком месте бизнес-операция заняла больше всего времени.
первичные ключи специально генерируются на основе метки времени, т.к. sphinxsearch умеет «быстро» выгребать данные по диапазону id. Начиная с некоторого объема индекса, выигрыш по производительности дает индексация отдельных колонок
Расскажите как вы сделали первичный индекс и индексацию отдельных колонок, в сфинксе такого раньше не было.
index project_20160509 {
type = rt
path = /data/sphinx/project/20160509/
rt_field = logline
rt_field = js
rt_field = logger
rt_attr_string = logline
rt_attr_json = js
}
В варианте "из коробки" индекс состоит из двух полей — logline (само сообщение от логгера) и js — это словарь с данными от python logging, переданными AMQPHandler. При этом запрос
SELECT * FROM project WHERE js.logger = 'django.db.backends'
выполняется путем full-scan по атрибуту js.
В случае, когда поле logger вынесено отдельно в конфиг сфинкса, как в примере выше, запрос трансформируется вот в такой:
SELECT * FROM project WHERE MATCH('@logger "django.db.backends"')
При этом сначала по полнотекстовому индексу выбираются документы, соответствующие выбранному логгеру, а потом уже осуществляется их дополнительная фильтрация по остальным атрибутам json, указанным в запросе (если таковые имеются).
На селективной выборке и некотором довольно большом объеме это дает выигрыш относительно первого варианта, хотя приходится в charset_table добавлять символы, обычно считающиеся разделителями слов.
Чем заменить ELK для просмотра логов?