понедельник, 24 февраля 2014 г.

Несколько месяцев назад, я начал работать над своим собственным open source проектом. Попробую рассказать почему я это все начал и чего хорошего хочу сделать.

Итак, все началось с того, что я не смог найти time-series БД, которая бы являлась продуктом с открытым исходным кодом и при этом нормально работала. Time-series данные, это любые данные снабженные меткой времени и идентификатором параметра (aka идентификатор метрики, aka идентификатор источника). Параметры могут соответствовать, например, разным сенсорам, разным измеряемым величинам, разным пользователям в click stream-е и тд.

Главная проблема time-series данных в том, что их всегда очень много. Представьте себе большой датацентр, в котором работают 10 000 машин, на каждой из которых специальный демон десять раз в секунду измеряет количество свободной памяти, загрузку CPU и отправляет это все в БД. Казалось бы, десять раз в секунду это не очень много, но это уже 100k операций записи в секунду, и это не пик, это sustained write rate, для данных, не помещающихся в память. А что, если потребуется измерять значения параметров не десять раз в секунду, а сто?

Самое известное решение этой проблемы - rrd-tool, де факто стандарт во многих областях, имеет жутко неэффективный формат хранения данных с огромным количеством недостатков. Для того, чтобы понять как плох rrd-tool (но в то же время хорош, для определенных применений), нужно понять как он хранит данные, я не буду вдаваться в подробности, скажу лишь, что точность хранения меток времени там ограничена, количество параметров там также ограничено, чем их больше, тем медленнее все работает. Запись в rrd файл это множество random writes. В общем, rrd подходит для чего-нибудь небольшого и не требовательного.

Представитель принципиально другого класса систем - open tsdb (и 100500 подражателей) тоже не слишком хорош, на мой взгляд. Во первых, оно зависит от hadoop и hbase. Hbase используется для хранения данных. Поэтому, open tsdb нельзя использовать в качестве embedded БД. Если вы пишете софт, который работает на каком нибудь промышленном ПК, собирающем данные от каких-нибудь датчиков, то вы open tsdb использовать не сможете. Помимо этого, open tsdb округляет метки времени. Для мониторинга серверов (задача, для которой open tsdb создавалась) это подходит. Для других применений - не всегда.

Самый главный недостаток всех этих систем - они игнорируют специфику данных. Как правило, они формируют некий ключ, комбинируя идентификатор параметра и метку времени, затем этот ключ используется для записи (в hbase, cassandra, leveldb etc). Для того, чтобы найти это значение, нужно использовать точно такой же ключ. По сути, эти БД работают с точечными данными. Отсюда все эти округления меток времени и тд. Главная задача той же open tsdb - построить сводки (rollups), а не поиск значения параметра X в момент времени Y.

В настоящей time series БД, операция записи создает не точку, а линию. Если мы записали значение параметра в момент времени T0, а затем ищем его значение в момент времени T1, причем T1 > T0, то мы должны найти ранее записанное значение. Это логично, ведь между моментами времени T0 и T1 значение параметра не менялось. К сожалению, большинству time series баз данных это неведомо.

В общем, я пришел к выводу, о необходимости создания специализированного бэкенда для таких данных. LevelDB, HBase и им подобные - не решают всех проблем. Собственно, я собираюсь заполнить данный пробел, создав быстрый и в тоже время "правильный" backend.

Цели пока такие:
  • Способность выдавать порядка миллиона операций записи в секунду на моем ноутбуке.
  • Использование фиксированного количества места на жестком диске (как rrd-tool).
  • Кэширование наиболее актуальных данных в памяти.
  • Хитрый алгоритм поиска, который я придумал, но еще не реализовал :)
Первые две цели уже достигнуты, остальное - в процессе. В ближайшее время я постараюсь описать более подробно архитектуру и алгоритмы, в том виде, в котором это все существует сейчас.

Behold!

Комментариев нет: