На первый взгляд, кажется довольно странным, что сейчас, в 2015 году, все до сих пор используют для хранения time series такой старый и «не модный» инструмент, как Graphite. О ужас, о нем даже почти не пишут в твиттере/G+ и он написан на старом будничном Python, а не на популярном сейчас Go (хотя уже частично написан, но об этом потом).

Но все равно многие используют его, и не сильно жалуются.

Экскурс в историю

До открытия кода Graphite в 2008 году был вездесущий RRDTool, использовавшийся (и используемый до сих пор) в таких инструментах как Cacti, Munin и еще в куче других. Этот самый RRDTool был первой популярной базой для хранения time series, и вполне хорошо с этой задачей справлялся.

Когда в 2008 году открывают код Graphite, который развивался как внутренний продукт с 2006 года, он становится популярен не потому, что это аналог RRDTool (сам компонент Graphite, отвечающий за хранение данных - Whisper - не сильно отличается от RRDTool), а в первую очередь потому, что был полноценным сервисом с простым API и набором функций для работы с данными на все случаи жизни.

Это становится этакой маленькой революцией, и мир мониторинга начинает свое неуклонное движение к модульной структуре, когда за отдельный функционал отвечает отдельный инструмент. Тут я не могу удержаться и не дать ссылку на очень понравившуюся мне презентацию на тему модульности мониторинга.

Если хочется еще немного прочитать про историю Graphite - рекомендую книгу "Архитектура приложений с открытым исходным кодом", глава про Graphite.

Личный опыт

Я не буду тут приводить банальные команды для установки Graphite на уютный локалхост или копировать официальную документацию, а напишу о том, с чем сам столкнулся в процессе работы и что показалось мне достойным упоминания.

При этом хочу отметить, что установка Graphite из репо или pip это весьма сомнительное удовольствие. Но, к моему большому админскому счастью, в Debian провели колоссальную работу и упаковали graphite и все его компоненты в пакеты, так что писать тут больше не о чем.

Ну а раз уж начали, поговорим и о других его недостатках.

Например, нельзя просто класть туда разные значения одних и тех же метрик параллельно или чаще раза в секунду - Graphite оперирует секундами как минимальными квантами времени, так что если попытаться с интервалом меньше чем одна секунда положить туда несколько значений, то значения не суммируются, а запишется только последнее. Для обхода этой проблемы придумали StatsD и аналогичные сервисы, которые получают кучу метрик, делают агрегацию на лету, и шлют в Graphite уже готовые значения.

Вот вроде бы очевидная вещь, но я годами использовал Graphite только для хранения метрик с серверов с разрешением около 15 секунд, и даже не подозревал об этой проблеме, так что существование сервисов типа StatsD казалось мне бессмысленным. А ведь если посмотреть на это с позиции разработчика, чей сервис шлет метрики на каждый чих, проблема видна сразу.

Также в недостатки Graphite можно записать достаточно примитивную древовидную иерархическую организацию метрик. Сейчас у конкурентов принято на каждую метрику вешать произвольный набор тегов, по которым затем проводить выборки и агрегации.

Если быть честным, то это действительно недостаток, но отнюдь не фатальный, и жить с ним можно вполне хорошо.

Еще можно отметить унылый веб-интерфейс на Django, но есть куча достойных дашбордов, что делает этот недостаток абсолютно несущественным.

Киллер-фичи

Ну а теперь перейдем к тем самым киллер-фичам, которые меня в нем до сих пор очень радуют.

Самая наверное из них недооцененная и мной любимая - это функция timeshift. Эта функция позволяет получать данные со смещением назад во времени, так что на одном графике можно совместить некую метрику сегодня и в этот же день на прошлой неделе. И на таких вот графиках без всяких продвинутых инструментов анализа зачастую видно, что что-то у нас поломалось, либо наоборот стало лучше. Да и в проверках эту функцию использовать удобно. Подробнее и с картинками - в отличном цикле статей про Graphite, выпуск 10.

Причем что характерно - у конкурентов типа Influxdb подобного функционала пока нет, так что трудягам в Grafana пришлось делать схожий функционал на стороне клиента.

Вторая фича. которая приходит сразу на ум - гибко настраиваемые периоды хранения данных с последующей агрегацией по различным алгоритмам, что позволяет хранить метрики очень долго, не теряя их значений, и не тратить на это тонны дискового пространства. Вспоминая, как с этим все плохо в том же Zabbix, и глядя на конкурентов, у которых этот функционал только в feature-requests висит, проникаешься к Graphite искренней любовью.

Отдельно хочется отметить фантастически простой формат, в котором Graphite получает метрики:

metric_path value timestamp\n

например

foo.bar.baz 42 74857843

На практике это означает, что слать метрики в Graphite можно хоть из bash-скрипта, используя в качестве клиента любимый netcat.

Ну и еще приятная особенность - за счет простоты формата и популярности Graphite, сегодня слать в него метрики умеет практически каждая кофеварка. Возьмем любой популярный агент мониторинга, например Collectd или Diamond, и увидим нативную поддержку отправки данных в Graphite. А еще Graphite/Carbon умеет забирать данные из AMQP, что тоже очень удобно и используется тем же Sensu.

И последняя в списке, но далеко не последняя по значимости особенность - Graphite модульный. На практике это означает, что можно (и многие так делают) заменить carbon на Influxb или на весьма интересную разработку ребят из Mail.ru - go-carbon.

Конкуренты

Теперь немного о конкурентах Graphite, которых сейчас не то чтобы много, но они есть. Этой весной я предпринял достаточно серьезную попытку заменить Graphite в мониторинге с помощью имеющихся альтернатив, и как, вы можете догадаться, не очень в этом преуспел.

Начал я с модного и молодежного Influxb, который как раз в апреле обещался выйти версии 0.9 с продакшн-версией кластеризации. Пробовал я его в версии 0.9rc20+, так как официальный сайт рекомендовал использовать именно новую, переписанную версию. Так вот, продукт был очень сырой. Данные по протоколу Graphite начинали записываться со все более нарастающим лагом, вплоть до нескольких суток (на версии 0.8 этого бага не было), создание новых баз работало только из консольного клиента, функция Derivative считала что угодно, но только не производную, причем в обоих версиях. Некоторого функционала Graphite, например timeshift, просто нет, а кластеризация даже сейчас, после стабильного релиза, находится в состоянии альфа-версии. К тому же, нормальной поддержки Influxdb 0.9 в используемом мной дашборде Grafana тогда тоже не было, так что я отложил знакомство с ним до лучших времен.

Расстроенный ситуацией с Influxdb, я обратил свой взор на нового и весьма перспективного игрока на этом поприще - Prometheus от Soundcloud. Тут уже не просто хранилище time series, а полноценная система мониторинга, с алертами, дашбордами и сервисами для сбора метрик. Причем их хранилище, так же как и Influxdb, позволяет на метрику вешать произвольный набор тегов, но при этом по их тестам тратит на это в разы меньше места на диске. Одна только особенность меня смущала - pull-режим. Если в Graphite мы шлем данные любым удобным нам способом, то Prometheus сам ходит на все настроенные endpointы и получает оттуда метрики. Есть весьма годная статья про pull vs push мониторинг, http://www.boxever.com/push-vs-pull-for-monitoring, и я с ней даже согласен, но мне на данном этапе push-модель кажется более удобной - настроил один раз сервер принимающий метрики, и только добавляешь клиентов.

Так вот, с этим Prometheus я вдоволь поигрался, даже написал Exporter для Apache Traffic Server, и могу уверенно сказать - продукт хороший, сделаный для людей, с понятным синтаксисом запросов и встроенным Alert-Manager. За несколько месяцев тестовой эксплуатации ни разу не упал, все описанные в документации возможности работают как заявлено. Динамично развивается, и уже сейчас может отлично заменить в некоторых случаях Graphite + Nagios/Icinga. Но тащить в продакшн (это же мониторинг, он падать не должен) такую экспериментальную штуку, про которую никто кроме меня толком ничего не знает, было бы очень наивно. Но я внимательно слежу за этим продуктом, и считаю, что его ждет большое будущее.

Еще хочется отметить проект Bosun от StackExchange. Он использует для хранения OpenTSDB или Graphite, и по сути представляет собой продвинутый движок для алертов, с возможностью получения метрик от собственного софта для их сбора - scollector. Меня он тогда не очень заинтересовал, поскольку искал я замену Graphite, а не алерты к нему, но проект вроде достаточно зрелый.

Ну и повторюсь про один такой большой минус всех альтернатив - они не умеют storage aggregation, то есть старые данные можно только удалять, нет никакой возможности хранить их с меньшим разрешением. Правда, для Influxdb я нашел вопрос про это на форуме, даже с ответом, но с имеющейся документацией мне не удалось найти, как же это сделать на практике (правда, я не особо искал).

Grafana

Немного о дашборде, который я использую с Graphite - это прекрасный продукт под названием Grafana.

Пользуюсь я им уже давно, так что не могу даже вспомнить, какие альтернативы ему я рассматривал. Но у него столько достоинств, что ни разу не было желания его на что-то заменить.

Кроме того, что он красив, быстр и удобен, он еще и поддерживает далеко не только Graphite. Официально из «из коробки» поддерживается OpenTSDB, Influxdb, причем уже и 0.8, и 0.9, а также Elasticsearch и, с помощью плагина, Prometheus.

Очень полезной и регулярно мной используемой функцией Grafana является возможность создания параметризованых дашбордов. То есть мы можем определить набор переменных, значения которых получаются из query к тому же Graphite, которые мы можем использовать в запросах. Например, получив список серверов из древовидной иерархии Graphite, можно создать стандартный дашборд системных метрик, и просто выбирать интересующий сервер.

Также хочется отметить богатый API для создания дашбордов «на лету», позволяющий в простом JSON-виде задавать все нужные параметры новых дашбордов - это мы тоже активно используем.

Ну и еще одна крутейшая вещь - аннотации. Это привязанные к конкретному моменту времени события, получаемые из Graphite Events, или, в моем случае, из Elasticsearch.

Представим, что мы деплоим регулярно новые версии приложения на сервера, и хотим соотносить эти события с метриками этой самой системы и серверов, на которых все крутится. Для реализации этой крайне удобной вещи достаточно при деплое писать в Elasticsearch (или в сам Graphite) eventы с описанием события (деплой такой-то версии приложения, например), и добавить на дашборд в Grafana аннотации из этого источника - и вуаля, можно с уверенностью показывать разработчику, что именно после деплоя этой версии какой-то метод API работает в 2 раза дольше. или что потребление памяти упало на 20%.

Я, к примеру, шлю события при делое в Elasticsearch из Ansible, причем самым простым способом:

- name: create deploy event in elasticsearch
  command: >
    curl -s -S -XPOST -d '
      {
        "service" : "{{ service }}",
        "version" : "{{ version }}",
        "timestamp" : "{{ ansible_date_time.iso8601 }}",
        "desc" : "Deploy {{ deploy_type }} to {{ env }}",
        "tags" : [
          "{{ service }}",
          "backend",
          {{ '"migrate",' if migrate is defined else ''}}
          {{ '"backup",' if backup is defined else '' }}
          "{{ version }}"]
      }' http://{{ log_host }}:9200/events-{{ ansible_date_time.date }}/deploy/
  ignore_errors: true

Заключение

В общем, за более чем 2 года постоянного использования Graphite, я убедился в исключительных качествах этого продукта, и несмотря на тягу ко всему новому, так и не смог заменить его каким-либо другим проектом.

Я использовал Graphite с Sensu и с Collectd, и всегда был очень доволен результатом.

Конечно, познав удобство Graphite и Grafana, решения типа Cacti, Munin или Zabbix вспоминаются с ужасом. Привыкнув к возможности совместить на одном графике использование CPU на одном сервере и задержки получения ответа от базы на другом сервере, уже не хочется возвращаться к обычным графикам серверных метрик. Ведь мы собираем метрики не для красоты, а для удобства анализа состояния продукта.

Поэтому хочется повторить слова, которые я неоднократно слышал от айтишников крупных проектов на различных конференциях и докладах:

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


Comments

comments powered by Disqus