Информация об изменениях

Сообщение Akumuli - time-series database от 26.10.2015 10:18

Изменено 26.10.2015 10:21 ELazin

https://github.com/akumuli/Akumuli

Это хранилище данных для временных рядов (серий), коротко можно описать как RRD-tool на стероидах. Использует константное количество памяти на диске (под нагрузкой может использовать несколько больше), но при этом, в отличии от RRD поддерживает сжатие, динамическое добавление серий, теги, выборки и все такое.
Имена серий имеют такой вид: `metric.name tag1=XXX tag2=YYY`, например: `cpu host=balancer2 awsregion=eu-central-1`. Далее можно их выбирать указывая те или иные тэги и метрики, например:
{
    "metric": "cpu",
    "range" : {
        "from": "20150101T000000",
        "to"  : "20150102T000000"
    }
    "where" : [
        { 
            "host" : {"in": [ "balancer1", "balancer2" ]}
        },
        {
            "awsregion" : {"in": [ "us-east-1" ]}
        }
    ]
}


В данном случае сервис вернет все временные ряды в заданном временном диапазоне, которые соответствуют метрике "cpu" и у которых ключ "host" равен "balancer1" или "balancer2" а ключ "awsregion" равен "us-east-1". Метки времени можно указывать в ISO (сервис будет считать что они в UTC), можно просто в виде чисел. Язык запросов на основе json не финальный, а скорее рабочий вариант. Я бы предпочел что-нибудь более простое, чтобы можно было запрос в url передавать, например (может язык запросов prometeus-а стоит передрать). Я еще не придумал как это сделать.

Для записи и чтения используются разные механизмы. Записывать данные можно через tcp или udp. Пропускная способность весьма неплохая, у меня получалось примерно 2 миллиона операций записи в секунду на двух m3.xlarge инстансах (на одном крутился сервис, на другом клиент). Читать данные можно через http. Запрос в json передается в postъ данных, в ответ сервис отдает результаты. Данные отдаются в chunked transfer encoding, т.е. размер указан не будет и данных может быть очень много. Формат ответа — текстовый, либо CSV, либо RESP. Скорость отдачи довольно неплохая, пока что это еще не реализовано, но в будущем возможно будет в поле запроса range.to ничего не указывать и сервис будет отдавать данные по мере записи.

Движок хранения данных умеет в сжатие. Все что в него записывается делится на блоки, внутри каждого блока данные хранятся в column oriented порядке, при этом для каждой колонки используется специализированный алгоритм сжатия. В синтетических тестах получается сжать до 4х байт на каждую точку (имя серии (метрика + набор тегов), 8ми байтовая метка времени, 8ми байтовое значение).

Помимо непосредственно чтения/записи поддерживаются следующие запросы:
1. Случайная выборка (сейчас используется reservoir sampling, но нужно реализовать что-нибудь более полезное).
2. Кусочная аппроксимация (PAA), позволяет преобразовывать нерегулярные временные ряды в регулярные (с фиксированным шагом).
3. Frequent items/heavy hitters.
4. Детектор аномалий. Реализовано несколько алгоритмов — EWMA (exponentially weighted moving average), non-seasonal Holt-Winters, seasonal Holt-Winters. Помимо этого, детектор аномалий может работать используя фиксированный объем памяти и выполняя фиксированный объем вычислений (sketch based anomlay detector), при этом могут быть ложные срабатывания. Этот детектор аномалий может выполняться с той же скоростью, с которой вы добавляете данные и находить аномалии в реальном времени. КМК. нормальной практикой может быть 1) поиск кандидатов в аномалии с помощью вероятностного алгоритма 2) проверка кандидатов с помощью точного алгоритма.
5. SAX преобразование для индексации где-нибудь (например в Lucene) и последующего поиска.

В планах — добавить DTW запрос и коррелятор. В принципе, новые запросы добавляются достаточно легко вот здесь: https://github.com/akumuli/Akumuli/tree/master/libakumuli/query_processing там что-то вроде небольшого фреймверка для этого есть.

Документация пока сильно отстает от кода, ближайшие цели — финализировать все что в процессе допиливания, собрать и выложить куда-нибудь deb/rpm пакеты и доделать документацию.

Всегда рад пулл-реквестам. Также буду очень рад совету, где лучше всего хостить paa репозиторий для убунты, например. Через launchpad как-то очень сложно это все делается, особенно с бустом в зависимостях.
https://github.com/akumuli/Akumuli

Это хранилище данных для временных рядов (серий), коротко можно описать как RRD-tool на стероидах. Использует константное количество памяти на диске (под нагрузкой может использовать несколько больше), но при этом, в отличии от RRD поддерживает сжатие, динамическое добавление серий, теги, выборки и все такое.
Имена серий имеют такой вид: `metric.name tag1=XXX tag2=YYY`, например: `cpu host=balancer2 awsregion=eu-central-1`. Далее можно их выбирать указывая те или иные тэги и метрики, например:
{
    "metric": "cpu",
    "range" : {
        "from": "20150101T000000",
        "to"  : "20150102T000000"
    }
    "where" : [
        { 
            "host" : {"in": [ "balancer1", "balancer2" ]}
        },
        {
            "awsregion" : {"in": [ "us-east-1" ]}
        }
    ]
}


В данном случае сервис вернет все временные ряды в заданном временном диапазоне, которые соответствуют метрике "cpu" и у которых ключ "host" равен "balancer1" или "balancer2" а ключ "awsregion" равен "us-east-1". Метки времени можно указывать в ISO (сервис будет считать что они в UTC), можно просто в виде чисел. Язык запросов на основе json не финальный, а скорее рабочий вариант. Я бы предпочел что-нибудь более простое, чтобы можно было запрос в url передавать, например (может язык запросов prometeus-а стоит передрать). Я еще не придумал как это сделать.

Для записи и чтения используются разные механизмы. Записывать данные можно через tcp или udp. Пропускная способность весьма неплохая, у меня получалось примерно 2 миллиона операций записи в секунду на двух m3.xlarge инстансах (на одном крутился сервис, на другом клиент). Читать данные можно через http. Запрос в json передается в postъ данных, в ответ сервис отдает результаты. Данные отдаются в chunked transfer encoding, т.е. размер указан не будет и данных может быть очень много. Формат ответа — текстовый, либо CSV, либо RESP, но можно добавить protobuf или что угодно вообще. Скорость отдачи довольно неплохая (~50MB/sec), пока что это еще не реализовано, но в будущем возможно будет в поле запроса range.to ничего не указывать и сервис будет отдавать данные по мере записи (streaming).

Движок хранения данных умеет в сжатие. Все что в него записывается делится на блоки, внутри каждого блока данные хранятся в column oriented порядке, при этом для каждой колонки используется специализированный алгоритм сжатия. В синтетических тестах получается сжать до 4х байт на каждую точку (имя серии (метрика + набор тегов), 8ми байтовая метка времени, 8ми байтовое значение).

Помимо непосредственно чтения/записи поддерживаются следующие запросы:
1. Случайная выборка (сейчас используется reservoir sampling, но нужно реализовать что-нибудь более полезное).
2. Кусочная аппроксимация (PAA), позволяет преобразовывать нерегулярные временные ряды в регулярные (с фиксированным шагом).
3. Frequent items/heavy hitters.
4. Детектор аномалий. Реализовано несколько алгоритмов — EWMA (exponentially weighted moving average), non-seasonal Holt-Winters, seasonal Holt-Winters. Помимо этого, детектор аномалий может работать используя фиксированный объем памяти и выполняя фиксированный объем вычислений (sketch based anomlay detector), при этом могут быть ложные срабатывания. Этот детектор аномалий может выполняться с той же скоростью, с которой вы добавляете данные и находить аномалии в реальном времени. КМК. нормальной практикой может быть 1) поиск кандидатов в аномалии с помощью вероятностного алгоритма 2) проверка кандидатов с помощью точного алгоритма.
5. SAX преобразование для индексации где-нибудь (например в Lucene) и последующего поиска.

В планах — добавить DTW запрос и коррелятор. В принципе, новые запросы добавляются достаточно легко вот здесь: https://github.com/akumuli/Akumuli/tree/master/libakumuli/query_processing там что-то вроде небольшого фреймверка для этого есть.

Документация пока сильно отстает от кода, ближайшие цели — финализировать все что в процессе допиливания, собрать и выложить куда-нибудь deb/rpm пакеты и доделать документацию.

Всегда рад пулл-реквестам. Также буду очень рад совету, где лучше всего хостить paa репозиторий для убунты, например. Через launchpad как-то очень сложно это все делается, особенно с бустом в зависимостях.