11 декабря 2014 в 13:29

Time Series, метрики и статистика: знакомство с InfluxDB tutorial

InfluxDB

Введение


Любому системному администратору постоянно приходится иметь дело с данными, представленными в форме временных рядов (time series): статистика скачивания файлов, статистика запросов к серверам, данные об использовании системных и аппаратных ресурсов виртуальными машинами…

Чтобы все это хранить и обрабатывать, нужен адекватный и производительный инструмент.


Для хранения временных рядов часто используются специализированные решения — так называемые time series (темпоральные) базы данных. Об их плюсах и минусах мы уже писали. Пытаясь исправить недостатки имеющихся решений, мы даже разработали собственный продукт — time series базу данных YAWNDB, которая используется в нашей системе мониторинга. Но все time series базы данных являются низкоуровневыми, а возможности их применения весьма ограничены. Во-первых, они не позволяют объединять временные ряды c данными других типов — например, со словарями. Во-вторых, они совершенно не рассчитаны на работу с большими объемами данных. В большинстве темпоральных БД даже нет языка запросов. Поэтому стандартная задача — запросить и получить нужную информацию в любой момент времени — становится очень сложной и нетривиальной. Конечно, её можно решить и без языка запросов, но это под силу только пользователям, обладающим специальными знаниями и недюжинными навыками программирования.

Для хранения временных рядов сегодня всё чаще используются так называемые NoSQL базы данных — как популярные HBase и Cassandra, так и более специализированные решения — например, OpenTSDB, KairosDB и Acunu. Возможно, в некоторых ситуациях такой вариант вполне оправдан, но для решения подавляющего большинства практических задач он вряд ли подойдёт. Все перечисленные выше БД работают на базе инфраструктуры Hadoop, и для их нормального функционирования требуется огромное количество зависимостей. Да и с производительностью у них не всё так гладко, как может показаться на первый взгляд (подробнее об этом см., например, здесь).

Как же решить проблему хранения временных рядов, метрик и статистики? Мы серьезно задумались над этим вопросом, когда подбирали вариант хранения информации о запросах к нашим NS-серверам.

Совершенно неожиданно в обсуждении нашего поста на Хабрахабре один из читателей порекомендовал NoSQL базу данных InfluxDB. Мы попробовали ее — и остались вполне довольны. Своим опытом работы с InfluxDB мы хотели бы поделитьcя в этой статье.

Общая информация


База данных InfluxDB (см. репозиторий на GitHub), написанная на языке Go — продукт новый: первый его релиз состоялся в октябре 2013 года. Она позиционируется как база данных для хранения временных рядов, метрик и информации о событиях.

В числе преимуществ InfluxDB в первую очередь нужно выделить следующие:
  • отсутствие зависимостей (следствие того, что она написана на Go);
  • возможность работы в том числе и в кластерном режиме;
  • наличие библиотек для большого числа языков программирования (Python, JavaScript, PHP, Haskell и других);
  • SQL-подобный язык запросов, с помощью которого можно производить различные операции с временными рядами (объединение, слияние, разбиение на части);
  • удобный графический интерфейс для работы с БД.


B качестве низкоуровневого хранилища пар «ключ-значение» в InfluxDB используется база данных LevelDB. Для этой цели можно также использовать RocksDB (по утверждению разработчиков InfluxDB, именно это хранилище показывает наилучшую производительность — см. отчет о тестировании здесь), и LMDB.

Записывать данные в InfluxDB можно различными способами. Во-первых, данные в формате JSON можно передавать через HTTP API. Во-вторых, InfluxDB поддерживает протокол Carbon, используемый в инструменте для обработки и визуализации данных Graphite. В-третьих, данные можно отправлять по протоколу UDP.

InfluxDB может использоваться в качестве бэкенда для Graphite, и благодаря этому можно существенно повысить его производительность. Поддерживается также возможность работы с дашбордом для метрик Grafana (более подробно об этом речь ещё пойдёт ниже).

Несомненным плюсом InfluxDB являются и широкие возможности интеграции с другими программными продуктами — например, инструментом для обработки логов Fluentd, демонами для сбора статистики CollectD и и StatsD, фреймворками для мониторинга Sensu и Shinken.

Имеются клиентские библиотеки для языков JavaScript, Ruby, Ruby on Rails, Python, Node.js, PHP, Java, Clojure, Common Lisp, Go, Scala, R, Erlang, Perl, Haskell, .NET(C#).

Создатели InfluxDB ведут активную работу по развитию и усовершенствованию продукта. На ближайшие версии запланированы следующие нововведения:
  • добавление бинарного протокола обмена данными;
  • добавление интерфейса «издатель-подписчик» (pubsub): благодаря этому появится возможность подписываться на любой запрос и получать данные по мере их поступления в виде push-уведомлений;
  • возможность индексирования столбцов;
  • возможность добавления кастомных (задаваемых пользователем) функций с помощью сценариев на языке Lua;
  • добавление функций безопасности;
  • возможность слияния данных.


Установка


Установим Influx DB и посмотрим, как её можно использовать на практике. Процедуры установки и настройки мы будем рассматривать на пример с OC Ubuntu; для других дистрибутивов Linux они могут отличаться (подробности см. в официальной документации).

Выполним следующую команду:
# для 64-битных систем
$ wget http://s3.amazonaws.com/influxdb/influxdb_latest_amd64.deb
$ sudo dpkg -i influxdb_latest_amd64.deb


# для 32-битных систем
$ wget http://s3.amazonaws.com/influxdb/influxdb_latest_i386.deb
$ sudo dpkg -i influxdb_latest_i386.deb

По завершении установки запустим InfluxDB:

$ sudo /etc/init.d/influxdb start


По умолчанию InfluxDB использует порты 8083, 8086, 8090 и 8099. Можно использовать и другие порты — для этого потребуется внести соответствующие изменения в конфигурационный файл. Рассмотрим особенности конфигурирования InfluxDB более подробно.

Настройка и конфигурирование


Все настройки InfluxDB хранятся в конфигурационном файле /opt/influxdb/current/config.toml. Они делятся на следующие группы:


[logging] — параметры логгирования (указываются уровень логгирования и имя файла лога);
[admin] — настройки веб-интерфейса (порт, на котором работает внутренний веб-сервер, и путь к файлам веб-интерфейса);
[api] — настройки HTTP API;
[input_plugins] — настройки ввода данных из внешних источников (в InfluxDB можно передавать данные, предназначенные для отправки в Graphite; также в этом разделе можно настроить ввод данных по протоколу UDP).
[raft] — настройки протокола согласования RAFT;
[storage] — общие настройки хранения данных;
[cluster] — настройки работы в кластерном режиме (более подробно они будут описаны ниже;
[wal] — настройки опережающего введения журнала (Write Ahead Logging, WAL).


Создаём базу данных


По завершении установки откроем в браузере страницу localhost:8083. Мы увидим веб-интерфейс для работы с базами данных. Выглядит он так:

InfluxDB

Введем теперь логин (root) и пароль (root) (начальные значения можно задать в конфигурационном файле до первого запуска), а затем нажмем на кнопку Connect. Откроется следующее окно:

InfluxDB

Графический интерфейс InfluxDB прост и интуитивно понятен. Обратим внимание на некоторые важные моменты, которые следует учитывать при создании первой базы данных.
Чтобы упростить и ускорить чтение данных при запросе, базу лучше разделить на составные части небольшого объема — так называемые шарды (англ. shards) Совокупность шардов, формируемых на основе одного и того же принципа, называется шардовым пространством (англ. shard space).

Создавая базу, нужно указать, какие шардовые пространства будут входить в ее состав. Данные можно делить на шарды, во-первых, по временным отрезкам. Если, например, мы будем хранить в базе информацию о действиях пользователей, то ее удобнее разбивать на временные отрезки — например, данные за каждые 7 дней будут хранится в отдельном шарде. Длина временного отрезка указывается в разделе Duration. В графе Retention указывается срок хранения шарда.

Формировать шарды можно также и с помощью регулярных выражений. Если мы храним в базе метрики по пользователям вида log.user.<id пользователя>, то отдельный шард будет создаваться на каждого пользователя — для этого нужно задать регулярное выражение /^log.user.*/.

При создании базы данных можно указывать и параметры для работы в кластере. В графе RF (эта аббревиатура означает Replication Factor — фактор репликации) указывается, на скольких узлах должна храниться копия каждого шарда в шардовом пространстве. В графе Split указывается, на сколько шардов нужно делить данные в для конкретного временного промежутка.

Чтобы каждый сервер в кластере был готов к записи «горячих» данных в любой момент времени, значение фактора репликации рекомендуется рассчитывать по следующей формуле:

RF = NoS/Split 

(RF — фактор репликации, NoS — число серверов)

Алгоритм, лежащий в основе деления данных на шарды, включает следующие шаги:

1. Программа просматривает все шардовые пространства в базе.
2. Затем она проходит все шардовые пространства циклом и ищет пространство, которому соответствуют новые данные.
3. После этого просматриваются все шарды для заданного временного интервала;
4. Если шардов не существует, то будет создано N шардов (N — число, указанное в графе split).
5. Данные записываются в шард с использованием алгоритма hash(series_name) % N.

Рекомендуется устанавливать небольшие размеры шарда по времени (duration).
Если установить для времени хранения шарда (retention) значение inf (т.е. бесконечный), этот шард никогда не будет удалён.
Установив все необходимые настройки, нажмём на кнопку Create Database.

Работа в кластере


В режиме кластера несколько серверов InfluxDB образуют единую систему. Каждый узел кластера может принимать запросы на чтение и запись. Для организации работы в кластере используется протокол согласования RAFT. Понятное и наглядное объяснение принципа его работы представлено в этой презентации.

Согласно официальной документации, в текущем релизе работа в кластере поддерживается лишь в режиме тестирования. Полноценная реализация запланирована на одну из следующих версий (0.9 или 0.10).

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

1. Запустить первый узел InfluxDB со всеми нужными настройками, но без параметра seed-servers в конфигурационном файле (раздел cluster).

2. На втором и всех последующих узлах в качестве значения параметра seed-servers указывается IP-адрес первого сервера, который должен быть запущен самостоятельно:
seed-servers = ["IP-адрес первого сервера: 8090"]

Если сервер уже был запущен без установки параметра seed-servers, то перед добавлением в кластер нужно удалить с него все данные InfluxDB (путь к данным по умолчанию: /opt/influxdb/shared/data/).
При добавлении нового узла можно указывать IP-адрес любого сервера, уже входящего в состав кластера.
Порт указываем тот же, что и в разделе [raft] (по умолчанию — 8090).

Управление правами пользователей


Возможности управления правами пользователей через графический интерфейс очень ограничены: можно только выполнять простейшие операции добавления и удаления пользователей и разрешать полный (c правами администратора) доступ.

Более тонкие настройки доступа к данным можно устанавливать только через API. Доступ к метрикам реализован в виде регулярных выражений.

Чтобы изменить доступ, нужно отправить POST-запрос в формате JSON на URL вида: influxdb.host:8086/db/<имя базы>/users/<имя пользователя>.

В схематичном виде структура запроса выглядит так:

{
"readFrom": "<регулярное выражение>",
"writeTo": <регулярное выражение>
}


Приведём пример команды для изменения настроек доступа:

$ curl' http://influxdb.host:8086/db/seriousmetrics/users/grafana?u=root&p=root' -XPOST -d '{"writeTo": "^$","readFrom": ".*"}'


Просмотреть текущие правила можно с помощью команды

$ curl 'http://influxdb.host:8086/db/seriousmetrics/users/grafana?u=root&p=root&pretty=true'


{
 "name": "grafana",
 "isAdmin": false,
 "writeTo": "^$",
 "readFrom": ".*"
}


Из полученного вывода видно, что пользователь grafana может читать все метрики (“*.”), но при этом не может ничего писать (“^$”).

Интеграция с Grafana


Grafana

Grafana представляет собой удобный дашборд для выборки и визуализации метрик. На русском языке публикаций о нём почти нет, за исключением совсем небольшой заметки на Хабре.

Специально для желающих посмотреть, как работает InfluxDB в связке с Grafana, мы подготовили сценарий (playbook) для Ansible и разместили его на GitHub.
Чтобы осуществить тестовый запуск, клонируйте репозиторий по ссылке выше, в файле hosts укажите IP-адреса машин, которые будут входить в кластер, а затем запустите скрипт run.sh. Обратите внимание, что описание конфигурации Influxdb задаётся в «родном» для Ansible формате YAML, из которого затем генерируется файл в формате TOML.

Заключение


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

Если кто-то из вас уже использует InfluxDB — приглашаем поделиться опытом в комментариях.

Читателей, которые по тем или иным причинам не имеют возможности оставлять комментарии здесь, приглашаем в наш блог.
Автор: @clickfreak
Селектел
рейтинг 280,51

Вакансии компании Селектел

Комментарии (25)

  • +3
    Вот уже несколько месяцев используется для рисования графиков вместо pnp4nagios — пара скриптов + curl, несколько дашбордов в Grafana. Также в InfluxDB скидывается статистика из collectd, в планах скидывать счетчики производительности из Windows (используя github.com/Iristyle/PerfTap + github.com/armon/statsite) и из Java-приложений (jmxtrans).

    Непонято, как всё это бекапить и, пока этот вопрос не решится, ставить в продакшен даже не-кластер побоюсь.

    Попытки поднять кластер в текущих релизах работают не всегда — несколько попыток закончились потерей данных на первом узле и неподнявшимся кластером. Если собирать из Git, то ситуация несколько лучше.

    Ещё есть интересный вопрос, как всё это будет работать с большим количеством данных — приложение написано на Go, а значит что временами будет отрабатывать Garbage Collector.

    Решение об использовании SQL-подобного языка запросов тоже кажется несколько спорным.

    Из дополнительных источников информации я бы отметил dieter.plaetinck.be/, в частности для желающих смигрировать с graphite или желающих поставит influxdb параллельно graphite.
  • +3
    Использую influxdb в одном проекте, с удовольствием поделимся опытом и обсудим впечатления. Пока что influx радует почти всем, но есть пара моментов:
    1. Все-таки весьма куцые возможности по обработке данных, выборкам, агрегатным функциям и т.п. Хотелось бы where в continuous queries, функций типа moving average, и/или какого-нибудь вообще встроенного скриптинга.
    2. Он у нас уже несколько раз падал или зависал — при условии постоянной нагрузки на запись (средней интенсивности — порядка 200 записей в секунду, пачками) и пары тяжелых запросов на чтение поверх нее. Причем, без всякий слов в логах. У вас не случалось подобного?
    • 0
      Графики машины во время падения были ок? Память в частности.
      • 0
        Да, память и подозреваю. Сейчас уже нет графиков (у меня эта машина мониторится только за сутки, надо бы свой мониторинг настроить), но память там точно кушалась (как и проц).

        Я так понимаю, influx не очень умеет справляться с ситуацией, когда ему кидают одновременно десяток-два запросов, которые заставляют его бежать по данным на сутки назад. К сожалению, та же grafana устроена так, что она закидывает его отдельными запросами для каждого графика, хотя могло бы быть намного оптимальнее.
      • 0
        Для истории оставлю это здесь: отказались от influxdb после еще пары эпизодов полной потери данных в бою.

        Influxdb в непредсказуемые моменты необъяснимо портил свои файлы данных, после чего полностью переставал запускаться. Я пообщался про это с его разработчиками, но разобраться не смогли. В итоге переехали на старый добрый mysql, разработав под него немного другую структуру данных. Все написанное относится к influxdb версии 0.8.x, на текущий момент готовится 0.9.0 (есть release candidate), но его мы не пробовали.
        • 0
          а на OpenTSDB не смотрели?
          • 0
            Смотрели, но не пробовали: показалось (?), что его будет долго и сложно разворачивать и что это некий overkill для нашей задачи.
        • 0
          ахахаха!

          Ну это вам не повезло: он у вас взлетел. У везунчиков он просто не заводится.
    • +1
      странно, наш сторадж: github.com/pulsedb/pulsedb справляется с куда более существенными нагрузками, хотя не имеет конечно такого клевого интерфейса
  • +3
    Очень внимательно слежу за этим крайне интересным проектом, но пока использовать мешают три немаленькие проблемы:
    1. сих пор нет отмены исполнения запроса при разрыве конекта,
    2. нет возможности перегенирить данные для continuous query,
    3. не решена проблема OOM для continuous query на большом объеме.
    • 0
      1. Согласен, это очень мешает
      2. Удалить его и создать заново — нормально перегенеряет
      3. Возможно, хотя у меня крутятся continuous query с кардинальностью группировки порядка 50к — вроде нормально работает.
      • 0
        Имел ввиду 'за выбранный интевал', конечно, полностью перегенеривать накладно как-то.
        Полагаю это связано с запросами на подсчет уникальных вхождений.
  • +1
    Было бы интересно увидеть сравнение производительности с Graphite.
    • 0
      Видел в сети сравнение со стабильной версией graphite — на больших объемах influxdb быстрее.
      В целом графит это отдельная песня. Тоже слежу очень вниамтельно: он где-то год лежал мертвецом, летом вроде бы разработка активизировалась. Нас ждет много интересных плюшек.
      Не исключаю что новая версия будет на уровне. Не исключено, что скажутся особенности стека технологий. Go разрабатывался как язык для параллельных вычислений. Python же со своим GIL порой вгоняет в беспросветную тоску.
  • +1
    Пара комментариев.
    1. Текущая версия 0.8.7 (и все ниже) написаны не на чистом Go. Чистый Go будет начиная с версии 0.9.0 (http://influxdb.com/blog/2014/12/08/clustering_tags_and_enhancements_in_0_9_0.html)
    2. Также начиная с версии 0.9.0 произойдет переход на BoltDB как единственный вариант стораджа. LevelDB, RocksDB, HyperLevelDB и LMDB больше поддерживаться не будут (обещают предоставить средства миграции)

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

    Поддержку пользователя smart — был период когда Инфлюкс сходил с ума, кушал весь CPU, по логам разобраться в чем причина не удалось. Переписали некоторые запросы, и еще местами пошаманили и с тех пор полет нормальный.

    Нас немного расстроил отказ от LevelDB, так как он позволяет очень компактно хранить данные, в нашем случае ограниченного места это очень важно.
  • 0
    Используем для того же OrientDB (http://www.orientechnologies.com/orientdb/) и Orienteer (http://orienteer.org/). Не без собственных костылей, но зато можно использовать преимущества OrientDB: key-value/document/graph DB/RDBM в одном флаконе + масштабируемость.
    За наводку спасибо! Весьма интересно особенно «синтаксический сахар» в InfluxDB SQL для временных данных…
  • +2
    Из переписки с одной австралийской компанией:

    Does that interest you?
    We are currently working on an open source TSDB:
    github.com/anchor/vaultaire/tree/v2

    > Yes, it is interesting,
    > I review code, you are use cerph as distributed store,
    > but why not using InfuxDB? ( influxdb.com )

    We chose to build our own TSDB after evaluating a few, such as influxdb and
    finding them immature/unstable/etc. We could not get influxdb to build at the
    time, and fixed a few bugs before giving up. We already have Ceph rolled out
    internally as a data store and trust it to replicate data without losing it. I
    will be releasing a blog post shortly on the subject, I'll send you a copy.


    Собственно парни работают в аналогичной сфере что и вы.
    Тут можно прочитать про их TSDB,
    Исходники на github, язык реализации haskell.
    • +1
      We could not get influxdb to build at the time, and fixed a few bugs before giving up.
      Я тут несколько месяцев назад собирал InfluxDB под ARM, и вы даже не представляете, что я испытал. Эти ребята вообще не знают, что существуют системы сборки. Я буквально переписывал makefile.
      • 0
        Ну с другой стороны концепт обещает быть весьма интересным.

        В мой проект, в качестве хранилища для метрик, он у меня вписался как влитой.
        В процессе разработки пока удобно, буду ближе к релизу, буду думать, оставлять его или менять на что-нибудь другое (архитектура позволяет, код привязки строк 150).

        А так да, сыроват, эпизодически странно себя ведет.
      • 0
        А под windows не пробовал собирать? Я собрать то собрал, да только даже консоли 8083 нет. Хотя «exe» запускаются.
        • 0
          Нет
  • 0
    Интересует сравнение с Графитом.
    • +2
      Ну это немного разные вещи все-таки: graphite именно для графиков и измерений, а influxdb — почти база данных, с выборками разными. По фичам в influxdb пока сильно не хватает функций для обработки данных, например банальной moving average.
  • +1
    Вот небольшая и легковесная Time Series DB: github.com/Akumuli/libakumuli via Lazin

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное