Comments 49
И еще, возможно пропустил — как удаляются старые данные?
- Я считаю, что такие вещи, как запись статистических данных (среднее за час/минуту) не задача самого движка хранения. Да, в dariadb реализован метод stat, который выдаст вам для определенного измерения среднее значение, мин/максы. Но вот ведение параллельного временного ряда, со статистикой, это не задача движка. Я бы это вынес в серверную часть. Что я и сделаю в будущих версиях.
- Что касается удаления. Сейчас есть два способа удалить:
- метод erase — который просто удалит страницы из интервала.
- метод compact (в ветке dev) — с его помощью можно не только удалить выборочно измерения, но и заменить группу замеров на 1.
Да, можно сделать сейчас и более элегантное удаление, как в leveldb (запись специального значения в базу, которое говорит, что у нас удалена какая то часть), но этого пока у меня нет в планах. Если найдется гурппа желающих, то сделаю.
Зачем нужен ваш комментарий?
Blosc — компрессор, который не подходит для TSDB, которая держит открытыми очень много рядов (например миллион), каждый ряд нужно уметь читать независимо, поэтому ему нужен свой отдельный контекст компрессора, а этот контекст обычно занимает десятки килобайт. Ну и еще он медленный.
std::unique_ptr<Callback> callback_ptr{new Callback()};
storage->foreach (qp, callback_ptr.get());
callback_ptr->wait();
В этом есть какой-то тайный смысл? Или это можно переписать так:
Callback callback;
storage->foreach(qp, &callback);
callback.wait();
А почему вы используете 4 байта для флага? Простите если читал невнимательно.
2. Dariadb — хобби проект. Он не рассчитан (во всяком случае пока) на продакшн. Делался для себя, чтобы понять как оно там внутри.
Если брать готовое решение (абстрактный KV-сторадж или leveldb для конкретности), то их можно использовать, если они дают построить в памяти (ну или на диске) индекс таким образом, чтобы мы знали какие временные ряды имеются в хранилище, где они лежат на диске, чтобы не заниматься сканированием всего файла, а сразу сделать seek к нужным данным, а также уметь эффективно упаковывать значения временного ряда, потому что самое поле Value может почти не меняться для рядом стоящих замеров. Если абстрактный kv-сторадж это умеет, то его можно использовать вместо dariadb.
В dariadb заголовки индексных файлов лежат в памяти, по этим заголовкам мы определяем нужные нам файлы (индексные), проходим по ним и находим смещения нужных нам чанков, которые попали в запрос. Сами индексные файлы небольшие, для страницы в 1 мегабайт размером, индексный файл будет примерно 30 килобайт, при желании их вообще можно полностью держать в памяти. Причем сами индексы содержат статистику, поэтому для запроса среднего на интервале, или минимума за период, читать и распаковывать страницу не надо.
Что касается джоинов, то это вполне себе реализуемая вещь. Единственная проблема, что сейчас реализовано так, что упакованные данные для каждого временного ряда полностью вычитываются с диска в память, что в случае большого запроса скушает всё, что есть. Такой подход выбран, как самый простой в реализации. Позже это можно сделать "по правильному".
А вот с group by хотелось бы пример реального использования. Мне оно не встречалось, поэтому интересно зачем оно и как использовать.
Как в DariaDB обстоят дела со всем этим?Мой вопрос был скорее адресован автору комента выше :)
Если абстрактный kv-сторадж это умеет, то его можно использовать вместо dariadb.Я думаю, что хороший kv-сторадж умеет эффективно искать по ключу, а также умеет сжимать данные. Можно почитать, к примеру, как устроена RocksDB.
Причем сами индексы содержат статистикуВот этого в kv-сторадже вероятно нет. Но до определенных пределов это может компенсироваться быстрым чтением или каким-нибудь кэшем сбоку.
Ну, и мне кажется, что реальный «топ» таких баз данных — это закрытые энтерпрайз-решения
Наиболее актуальными видами запросов были следующие (как для одного ряда, так и для группы рядов):
- выборка последнего значения по состоянию на момент времени, но не ранее заданного момента времени (фактически, выборка последнего значения в интервале);
- выборка значений за временной период + последнего значения по состоянию на начало периода, но не ранее заданной даты.
У автора есть размышления не сей счёт или таких нюансов пока не касались?
"выборка последнего значения по состоянию на момент времени, но не ранее заданного момента времени (фактически, выборка последнего значения в интервале);"
А это чем отличается от среза на момент времени? Вам фактически возвращается значение, которое не позднее заданного времени.
При обычном срезе давность последних значений ничем не ограничена, а часто нужны последние, но не слишком старые данные.
Например, значения телеметрического замера тока электродвигателя, работающего с изменяющейся загрузкой, быстро теряют актуальность (замер суточной давности имеет мало смысла).
Я к тому, что обычно востребовано последнее значение, находящееся между двух заданных дат, а не просто по состоянию на одну дату.
Два следствия для производительности для последовательного чтения записи:
- хранить лучше каждый параметр отдельным хранилищем/файлом
- это даст возможность предсоздавать файлы определенного размера, в том числе циклические
Ну и еще по закрытию периода (месяц, год) данные становятся менее актуальными и востребованными и можно думать об их перемещении на более дешевое хранение. Возможно, актуальными останутся агрегаты.
Перечень time-series dbms, возможно из них можно найти еще идеи для реализации
"хранить лучше каждый параметр отдельным хранилищем/файлом"
это смотря сколько значений. Знаю "скаду", где 100к временных рядов с разным шагом записи.
Есть тестовый стенд со сбором порядка 40к метрик в кассандру с time window compaction strategy.
Такие данные в любом случае нужно хранить на нескольких сервреах с прицелом на автоматический файловер и избыточность — на случай выходя из строя, апгрейда и т.д. Кассандра в этом смысле идеальна — все механизмы у неё встроенные. Графит с карборонм — хуже.
Мой пойнт был в том, чтобы при необходимости например, построить 15 графиков из 100к по архивным данным, не пришлось 15 раз перечитать данные с диска от всех 100к параметров.
а в dariadb эти данные считаются за один проход с диска, потом уже в памяти будут выдаваться последовательно для каждого временного ряда.
DariaDB. Разработка базы данных для хранения временных рядов