Настраиваем Graphite с хранилищем метрик в ClickHouse

Начну с того, что я очень люблю graphite, на мой взгляд это лучше решение для Time Series. У него множество достоинств, перечислять которые будет крайне долго и бессмысленно, но есть и два недостатка:

  • Оригинальные carbon и graphite-web написаны на python. Я ничего не имею против python, но опыт его использования поможет вам отлично развить навык терпения, потренировать медитативные практики и истощит запасы чая и кофе.
  • Формат хранения whisper (ceres так же) очень похож на RRD и так же плохо поддается шардированию и реплицированию. Если вы пробовали выполнить ресинхронизацию кластера carbon c миллионом метрик, то вы понимаете о чем я.

В прошлом году парни из Яндекса сделили доступным всему миру свое детище: ClickHouse— столбцовая СУБД для OLAP, в которой сейчас живут данные Яндекс.Метрики. Широко известным аналогичным коммерческим решением является HP Vertica.

Немного отвлечемся, в чем же разница между классическими (реляционными) и колоночными СУБД? Предствами себе, что у нас есть таблица в которой A, B и С — это поля (столбцы), а 1, 2 и 3 — строки. В таком случае данные будут храниться следующим образом:

Реляционные СУБД

Все строки таблицы будут хранится в виде одной записи, в которой поля идут последовательно одно за другим, а за последним полем записи в общем случае идет первое следующей записи: [A1, B1, C1], [A2, B2, C2], [A3, B3, C3]….

Такое хранение чрезвычайно удобно для частых операций добавления новых строк в базу данных. Однако, что если выбрать, например, только 3 поля из таблицы, в которой их всего 20? В силу построчного хранения данных будут прочитаны абсолютно все строки целиком со всеми полями, т.е. не важно, нужны нам только 3 поля или 20, с диска в любом случае они все будут прочитаны целиком и целиком же поступят на обработку процессору, который уже отдаст клиенту только то, что требуется.

Столбцовая СУБД

Каждый из столбцов по сути представляет собой отдельную таблицу из одного поля. При этом физически на диске значения одного поля хранятся последовательно друг за другом: [A1, A2, A3], [B1, B2, B3], [C1, C2, C3]..

Такая организация данных приводит к тому, что при выполнении выборки в которой фигурируют только 3 из 20 полей таблицы, с диска физически будут прочитаны только 3 колонки. Это означает что нагрузка на канал ввода-вывода будет приблизительно в 20/3=7 раз меньше, чем при выполнении такого же запроса в реляционной СУБД. Значительным бонусом поколоночном хранении данных так же является возможность сильно сжимать данные, так как в одной колонке таблицы данные как правило однотипные, чего не скажешь о строке. Это позволяет снизить объем хранения данных, а так же уменьшить число операций ввода-вывода, так как потребуется читать меньше данных с диска.

Теперь вернемся к graphite. Парни из Mail.Ru выложили carbon-clickhouse и graphite-clickhouse — это написанные на языке go демоны, позволяющие хранить метрики Graphite в СУБД ClickHouse. Их мы и будем использовать.

Далее я хочу поделится примером настройки Graphite с хранилищем метрик в ClickHouse на базе Ubuntu Xenial.

1. Настройка ClickHouse

На текущий момент устновить СУБД ClickHouse из пакетов можно только на Ubuntu: Trusty, Xenial или Precise. Так же доступен docker-образ.

Настраиваем репозитарий и устанаваливаем СУБД:

$ echo 'deb http://repo.yandex.ru/clickhouse/xenial stable main' > /etc/apt/sources.list.d/clickhouse.list
$ apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4
$ apt-get update
$ apt-get install clickhouse-client clickhouse-server-base clickhouse-server-common

Файлы конфигурации находятся в /etc/clickhouse-server, нам потребуется внести следующие изменения в config.xml:

<graphite_rollup>
  <!-- default -->
  <default>
    <function>avg</function>
    <retention>
      <age>0</age>
      <precision>60</precision>
    </retention>
    <retention>
      <age>864000</age>
      <precision>900</precision>
    </retention>
    <retention>
      <age>1728000</age>
      <precision>1800</precision>
    </retention>
    <retention>
      <age>3456000</age>
      <precision>3600</precision>
    </retention>
    <retention>
      <age>10368000</age>
      <precision>21600</precision>
    </retention>
    <retention>
      <age>34560000</age>
      <precision>43200</precision>
    </retention>
    <retention>
      <age>63072000</age>
      <precision>86400</precision>
    </retention>
    <retention>
      <age>94608000</age>
      <precision>604800</precision>
    </retention>
  </default>
</graphite_rollup>

Приведенный блок соответсвует следующей секции storage-schemas.conf:

[default]
pattern = .*
retentions = 1m:10d,15m:20d,30m:40d,60m:120d,360m:400d,720m:2y,1d:3y,7d:10y

Запускаем СУБД:

$ systemctl start clickhouse-server 

Теперь можно подключиться к БД:

$ clickhouse-client

И создать таблицы необходимые для работы:

CREATE TABLE graphite ( 
  Path String,  
  Value Float64,  
  Time UInt32,  
  Date Date,  
  Timestamp UInt32
) ENGINE = GraphiteMergeTree(Date, (Path, Time), 8192, 'graphite_rollup');

CREATE TABLE graphite_tree (
  Date Date,
  Level UInt32,
  Path String,
  Deleted UInt8,
  Version UInt32
) ENGINE = ReplacingMergeTree(Date, (Level, Path), 8192, Version);

На этом базовая настройка ClickHouse закончена. Настройке репликации и шардированию данных в ClickHouse позднее я посвящю отдельную заметку.

2. Сarbon-clickhouse

Основа комплекса — Сarbon-clickhouse он принимает метрики в виде tcp, udp, pickle и складывает их в ClickHouse. Написан на Go. На момент написания данной записи актуальная версия 0.6.3, сборка доступна на github:

$ wget https://github.com/lomik/carbon-clickhouse/releases/download/v0.6.3/carbon-clickhouse_0.6.3_amd64.deb
$ apt-get install $(pwd)/carbon-clickhouse_0.6.3_amd64.deb

Файл кофнигурации /etc/carbon-clickhouse/carbon-clickhouse.conf, можно произвести тюнинг производительности или работать на том что идет в инсталляции.

Запус сервиса:

$ systemctl enable carbon-clickhouse
$ systemctl start carbon-clickhouse

Если все Ок и ошибок нет, метрики начали писаться в базу.

3. Graphite-clickhouse

Следующий черед за демоном который забирает данные из БД ClickHouse и отвечает на запросы вместо graphite-web. Демон так же написан на Go, актуальная версия на текущий момент 0.4.0, сборка доступна на github:

$ wget https://github.com/lomik/graphite-clickhouse/releases/download/v0.4.0/graphite-clickhouse_0.4.0_amd64.deb
$ apt-get install $(pwd)/graphite-clickhouse_0.4.0_amd64.deb

Перед запуском необходимо создать файл /etc/graphite-clickhouse/rollup.xml, содержание которого должно повторять блок graphite_rollup из /etc/clickhouse-server/config.xml.

После чего запускаем демона:

$ systemctl enable graphite-clickhouse
$ systemctl start graphite-clickhouse

4. Carbonapi

К сожалению, graphite-clickhouse не достаточно. Необходим еще один демон написанный на Go — Carbonapi. Он выступает в роле фронтенда перед интерфейсами, такими как grafana, а так же кеширует результаты запросов используя для этого memcached или непосредственно ОЗУ.

$ curl -s https://packagecloud.io/install/repositories/go-graphite/stable/script.deb.sh | bash
$ apt-get install carbonapi

Файл конфигурации /etc/carbonapi/carbonapi.yaml.

$ systemctl enable carbonapi
$ systemctl start carbonapi

На этом все, теперь можно зайти в grafana и наслаждаться красивыми графиками, такими как этот:
grafana collectd