Pull to refresh

Comments 3

VRackDB - это простая In Memory Graphite like база данных, предназначенная для хранения временных рядов (графиков). (TypeScript)

Просто интересно, а сколько человеко-дней занимает такая разработка сейчас (в наше время)?

Мы лет 30-40 назад написали примерно то же самое на фортране, только с акцентом на анализ/визуализацию ретроспективно накопленных данных. Система до сих пор используется, и после нескольких рефакторингов насчитывает несколько сотен тысяч строк кода. Она тоже достаточно быстрая (пока ряды содержат меньше миллиона измерений, все делается "на лету"), с минимальными требованиями к "железу", но есть и некоторые отличия:

  • рабочее пространство (а тем более данные) у нас хранятся на диске, так что при внезапном отключении света не теряется вообще ничего, кроме результатов текущей операции;

  • ОП у нас не используется вообще ;-) Ну то есть на самом деле там хранятся текущие графики (смешное количество точек), а при обработке рядов - скользящее окно, которое бежит по ряду (тут уже требования намного серьезнее). Но вот практически вся остальная доступная память напрямую программой не задействуется, а используется для кэширования дисковых файлов с данными, причем этим занимается ОС. Даже под DOS-ом это позволяло нам спокойно работать с миллионами точек. А сейчас у нас не редкость ряды из миллиардов значений. При этом они спокойно крутятся но компе с 8Гб памяти, где параллельно висит еще тьма всякой рутины от браузера до VS;

  • Но наиболее интересное в контексте вашей системы отличие в том, что данные для графика у нас возвращаются в двух вариантах: это либо обычный набор точек в соответствии с запрошенной детальностью (обычно она соответствует разрешению экрана) либо

набор "диапазонов" (т.е. пар {min,max}) той же размерности

Поясню, зачем нужен диапазон. Пусть, например, у нас есть ряд с опросом в 1 сек, а длина ряда 5 лет. Тогда каждый пиксел экрана (пойнт графика) должен показать пользователю фрагмент сигнала, состоящий из примерно 100 000 первичных (секундных) отсчетов данных. Понятно, что за 100 тыс. отсчетов ряд мог довольно сильно гулять вверх-вниз. В такой ситуации показывать юзеру одно лишь только среднее значение... ну, такое себе. У нас в графиках поэтому сделаны два режима (чуть подобнее здесь): можно показывать либо среднее, либо размах колебаний (он рисуется вертикальной палочкой). Вот сравнение двух графиков одного и того же ряда с генерализацией среднего либо размаха:

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

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

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

туда заглянуть

вроде, статья должна осенью выйти. В elibary она за paywall-ом, но на сайте ИФЗ-шных журналов доступ к статьям свободный. Короче, если статья понравится, не забудьте сослаться. Вам не сложно, а нам будет приятно ;-)

А вот "слои" у нас не прижились как-то. Хотя один из юзеров предлагал такой вариант. Но... небольшие ряды данных (до миллиона значений) на современных компьютерах агрегируются "на лету", поэтому на таких масштабах просто нет смысла заморачиваться с предвычисленными слоями. Когда рисовалка запрашивает у БД нужный ей фрагмент данных, то проще сделать все расчеты в динамике и вернуть данные в точности с нужной детальностью, а не подбирать наиболее подходящий слой (который вдобавок может оказаться не совсем подходящим). А для гигабайтных рядов мы обычно делаем всего один промежуточный слой, да и то вручную.

Ну и еще из отличий - шкала времени у нас начинается не с секунд, а с микросекунд, т.к. в геофизике в последнее время внедряются все более высокочастотные регистрирующие системы.

Так вот, я сейчас попытался прикинуть, сколько же времени у нас ушло на разработку всей этой системы. Очень грубо - несколько тысяч человеко-дней. Правда, основное время все-таки было потрачено не на СУБД, а на разные инструменты анализа временных рядов. Но вклад СУБД и визуализации в общие времязатраты тоже вполне заметный. С другой стороны, первоначально мы все писали под DOS, не имея многих сегодняшних инструментов. Ну и еще один нюанс - у нас абсолютно все алгоритмы поддерживают наличие в рядах данных пропущенных наблюдений. При написании своего алгоритма это часто увеличивает времязатраты втрое-вчетверо. А то и вообще на порядок, когда вместо готового библиотечного алгоритма приходится делать свой полный аналог просто потому, что в библиотечном Nan-ы обрабатываются не так, как нам хочется...

В общем, несмотря на все различие между системами, некоторая аналогия между ними проглядывается. Поэтому и интересно: насколько быстрее и проще сейчас можно "собрать" такую систему, как ваша, из почти готовых кубиков, по сравнению с самостоятельным изготовлением продукта "с нуля".

Просто интересно, а сколько человеко-дней занимает такая разработка сейчас (в наше время)?

На все, с документацией и структуризацией API не тратя на это полный рабочий день, написал ее за 2 месяца.

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

Так же, цели которые мы преследуем немного разные. У вас - научная работа/анализ данных. Поэтому вам конечно же лучше хранить все накопленные данные и я понимаю, насколько в вашем случае это важно.

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

Поскольку цели у нас разные - энергозатраты так сильно отличаются.

Есть некоторые вещи которые я у вас подметил. Прочитав ваш комментарий - понимаю, что измерять в секундах это очень долго учитывая современные вычислительные мощности компьютеров. Подумаю, как внедрить поддержку вплоть до микросекунд. И идея с парами min/max мне тоже нравится. Думал на эту тему, но как реализовать не знал, в принципе теперь более ли менее понятно.

Большое спасибо за такой развернутый комментарий!

Есть некоторые вещи которые я у вас подметил.

Буд рад, если навел на какие-то полезные мысли ;-)

измерять в секундах это очень долго (...) внедрить поддержку вплоть до микросекунд.

Мы свою систему начинали пилить в те далекие времена, когда деревья были большими integer был двухбайтным ;-) Поэтому для универсальности шкалы времени дату оформили в виде структуры из "общечеловеческих ценностей": года, месяца, дня и т.д. Идея была в том, что все даты, кроме ключей, не хранятся наравне с данными, а вычисляются по мере необходимости. То есть, каждое значение данных сопоставляется с датой динамически, а в базе (в памяти) хранятся только характеристики сигнала в целом (ну или его фрагмента). Соответственно, при длине сигнала от 100 точек и более размер структуры даты не важен вообще.

Для манипуляций с такими датами пришлось запилить собственную библиотеку со всякими оптимизациями скорости типичных (для нас!) операций: инкремент даты с разным шагом, пересчет номера точки в дату и обратно, сложение-вычитание дат (интервалов) и т.д. Которая так с тех пор и работает (если интересно, она лежит вот тут среди прочих кодов - файлы clib.inc и clib.for).

Сейчас мы бы уже ядро библиотеки попроще сделали, на основе 16-байтовых (а не 16-битных) вычислений ;-). С конверсией даты в человеческий формат и обратно на уровне интерфейса, как это принято "у взрослых". Но тут уж, что называется, не буди лихо, пока легаси работает - ;-)

Sign up to leave a comment.

Articles