Макс Лапшин (levgem) wrote,
Макс Лапшин
levgem

Categories:

Метрики, графики, статистика

Уже почти год эрливидео умеет рисовать всякие графики: отдача по сети, количество клиентов и т.п.

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

Итак, какая ситуация вырисовывается с бесконечными метриками и замерами.

TL;DR отдельно решается задача усреднения замеров отдельных HTTP запросов до красивого графика и отдельно решается задача хранения данных для построения графиков. statsd, rrdtool, whisper(graphite), opentsdb, pulsedb.



Временные ряды



Есть две разных задачи:
1) сохранить, достать и нарисовать равномерный временной ряд
2) сгенерировать равномерный временной ряд из неравномерного временного ряда

Временной ряд — это набор упорядоченных пар (time,value).
Равномерный — это когда расстояния между соседними time в ряду постоянные. Т.е. раз в секунду, раз в 5 секунд и т.п. Тут надо сделать небольшое допущение на разрывы между областями равномерности, например всю ночь не было данных.

Описанные выше задачи действительно разные и решаются разными средствами. Поясню, почему я так говорю.

Человеку для анализа нужен график. График на экране компьютера — это почти всегда равномерный временной ряд, потому что пиксели занимают фиксированный размер. Почти — это если время нелинейно зачем-то сжимали.

Данные не всегда берутся равномерно и это важно понимать. Замеры скорости сети или загрузки cpu обычно интегрально замеряются (пишу интегрально, потому что вообще говоря это тоже дискретные замеры, просто наносекундные) раз в секунду и порождают равномерный временной ряд, пригодный для построения графика.

Другая история с характеристиками единичных HTTP запросов. У каждого запроса есть суммарное время, сколько он сожрал дискового времени, трафика и т.п. Эти запросы приходят как получится и их надо усреднять. Хранить все данные всех HTTP запросов можно, но не всегда нужно и всё равно с них надо строить равномерные усреднения.

Итак, для того что бы нарисовать график, нам надо получить равномерный временной ряд. Для того, что бы получить равномерный временной ряд, надо либо активно раз в секунду снимать замеры с cpu, сети, термометров или нейтронометра на raspbery, который мы опустили в ядерный реактор, либо надо каким-то образом усреднять шквал неоднородных данных.


Усреднение наравномерного временного ряда



Для усреднения наравномерного временного ряда до равномерного можно пользоваться разными вариантами. Например, мы хотим выяснить максимальное время запроса за секунду или среднее, или медиану или 90 перцентиль.

statsd именно это и делает. В него кидают неравномерный ряд, он наружу выдает раз в секунду какую-то цифирку.


riemann представляет из себя существенно более развесистую софтину чем statsd.




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

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

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



Работа с равномерными рядами



С равномерными рядами приходится решать следующие проблемы:
1) как их хранить и показывать с разным разрешением
2) как их склеивать вместе

Первая проблема — как не хранить секундные замеры за 10 лет, учитывая что они нафиг никому не нужны. За прошлый год хранить дневные замеры, за этот часовые, за этот месяц минутные замеры, за эти сутки секундные замеры.

Т.е. надо через какой-то период времени брать равномерный временной ряд и увеличивать расстояние между точками. Сразу возникает вопрос: чего делать со значениями? Чаще всего достаточно просто среднего арифметического, но тут мы всё равно возвращаемся к предыдущему пункту: иногда нужно и похитрее.

Следующий вопрос про глубину хранения. rrdtool предлагает фиксировать по размеру, а не по глубине. В принципе, это устраивает большинство людей. При переполнении зоны секундных замеров происходит выталкивание в зону минутных замеров и т.п.


Вторая проблема — как объединять данные от разных источников. Например, когда мы собираем скорость трафика с компьютеров в сети, то на суммарном графике хочется видеть сумму. Если мы собираем показания датчиков температуры, то хочется видеть среднее (или среднее с весами, когда термометры в разные места вставлены).

При этом надо не забывать про проблему дырок во временных рядах. Что будет если в какую-то секунду с одного из трех серверов не пришел замер? Если ничего не делать, а просто суммировать цифры с одинаковыми секундами, то будет провал. Такой провал легко пропустить взглядом мимо (в человеческий мозг встроен охренненного качества интегральный анализатор графиков). Но что будет, если по какой-то причине систематически будет недополучаться каждый третий пакет? В этом случае дырки склеются и мы увидим испорченый, гладкий график сети.

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

Чем хранить временные ряды



Если вкратце, то единого ответа тут нет. Гора денег лежит и ждет желающих.

RRDtool
Самое древнее, часто используемое, совершенно не масштабируемое решение. Ему надо при создании базы указать имена метрик и размеры. После этого засовывать в него тик за тиком. Добавлять на ходу метрики нельзя.

Whisper из Graphite

Whisper — это тот же RRDtool, но только в 500 строк кода на питоне, которые можно пофиксить и не ослепнуть.

Ceres как замена whisper, потому что в том есть фатальный недостаток.



OpenTSDB

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

Проблема одна: пока поставишь, можно ослепнуть, потому что hadoop, hbase, gwt, gnuplot и прочий zookeeper, не к ночи он будет упомянут. Т.е. на управление всем этим хозяйством нужен java-compatible админ со всеми вытекающими.

Очень важная штука у OpenTSDB — это то, как хранятся временные ряды. В систему отправляются кортежи из имени метрики, времени, значения и набора тегов. Теги — это секретное оружие tsdb. Надо понимать, что внутри имя метрики представляет из себя склеенное входное имя и теги, но вопрос в том, как это потом достается.

Можно записать такие временные ряды:

output 1389787022 435600 media=ort,host=streamer1
output 1389787022 332600 media=zvezda,host=streamer1
output 1389787022 864600 media=zvezda,host=streamer2


Потом можно выбрать так:

sum:output:media=zvezda


и получить суммарную скорость раздачи по каналу zvezda со всех хостов. Или например можно так:

avg:temperature:hospital=sklif


получить график средней температуры по больнице.

Ещё есть возможность получить усредненный график, попросив выдать данные с шагом в 10 минут, усреднив.


TempoDB

Штука похожа на hosted opentsdb, но не то. Вроде как они не умеют склеивать соседние временные ряды.


librato

умеет собирать и аггрегировать метрики. В коментах мнения расходятся.

influxdb

Go + LevelDB. Развивается

KairosDB
Клон OpenTSDB но на кассандре и гуглкоде.


Blueflood

Ещё одна хранилка поверх кассандры.

seriesly

Хранилка на go со стораджем в couchstore.


Circonus

Коммерческое SaaS / SDP решение для хранения и представления time series.



pulsedb

Наша собственная база pulsedb. Предназначение — носимый и встраиваемый аналог opentsdb с возможностью риалтайм подписки на события.



Как-то так. Чего я упустил?



UPD: сдайте свои дипломы назад, на 3-й странице обнаружена опечатка.

Я назвал равномерные ряды монотонными и это была непростительная ошибка, простите.
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 85 comments