Всем привет! В своей прошлой статье я писал об организации модульной системы мониторинга для микросервисной архитектуры. Ничего не стоит на месте, наш проект постоянно растёт, и количество хранимых метрик — тоже. Как мы организовали переход с Graphite+Whisper на Graphite+ClickHouse в условиях высоких нагрузок, об ожиданиях от него и результатах миграции читайте под катом.   Прежде чем я расскажу, как мы организовали переход от хранения метрик в Graphite+Whisper на Graphite+ClickHouse, хотелось бы дать информацию о причинах принятия подобного решения и о тех минусах Whisper, с которыми мы жили в течение продолжительного времени. 1. Высокая нагрузка на дисковую подсистему На момент перехода к нам прилетало примерно 1.5 млн метрик в минуту. С таким потоком дисковая утилизация на серверах была равна ~30%. В целом это было вполне приемлемо — все работало стабильно, быстро писалось, быстро читалось… До того момента, пока одна из команд разработки не выкатила новую фичу и не стала отправлять нам 10 млн метрик в минуту. Вот тогда-то дисковая подсистема поднапряглась, и мы увидели 100% утилизации. Проблему удалось быстро решить, но осадочек остался. 2. Отсутствие репликации и консистентности Скорее всего как и все, кто использует/использовал Graphite+Whisper, мы лили одинаковый поток метрик сразу на несколько серверов Graphite с целью создания отказоустойчивости. И с этим особых проблем не было — до момента, когда один из серверов по какой-либо причине не падал. Иногда мы успевали поднять упавший сервер достаточно быстро, и carbon-c-relay успевал заливать в него метрики из своего кэша, а иногда нет. И тогда в метриках была дыра, которую мы затягивали rsync`ом. Процедура была достаточно долгой. Спасало только то, что происходило подобное очень редко. Также мы периодически брали рандомный набор метрик и сравнивали их другими такими же на соседних нодах кластера. Примерно в 5% случаев несколько значений различались, что нас не очень радовало. 3. Большой объем занимаемого места Так как мы пишем в Graphite не только инфраструктурные, но и бизнес-метрики (а теперь ещё и метрики из Kubernetes), то довольно часто получаем ситуацию, при которой в метрике присутствуют только несколько значений, а .wsp-файл создается с учетом всего retention периода, и занимает предвыделенный объем места, который у нас был равен ~2Мб. Проблема усугубляется ещё и тем, что подобных файлов со временем появляется очень много, и при построении отчетов по ним на чтение пустых точек уходит много времени и ресурсов. Сразу хотелось бы отметить что с проблемами, описанными выше, можно бороться различными методами и с разной степенью эффективности, но чем больше к вам начинает поступать данных, тем сильнее они обостряются. Имея все вышеперечисленное (с учетом предыдущей статьи), а также постоянный рост количества получаемых метрик, желание перевести все метрики к интервалу хранения в 30 сек. (при необходимости — до 10 сек.), мы решили попробовать Graphite+ClickHouse в качестве перспективной альтернативы Whisper. Посетив несколько митапов ребят из Яндекса, прочитав пару статей на Хабре, прошерстив документацию и найдя вменяемые компоненты для обвязки ClickHouse под Graphite, мы решили действовать! Хотелось получить следующее: Достаточно амбициозно, правда?  Для получения данных по протоколу Graphite и последующей записи их в ClickHouse, был выбран carbon-clickhouse (golang).  В качестве базы данных для хранения временных рядов был выбран последний на тот момент релиз ClickHouse стабильной версии 1.1.54253. При работе с ним были проблемы: в логи сыпало гору ошибок, и было не совсем понятно что с ними делать. В обсуждении с Романом Ломоносовым (автор carbon-clickhouse, graphite-clickhouse и еще много-много чего) был выбран более старый релиз 1.1.54236. Ошибки пропали — все стало работать на ура. Для чтения данных из ClickHouse был выбран graphite-сlickhouse (golang). В качестве API-интерфейса для Graphite — carbonapi (golang). Для организации репликации между таблицами ClickHouse был использован zookeeper. Для маршрутизации метрик мы оставили нами горячо любимый carbon-c-relay (С) (см. прошлую статью).  “graphite” — база данных, созданная нами для таблиц мониторинга.  “graphite.metrics” — таблица с движком ReplicatedReplacingMergeTree (реплицируемый ReplacingMergeTree). В данной таблице хранятся имена метрик и пути до них. “graphite.data” — таблица с движком ReplicatedGraphiteMergeTree (реплицируемый GraphiteMergeTree). В данной таблице хранятся значения метрик. “graphite.date_metrics” — таблица, заполняемая по условию, с движком ReplicatedReplacingMergeTree. В эту таблицу записываются имена всех метрики, которые встретились за сутки. Причины создания описаны в разделе «Проблемы» в конце этой статьи. “graphite.data_stat” — таблица, заполняемая по условию, с движком ReplicatedAggregatingMergeTree (реплицируемый AggregatingMergeTree). В эту таблицу записывается количество входящих метрик, с разбивкой до 4 уровня вложенности.  Как мы помним из ожиданий от данного проекта, переход на ClickHouse должен быть без даунтаймов, соответственно, мы должны были каким-то образом переключить всю нашу систему мониторинга на новое хранилище максимально прозрачно для наших пользователей.
Сделали мы это так.  В carbon-c-relay добавили правило отправлять дополнительный поток метрик в carbon-clickhouse одного из серверов, участвующих в репликации ClickHouse таблиц. Написали небольшой скрипт на python, который с помощью библиотеки whisper-dump вычитывал все .wsp-файлы из нашего хранилища и отправлял эти данные в вышеописанный carbon-clickhouse в 24 потока. Количество принимаемых значений метрик в carbon-clickhouse, достигало в 125 млн/мин., и ClickHouse даже не вспотел. Создали отдельный DataSource в Grafana с целью отладки функций, использующихся в существующих дашбордах. Выявили список функций, которые мы использовали, но они не были реализованы в carbonapi. Дописали эти функции, и отправили PR`ы авторам carbonapi (отдельное им спасибо). снизили утилизацию дисковой подсистемы с 30% до 1%; 

 В нашем случае не обошлось и без подводных камней. Вот с чем мы столкнулись после перехода.  С версии 1.1.0 Graphite стал официально поддерживать теги. И мы активно думаем над тем, что и как надо сделать чтобы поддержать эту инициативу в стеке graphite+clickhouse. На базе описанной выше инфраструктуры, мы реализовали прототип детектора аномалий, и он работает! Но о нем — в следующей статье.  Подписывайтесь, жмите стрелку вверх и будьте счастливы!