Pull to refresh

Comments 47

Важное архитектурное замечание состоит в том, что на данный момент поддерживается запись в единственный экземпляр СУБД ClickHouse

Так а почему не построить отказоустойчивый clickhouse-кластер в Kubernetes? C load balancer(ами) и autoscaling(ом). Именно как отдельный сервис (и даже в отдельном Kubernetes-кластере), а не в рамках проекта loghouse?

Конечно так и сделаем. Планируем три основных архитектуры: standalone clickhouse (быстро и просто), clickhouse на каждой ноде (логи индексируются в локальный инстанс, подходит только для bare metal, где ноды статичны) и clickhouse cluster. Просто не все сразу.

> подходит только для bare metal, где ноды статичны

Почему ТОЛЬКО? В том же AWS(e) все можно сделать, просто записи для service discovery хранятся снаружи, например, в Route53 private zone. Ну и lifecycle_hook на «autoscaling:EC2_INSTANCE_LAUNCHING».

Слишком кратко сказал и был неверно понят. Сценарий "ClickHouse на каждой ноде" означает, что он стоит на каждой ноде Kubernetes. И fluentd читает данные из /var/log/containers и пишет в локально расположенный на этой же машине ClickHouse. Запросы делаются к распределенной таблице, которая собирает данные со всех инстансов. Бонус такого сценария — снижение нагрузки на сеть (практически до нуля) и возможность использовать дешевые локальные диски (которые часто есть в bare metal, но обычно нет в cloud). Если вероятность выхода из строя железки не высокая и логи можно терять в такой (редкой) ситуации, то этот сценарий позволяет сильно сэкономить. И по моему мнению он может быть особенно удобен для небольших кластеров на 3-7 железках, где еще не настал момент выделять отдельные ноды под логирование.


Почему я считаю, что такой сценарий не подходит для aws? Очень просто. Облака есть динамичность. Автоскейлинг. Например, у нас во всех кластерах Kubernetes в aws сейчас работает автоскейлер — днем кластер подростает, ночью сдувается. Если ставить ClickHouse на каждый узел, то при даунскейлинге надо будет пересохранять куда-то данные с этого узла. И в этом случае проще и удобней сделать отдельную (автоскейлинг) группу для кластера ClickHouse.

или fluentd + ELK/Graylog?

Ну, почему clickhouse, а не elasticsearch на самом деле можно понять. Он довольно тяжелый бывает и для очень простых случаев хотелось бы чего-то по легче, по крайне мере, мне так кажется)

Мы протестировали несколько вариантов, но они оказалось либо очень ресурсоемкими (как CPU, RAM так и дисковое пространство), либо крайне не удобными и не соответствовали нашим требованиям.
Elasticsearch оказался слишком «толстым».

fluentd + ELK/Graylog — ну так основная проблема в ELK и Graylog это ELK. Точнее сам Elastic. Мы долго и упорно пытались на разных проектах использовать Elastic, но с ним постоянные проблемы в эксплуатации (разваливающийся кластер при любом чихе) и он употребляет не меренно ресурсов. Бонус ClickHouse в том, что он практически не использует ресурсов. Разница с Elastic где-то на порядок. По сути, ClickHouse при записи создает такую же нагрузку, как простой gzip без параметров.

Формат отображения логов и возможностей было крайне недостаточно для нас в grafana.
Пришлось сделать свое решение.

Хм, а не разумнее ли было сделать свой дашбоард? Или уперлись в сам datasource плагин?

Даже не думали об этом. Это совершенно другое решение. В grafana его пихать смысла нет совсем. Мы делаем OpenSource клон http://papertrailapp.com/ для Kubernetes.

Потому что это рисователь графиков, а не утилита для мониторинга логов. Однако, у нас стоит в средне-дальнем беклоге план по grafana (и в частности по этому плагину), чтобы можно было делать визуализации по логам.

Визуализировать в Grafana можно.
На графиках удобно отслеживать интенсивность получения логов от приложений.
А вот табличная форма отображения требует доработок, т.к. встроеный плагин `table` расчитан на небольшие обьемы данных. Поэтому мы используем свой плагин таблиц, который умеет в пагинацию(отправку запросов в КХ с LIMIT N, M), кеширование ответов, визуализацию JSON в виде раскрывающегося дерева.
UFO just landed and posted this here
В данный момент loghouse не обработает миллион строчек логов в секунду.
В таком случае мы получим дикую нагрузку на диск, так как лог пишется в логи, а после чего fluentd их пишет в clickhouse. Сколько эти логи занимают места — столько они и будут занимать.
Зависит от того, сколько эти логи занимают пространства.

Как не обработает? Обработает! ClickHouse такое может даже на одном узле (правда на совсем простых данных). Цитирую:


We recommend inserting data in packets of at least 1000 rows, or no more than a single request per second. When inserting to a MergeTree table from a tab-separated dump, the insertion speed will be from 50 to 200 MB/s. If the inserted rows are around 1 Kb in size, the speed will be from 50,000 to 200,000 rows per second. If the rows are small, the performance will be higher in rows per second (on Yandex Banner System data -> 500,000 rows per second, on Graphite data -> 1,000,000 rows per second). To improve performance, you can make multiple INSERT queries in parallel, and performance will increase linearly.

Да, конечно поддерживает обратное давление! Это штатный функционал fluentd, который на данный момент используется как коллектор.


Поток данных выглядит следующим образом:


  • приложения пишут логи в stdout (12 factor, принято в kubernetes),
  • kubernetes (и docker) все это складывают в файлики локально на каждой ноде, и на этом их ответственность заканчивается,
  • fluentd запущеный на каждом узле читает файл и шлет данные каждую секунду в ClickHouse.

Соответственно, в описаном вами кейсе, скорей всего раньше ляжет нода, на которое такое приложение (забьется место на диске, там логи не жатые), чем ClickHouse в котором есть сжатие. Но в любом случае, если ClickHouse ляжет по любой причине — логи будут ждать локально, до тех пор пока он не вернется.

UFO just landed and posted this here
Но непонятна связка: kubernetes — локальный файлики. "Нода" на которой хранятся файлы это kubernetes node? Получается, что если мой компонент, который сошёл с ума забивает диск на ноде, то все остальные kubernetes pod перестают писать туда логи?

Да, все так. Это штатное поведение Kubernetes, и оно никак не относится к loghouse. Kubernetes штатно кладет лог контейнера всегда в файл в /var/log/containers (подробнее об этом тут). В Kubernetes сейчас это никак не изолировано. Наше решение занимается другой задачей — собирает логи всех контейнеров в одном месте, чтобы можно было удобно централизованно искать.


Еще непонятно что будет если pod будет перемещён на другой node. Согласно документации файлик будет удален. Это правда? Логи все таки можно будет потерять? Или у вас используется PVC для этого?

Под не может быть перемещен на другой узел в Kubernetes. Может быть удален старый под и создан новый. Логи контейнеров удаленных подов хранятся некоторое время до того, как быть удаленными.

UFO just landed and posted this here

На практике у нас таких проблем не было. Ответ искать где-то здесь: https://docs.docker.com/engine/admin/logging/overview/. Вот даже тут: https://docs.docker.com/engine/admin/logging/json-file/. Там всякие max-size, max-file и решает вопрос с размером штатно. А вот по интенсивности — мне не известно.

А почему на бекенде Ruby? Насколько мне известно практика крупных компаний показывает, что для высокой производительности он не очень подходит.
У нас в планах миграция бекенда на Go
Это бэкенд именно у веб-интерфейса (не каких-то системных компонентов типа сборщика/обработчика логов), поэтому не так критично. А Ruby, потому что с него нам было проще начинать воплощать задумки в жизнь.

Я бы ответил кратко — для быстрого прототипирования. До конца года перепишем на Go.

Есть ли в loghouse уведомления (в Slack или Telegram) при появлении определённых событий? А авторотация за определённый период?

Спасибо за вопросы!


Что касается уведомлений — думали об этом, обязательно будет, но по срокам пока совсем нет никакого понимания. Во многом это сейчас зависит от спроса. Если мы не ошиблись и с проблемами простого и удобного логирования сталкиваемся не только мы, и если loghouse пойдет в массы, думаю можно ждать эту фичу весной.


Что касается авторотации за определенный период — пока нет, но это будет буквально на днях. Можете начинать использовать, а обещаем выкатить новую версию с ротацией до того, как у вас закончится место. В структуре данных все возможности для ротации заложены (есть партиционирование по дням, можно выбрать партиционирование по меньшему периоду). Для начала будет две настройки — сколько дней хранить и какой максимальный размер занимаемого места на диске. Можно будет указывать любую или обе одновременно. Отпишем тут, когда будет готово.

Что там с авторотацией? Не вижу настройки.

Как разработчик Tabix ( может слышали ), смотрите в сторону React, но только не angular))

Привет, разработчик Tabix. Мы не просто слышали, а ставим вместе с loghouse везде Tabix, чтобы можно было посчитать что-то сложное. Типа, сколько в среднем таких-то сообщений в час с распределением по pod'ам. Ну или коды ответа HTTP, или сколько уникальных пользователей. Большое спасибо вам за Tabix!!


Что касается react/angular — ничего в этом не понимаю, но нам нужно быть максимально совместимыми со стеком Kubernetes. В перспективе хочется сделать бекенд плагином к api-серверу kubernetes, консольный интерфейс плагином к kubectl, а gui плагином к kuberentes dashboard. Последний, кстати, на angular и go — так что мы должны быть на них же, чтобы было проще получить поддержку сообщества kubernetes.

вопрос: есть ли в clickhouse полнотекстовый поиск по текстовым полям?

Нет. Классического полнотекстового поиска (токенизация, стемминг, индекс по словам) в ClickHouse, на сколько мне известно, нет. Однако ClickHouse позволяет прогнать данные через простую регулярку, и он может это сделать ооочень быстро. Поиск регуляркой среди 7 млрд записей занимает 6 ядер (12 тредов) на десяток секунд, а если локализовать (указать диапазон времени в несколько часов) — несколько сотен миллисекунд. Соответственно для логов самый раз — индексировать для настоящего полнотекстового поиска очень дорого (это куча места и вычислительных ресурсов, да и большие сложности с ротацией), запросов на запись несоизмеримо больше запросов на чтение (поэтому лучше съесть иногда чуть больше ресурсов на поиск, нежели постоянно на индексацию). Как-то так.

А минимальные требования по железу более подробно не проясните? Объем ОЗУ, место на диске и т.д.
Как таковых «минимальных» требований нет. Те лимиты, которые мы считаем минимальными (requests) описаны в value, но это не значит, что оно будет потреблять именно столько ресурсов, все зависит от количества логов.
Добрый день!
Посмотрел на ваш проект после неуспешного опыта эксплуатации ELK стека.
Действительно, ELK очень требователен к ресурсам и падает чуть больше, чем постоянно с ошибкой OutOfMemory.
Я весьма признателен за инструмент, который вы выпустили, поскольку, все что я нашел на просторах интернета в плане логов, использует elasticsearch.
Однако, после ознакомления с helm пакетом, возникло несколько вопросов:
1. Чем продиктовано использование отдельного файла namespace.yaml? Ведь helm создает namespace при инсталляции пакета.
2. Почему используется .Values.namespace вместо .Release.namespace? Ведь чем больше переменных нужно изменить, тем больше вероятность ошибки при развертывании.
3. Почему Вы используете alpha k8s API в файле loghouse-cronjob.yaml? Вроде бы возможности, которые описаны у вас в CronJob, не альфа, а установить без включения alpha feature gate ваш пакет невозможно.
4. Вы не учли возможность указания ресурсов в ингрессе и полагаете, что каждый ингресс будет отдавать приложение из корня, а это может быть не так, если используется один хост на всё. Также отсутствует возможность увказания имен секретов.

Я склонировал репозиторий и пилю сейчас helm пакет по вышеозначенным вопросам.
Но, возможно, я что-то упустил и не прав. Прошу пояснить, мои вопросы это баги, которые я нашел или фичи которые я принял за баги?
Добрый день…
Спасибо большое за интерес к нашему проекту и мы очень рады, что есть люди, которые испытывают те же потребности, что и мы.
Это все баги, связанные с тем, что это PoC. Мы будем очень рады, если вы пришлете PR или создадите Issue по любым улучшениям или вопросам.

Огромное спасибо за фидбек. Выглядит так, как буд-то вы правы по каждому пункту. Будем благодарны за pull-request или сделаем сами чуть позже.

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

Спасибо больше за статью и проект! Очень нужный стек!


Поддержку вопрос hostmaster, не рассматривали
fluentbit
как легковесный коллектор?


Также хотелось бы деталей по использованию clickhouse в кластере k8s. Какой тип волюмов используете? cephfs? есть ли проблемы с проседанием перфоманса? pod clickhouse привязан к какой-то конкретной ноде?

Спасибо больше за статью и проект! Очень нужный стек!

И вам спасибо, за интерес к проекту!


Поддержку вопрос hostmaster, не рассматривали fluentbit как легковесный коллектор?

Нет, но мы четко понимаем, что fluentd — это времянка. Сейчас мы подтвердили, что все работает и что проект нужен. Дальше заменим на что-то более эффективное. Сейчас у нас fluentd раз в секунду вызывает консольный клиент ClickHouse, до эффективности тут очень далеко :). Пока что думаем написать свой небольшой бинарь на go. А следующим шагом — добавить в этот бинарь поддержку query language, чтобы можно было сделать механизм подписок прямо на коллекторах (режим follow, который сейчас работает на polling из ClickHouse).


Также хотелось бы деталей по использованию clickhouse в кластере k8s. Какой тип волюмов используете? cephfs? есть ли проблемы с проседанием перфоманса? pod clickhouse привязан к какой-то конкретной ноде?

cephfs не нужен, если на bare metal и есть ceph — то rbd. Вообще, пока что, стараемся локально. Цифры по точному перфомансу (cpu, memory, iops, etc) выложим чуть позже, когда подготовим.

Благодарю за ответ!
По моему опыту работать с базами локально значительно проще, чем в кубере (когда дело доходит до нестандартных случаев, рекавери и прочего), но не всегда хочется деплоить доп. сервера -)


Еще вопрос на счет flunetd-clickhouse. ClickHouse ведь любит хорошо определенные структуры. Но логи то далеки от этого. Вот лог нжинкс, вы целиком в столбец таблицы кладете или как-то распарсиваете (например, чтобы было можно сделать выборку по http response code, upstream_response_time)?


Вообще хотелось бы с nginx-ingress-controller слать логи в json. И класть их в clickhouse уже в структурированном виде. Насколько это просто\сложно сделать (в рамках loghouse)?

У нас поддерживается одноуровневый JSON и поддерживаются String, Number, Bool и Nil колонки. Как мы это делаем — кратко словами не передашь. Гляньте структуру таблицы, если интересно.

А нет ли документация как поднять его в с помощю docker-compose / docker-swarm?
Т.е. что делать у кого нет kube?
который, обеспечивая хорошую производительность (10 тысяч записей в секунду при занятых в памяти 300 Мб)

Дальше даже не читал.
10 тысяч записей в секунду при 300 мегабайт памяти это ХОРОШАЯ производительность? Сepьёзнo?
Вы невежда :) В те времена не было еще vector.dev да и при чем тут производительность коллектора логов к loghouse?
Sign up to leave a comment.