Комментарии 84
А в чем отличие вашей реализации от уже существующих, например Click House или KDB?
Ведь для хранения TS уже давно используются колоночные базы данных. Более того, в существующих решениях уже есть немало полезных опций (скажу про KDB):
- Драйверы под разные технологии (.Net, Java, ODBC и пр.)
- Права доступа
- Вертикальное и горизонтальное масштабирование
- Stored Procedures
Более того, у них есть также ряд важных для Enterprise особенностей:
- Они давно на рынке
- Есть специалисты на рынке
- Можно купить поддержку
- Есть community
На тему баланса скорости записи и чтения могу посоветовать схему из той же KDB:
- данные хранятся индексированные, оптимизированные для быстрого поиска (разработчик выбирает методику хранения)
- последний день хранится отдельно
- в конце дня происходит сброс данных, т.е. текущий день пересортировывается и записывается начисто
- если исключить последний день, то для добавления/удаления/изменения данных следует прочитать весь день в память, сделать нужные операции и сохранить весь день обратно. Т.е. по факту никаких update/delete/insert, кроме редких случаев
Оптимизации для чтения:
- исходя из предыдущего — нет разреженного индекса, никаких деревьев; все данные хранятся максимально плотно
- каждая колонка хранится в отдельном сжатом файле
- на колонку можно наложить аттрибуты, с помощью которых можно или увеличить скорость обращения (т.е. сделать отдельную хеш таблицу), или соптимизировать хранение (записывая одинаковые данные в отдельный блок)
- если определенное значение хорошо квантуется (например: страна, валюта), то можно попросить не хранить каждый раз значение, а создать отдельно Map: Int -> Value, то есть хранить просто номер значение (подобие динамического enum'а)
- для жирного запроса — параллельное чтение из нескольких файлов.
И еще раз вопрос: в вашей базе это есть? А если нет — то почему не использовать одно из уже существующих решений (в случае с KDB — она доступна с 2003 года)?
Видимо, ответ такой:
Потому, что не блокчейн)
Белый лист в тексте как бы мягко намекает на ICO)) И да, это не критика или ирония) дерзайте!
drop-in replacement
Я бы вообще даже не заводил разговор про такое. Это продукт такого типа, что замена его на другой, даже путь бесплатный и заведомо лучше по характеристикам, все равно будет непростым процессом, который сам по себе стоит денег.
Запрос, говорят, всегда прост: выдай данные от и до, возможно с какими-то базовыми статистиками
Сразу скажу — у меня практический опыт работы только с OneTick (в пределах трех лет), и там это, мягко говоря, не совсем так. Даже совсем не так. А в целом суть моих соображений проста — это не SQL, при этом даже перенос базы с одного SQL диалекта на другой — штука не всегда простая. А тут со стандартами похуже будет.
Ну и соответственно, переписать адаптеры — может быть нетривиальной задачей с изменением логики обработки.
Я как-то пытался переносить логику работы с OneTick на MS SQL (благо, объемы данных позволяли). Даже на сравнительно небольших потоках, которые MS SQL в принципе переваривает, все не так уж примитивно. И совсем не похоже на оригинал в OneTick.
Тут дело не совсем в сложности запроса. Там свой язык запросов, ни с кем не совместимый (хотя ODBC драйвер существует, но SQL весьма специфичный). Функции с одной стороны, как вполне обычные, типа max/min/first/last за период, так и достаточно экзотические. К сожалению, с открытой документаций как-то не очень, я затрудняюсь отослать к какому-либо примеру в интернете.
Кстати, попробуйте на досуге реализовать в виде SQL запроса такую тривиальную в общем-то штуку, как last за произвольный период. И главное посмотрите, как быстро это будет работать.
Но на сколько я понял, нет потребности такие фичи в язык запросов вставлять, все это делается на мидллейере.
Что значит "все делается"? Тут есть одна небольшая проблема — при больших объемах вы не можете просто так вытащить нужные вам данные из TDSB "с запасом", и потом их где-то обработать, это слишком много ресурсов потребует.
Частично согласен про "сложности переноса", но… меня смутил ваш пример:
попробуйте на досуге реализовать в виде SQL запроса такую тривиальную в общем-то штуку, как last за произвольный период.
Иии… оно как бы тоже довольно тривиально на SQL:
select * from tab where rowid = (
select max(rowid) from tab
where rowdate >= :from and rowdate <= :to
)
И главное посмотрите, как быстро это будет работать.
Ну… очень быстро будет, если rowid — primary key с (clustered index) и rowdate тоже проиндексирован (напрямую, или в join'е с другой какой табличкой).
Сложный last
реализуем "отсортированым подзапросом" с TOP N
сверху, или WHERE ROWNUM <= N
или LIMIT N
(соотвественно для MSSQL, ORA, и другие). Тоже не вижу особых проблем: execution plan построится как выбока N значений после мёржа с пересечением двух индексов (один ограничен/отфильтрован по rowdate).
Я не совсем в теме как оно там в OneTick, может там какой другой last
или вы что-то другое имеете ввиду?
Мне все же очень интресно — не ужели никто не пробовал сохранять аппроскимации для оптимизации IO Read запросов? Не только для графиков можно использовать — но и для счета: есть аппроксимации сохраняющие и важнейшие статитсики (среднее, ошибку, экстремумы)
Добавлю что вопрос был о сложности переноса с одной TSDB на другую TSDB…
ждем что оптыом подлятся бывалые.
Как бы оно тяжело так ответить. Зависит от многих параметров, как-то:
- необходима ли перестройка структур для внутренних/внешних данных под новую TSDB;
- если да насколько она сложна;
- имеется ли прослойка/надстройка в виде Middle-Level-API оборачивающая вызовы к TSDB;
- насколько это Middle-Level-API абстрактно и/или видоизменяемо;
- насколько глубоко используются возможности конкретной TSDB;
- весь ли используемый функционал в оригинальной TSDB предоставляется целевой TSDB;
- т.к. как правило переезд обоснован новым функционалом и/или конструктами (предоставляемым новой TSDB), сколь долго код переделывается/переписывается под новый конструкт/модель;
- насколько тяжела собственно миграция данных (если необходима) с учетом всего вышеописанного, возможна ли в отрыве от продакшн (инкрементально), есть ли готовые наработки и т.д.;
И это на бумаге, где мы еще "забыли про овраги"…
… тут картинка с Боромиром — "нельзя просто так взять и… рассазать про перенос TSDB/RDMS/NoSQL/любимое-подставить".
Ибо разное оно все…
А так-то перетаскивал и не раз, но… в каждом конкретном случае с совсем разными трудозатратами… и граблями.
Ну раз "вопрос в лоб", вот конкретный ответ на вскидку и "в лоб":
Например Kx kdb+ подразумевает что вы умеете Q (язык такой от Kx Systems), и он по умолчанию практически не совместим ни с одним известным мне другим "query-языком" (умолчим уже про чистые АПИ типа С++, Java, Python) для работы с TSDB даже в примитивах.
Если мощь языка использовалась на всю катушку, то переписывать 3-х этажные конструкции с Q на любимое-подставить — это то еще удовольствие (если вообще возможно без полной перестройки структуры списков и сопутствующего), а там еще могут быть функции и т.д. и т.п.
Причем, много есть чего она умеет из коробки, что либо нет вовсе, либо нужно полностью переделать для конструкций другой TSDB/языка.
Я раз видел как-то одного разраба за переписыванием такого 3-х этажного Q-statement на PyQ (то ли ему где-то нужен был промежуточный питоний reduce, как ему казалось не реализуемый на Q, то ли не оптимальный и не миксуемый по другому был). Так вот он это делал день… Еще раз — один единственный statement. С матом (ну как умел, ибо немец), приступами агрессии и др. сопутствующими симптомами (вынос мозга и т.д.).
Вот вам например, первый попавшийся, небольшой сценарий на Q, попробуйте представить, что нужно сделать, чтобы переложить хотя бы его на любой другой вам известный TSDB/язык, фреймворк и т.п.
Ваше представление aka Smalltalk? 1C? SAP? (что вы назвали "исходя из примитивного понимания") — описал кортеж, покликал мышем связав две кнопки и функцию, скормил ему кучу данных (магически видимо как-то) и бац — получил красивый график — к сожалению (а может к счастью) так не работает и далеко от реальности, от слова совсем.
Вы правда с биг-дата и time series работали? Или для вас табличка с BLOB (JSON) обернутая кучей stored functions вокруг — тоже TSDB?
Ну, никто не говорил, что это не решаемая задача. Я просто имел в виду, что в конкретно моем случае почти все получилось по другому, совсем не так, как было на OneTick. Т.е. тупо и в лоб почти ничего не перенеслось, в большинстве случаев пришлось думать о том, как конкретно то или это сделать. И менять логику, которая была более-менее прямолинейно взята из бизнеса, на ту, которую можно сделать, и не просадить при этом производительность вставки.
where rowdate >= :from and rowdate <= :to
А теперь вспоминаем, что нам нужно агрегировать до минут/часов и т.п. Т.е. эти самые from и to нужно вычислять, как начало и конец секунды. Ну в общем, много мелкой разной возни.
И как вы уже заметили, для MS SQL и Oracle подходы могут быть слегка разные.
Дальше — OneTick, как ориентированная на временные ряды база, сама умеет генерировать уникальные seq id для тех тиков, у которых полностью совпали timestamp — т.е. время получается дополненным числом 1, 2, 3..., если оно совпадало. Я, скажем так, не разработчик MS SQL, и могу ошибаться, но я знаю один способ сгенерировать именно такие уникальные id — и это триггер (и это плохо, потому что будет тормозить вставки). Или уже будет что-то по-другому, например сквозная нумерация.
А теперь делаем на SQL табличку — по строкам дата/время и срез десятка параметров с этим временем +-200мс (т.к.снимаются асинхронно).
Т.е. если задача «web dashboard графиков временного ряда c server-side zoom'ом » какой продукт (комбинацию продуктов) использовать?
Есть алгоритм Largest-Triangle-Three-Buckets. Простой, но хорошо аппроксимирует данные для отображения, не удаляя экстремумы.
По моему мнению для TSDB такая функциональность не требуется.
Chronix — это сила!
de.slideshare.net/QAware/chronix-time-series-database-the-new-time-series-kid-on-the-block
Project files & Examples: github.com/ChronixDB
db-engines.com/en/ranking/time+series+dbms
А в идеале — в этот рейтинг попасть.
Но сравниваться-то можно и бесплатно.
Насколько я помню, на Хабре в 17м году еще пробегала статья про TS DBMS и более приятно технически проработанная.
Честно говоря меня, как пользователя подобных СУБД, не зацепило
По чтению к сожелению результатов нет.
С другой стороны, писать плохой по производительности код на С++ значительно проще, но не факт, что переписывание на С тут хоть как-то поможет (плохой код скорее всего будет переписан в такой же плохой код).
Еще там есть описание языка запросов и форматов входных данных, но записывать данные можно через какой-нибудь коллектор (нужно только использовать протокол OpenTSDB) и читать данные с помощью плагина для графаны. Думаю это то что нужно большинству людей.
Продолжайте!
ageres, зачем Вы оказываете медвежью услугу?
И не бойтесь вопросов в стиле
Главное — не уверенность, а аргументы. Сейчас ответ читается как "да, я проигрываю комерческим базам и делаю вид, что не заметил в исходном комментарии Click House, так как я проигрываю Open Source решениям тоже".
Ибо получается, что автор сделал серьезный труд, даже внедрил решение, однако будущее его проекта туманно, т.к. придется тягаться с Яндексом на рынке дешевых решений и с кучей других на рынке коммерческих.
А теперь главное — если продолжать работу над Akumuli, то автор опять затратит много сил, добьется того, что уже есть в открытом доступе, и всё равно будет отставать от того же Яндекса.
Всё это, конечно, не отменяет полезность и интересность статьи (за что от меня плюс). Надеюсь, я ошибаюсь, и у автора получится таки найти нишу для Akumuli.
В моей базе есть много всего, но это не drop-in replacement для коммерческой БД для хранения тиков, которая стоит столько, что ее стоимость можно узнать только у персонального менеджера, только после того как он соберет всю нужную информацию о твоей компании, чтобы понять сколько денег у тебя можно просить. Сорян.
ClickHouse это тоже аналитическая БД, его имеет смысл с Vertica сравнивать, это не TSDB, там есть GraphiteMergeTree для метрик, но чтобы с этим разобраться нужно изучать исходники (оно не описано в документации, по крайней мере раньше не было) и судя по всему, создавалось для внутренних нужд. Данные в CH нужно писать батчами, нельзя просто открыть сокет и начать записывать туда данные, все будет слишком медленно. Нужен какой-то сервер, который будет получать данные мониторинга от коллекторов, батчить их и вставлять. Для этого есть graphite-clickhouse и graphouse. Ни одна из этих связок не поддерживат теги.
Сравнивать Akumuli имеет смысл с другими TSDB — OpenTSDB, Graphite, InfluxDB и тд. По сравнению с ними у меня есть преимущество в производительности и простоте операций. Akumuli может работать автономно, не нуждается в администрировании. У меня есть пользователи, которые выбрали Akumuli именно благодаря этому. Им нужна была БД, которая может работать на очень слабом железе, мониторить кучу контроллеров и не нуждаться в администрировании. У меня самого есть кое какой проект, который мониторится с помощью Akumuli на t2.micro инстансе.
Просто на страничке проекта есть текст «Akumuli is a time-series database for modern hardware.»
Мы успешно используем ClickHouse для временных рядов — храним результаты нагрузочных тестов и тестов энергопотребления. В случае с тестами энергопотребления нам удавалось заливать миллион замеров в секунду, а потом с этим работать. Так что сравнивать имеет смысл.
Данные в CH нужно писать батчами, нельзя просто открыть сокет и начать записывать туда данные, все будет слишком медленно. Нужен какой-то сервер, который будет получать данные мониторинга от коллекторов, батчить их и вставлять.
Мы используем buffer в самом ClickHouse.
Заметим, что даже для таблиц типа Buffer не имеет смысла вставлять данные по одной строке, так как таким образом будет достигнута скорость всего лишь в несколько тысяч строк в секунду, тогда как при вставке более крупными блоками, достижимо более миллиона строк в секунду (смотрите раздел «Производительность»).
А в чем заключается «медвежья услуга»?
Суть в том, что если есть популярное открытое и бесплатное решение (я про Click House), то очень сложно сделать более быстрый аналог. К тому же Click House прекрасно решает в том числе и задачу работы с временными рядами, так как по сути вам надо просто брать определенную проекцию из данных (т.е. создать materialized view для вашей таблицы со своей логикой сортировки).
А в итоге что имеем:
- Есть бесплатное открытое решение, которое улучшается кучей людей и компаний
- Когда новый человек ищет способ решение своей задачи, он зачастую будет руководствоваться тем, какие есть функции в проекте, какая документация, насколько большое сообщество и т.д.
- Ваше решение уже сейчас проигрывает аналогам.
- Если Вы будете продолжать разработку над Akumuli, ваш вклад в "open source" будет неоцененным, так как вы решили задачу, а немало людей пользуются другой такой же программой
- Через N лет вам надоест вкладывать силы в решение, и если вы не успеете собрать community, то проект будет затухать и забываться
То есть по сути серьезный труд остается неоцененным, однако вам говорят, что "всё круто, продолжай". Отсюда моё мнение — как можно раньше признать, что есть более серьезные аналоги, а дальше — попытаться интегрировать ваши алгоритмы в Яндекс (или аналоги), написать статьи об алгоритмах и добавить строчку в резюме.
Да, это шаг назад, однако иначе через 5 лет вам уже сложно будет выдать Akumuli за достижение.
К тому же Click House прекрасно решает в том числе и задачу работы с временными рядами, так как по сути вам надо просто брать определенную проекцию из данных (т.е. создать materialized view для вашей таблицы со своей логикой сортировки).
Materialized view сейчас убивает перформанс КХ напрочь, простите.
Просто проходил мимо.
Не обращайте внимание.
Slack и Trello, похоже, тоже оказывали медвежью услугу(конкурент Atlassian Jira и HipChat).
Главное — не уверенность, а аргументы.
Главный аргумент звучит так:
Akumuli, как публично доступный проект, появился в 2013 году.
Click House, как публично доступный проект — Тремя годами позже (в 2016 году).
В связи с этим Вы либо требуете от автора быть пророком видящим в будущее, либо Ваш вопрос на самом деле не к Akumuli, а к Click House — зачем его стали разрабатывать, если Akumuli уже 3 года как существовал и можно было бы в его разработке участвовать.
Почему-то в подобных вопросах сравнениях люди напрочь забывают, что более известный конкурент мог банально появиться позже и реальный выбор у разработчиков был не между конкурентом и своим решением, а между своим решением и ничем.
Конечно же я в курсе, что реальная разработка CH началась раньше, чем выкладка в open-source, но не суть важно, когда она началась. Важно, что в 2013 году тот, кто ставил себе задачу разработать TSDB скорее всего не мог знать о существовании внутренней разработки яндекса CH. Следовательно вопросы в стиле зачем писать свое, если есть CH — это отсылка к видению будущего.
Если вы делаете 10 000 вставок в свою SQL базу данных — все будет хорошо какое-то время, потом таблица вырастет в размерах настолько, что время выполнения операций вставки увеличится.
Пруфлинк в студию, пожалуйста!
Работаю в научной сфере с временными рядами без изысков и экзотики, используя банальную, хорошо настроенную SQLite. На 400 млн строк упомянутой у Вас просадки производительности для insert не наблюдается.
Вообще, хотелось бы увидеть сравнительные тесты разных БД с Вашей разработкой. SQLite в частности.
А почему именно SQLite?
Потому, что быстрее просто не удалось найти. Проводился целый ряд исследований под конкретную потребность — хранение временных рядов (среди основных задач). Хочу особенно подчеркнуть, что каждая БД хороша под свои цели. При нагрузочном тестировании рассматривались BerkeleyDB и PostgreSQL в т.ч.
BDB отпала по двум причинам:
1. Она «не SQL» — там своя атмосфера. Дизайн API очень запутанный и странный.
2. Не имеет преимуществ по производительности в сравнении с SQLite.
Производительность PostgreSQL под требуемую задачу не идёт ни в какое сравнение с SQLite. SQLite доступен напрямую как сишная библиотека, которую можно статически собрать с приложением. К PostgreSQL доступ только по сокетам. PostgreSQL хороша для проектов с многопользовательской нагрузкой, с доступом к случайным фрагментам БД и сложными выборками. А для последовательного доступа к данным от имени одного приложения (как в случае с временными рядами) лучше, чем SQLite найти не удалось.
Возможно, где-то MySQL и является преимуществом, но не в научных задачах. По производительности она вообще не конкурент.
Насчёт кофеварок Вы погорячились ) SQLite полноценная БД со своими киллерфичами. Одна из самых быстрых и, кстати, среди прочего, умеет вложенные запросы, in-memory, и много того, чего не умеет MySQL, несмотря на свою «зрелость» и «корпоративную поддержку».
В любом случае хочу Вам пожелать успеха в проекте. Продолжайте. Вы делаете полезное дело и пусть конкуренты не смущают — когда-то и про существование Линукс знала пара-тройка энтузиастов ;)
То, что на «больших» машинах она сильно обгоняет полновесные решения тут вполне понятен, так как она относительно проста.
Мой вопрос как раз был про простоту: достаточно ли её возможностей с учётом дальнейшего развития проекта?
И, да: посмотреть на структуру было бы интересно.
Т.к. это временной ряд, то при аварийном завершении приложения всегда можно подсмотреть время последней успешной вставки и недостающее подтянуть из внешнего «кеша». Помимо прочего, версия SQLite позволила реализовать consequtive disk access, а в момент старта приложения средствами SQLite производится проверка базы на консистентность pragma integrity_check. В общем, был реализован ряд мер, обеспечивающий и производительность, и надёжность для последовательной записи и обращений к временному ряду. Скорость выборок и вставки вне конкуренции с другими упомянутыми мной БД.
А вот и обещанная схема, она предельна проста. Одна отдельная БД с одной таблицей:
PRAGMA foreign_keys=OFF;
PRAGMA synchronous=OFF;
PRAGMA journal_mode=OFF;
PRAGMA cache_size=524288;
PRAGMA page_size=4096;
CREATE TABLE timeseries (time TIMESTAMP UNIQUE NOT NULL, responsiveness DOUBLE NOT NULL);
достаточно ли её возможностей с учётом дальнейшего развития проекта?
Абсолютно достаточно. Она, даже, избыточна по функционалу. Но это нельзя считать недостатком, т.к. на производительность приложения не влияет.
В моём случае сжатие нецелесообразно. Сэкономить пару гигабайт на диске при современных объёмах резон небольшой, а вот накладные расходы на CPU в момент компрессии/декомпрессии — это уже серьёзный недостаток, когда куча фоновых процессов и математическими расчётами генерируется большая нагрузка. SQLite хранит все данные в бинарном виде с приемлемо малым оверхедом.
Попробуйте переписать на чистый Си.
А попробуйте IDEA JetBrains переписать на чистый C, или vk.com. Сразу отпадет желание сравнивать теплое с мягким. Хорошо что выше уже заметили — С и C++ не имеют столь заметной разницы, больше это зависит от квалификации разработчика и правильно выбранных алгоритмов.
SQLite это вообще RDBMS. Это в принципе для другого создано. Если вы в нее пишете временные ряды это значит либо бюджета недостаточно для ClickHouse, либо что-то еще.
Обычно временные ряды между собой никак не связаны, как и записи в логах. Но по записям в логах не считают агрегаты. Ни одна запись временного ряда, например загрузки ЦП, не ссылается на другую. И уж точно не ссылается на записи из другой сущности, с записями о загрузке в сети, например. Нет связей. Нет связей — нет R в акрониме R(DBMS). Значит они проходят мимо.
Правильнее всего выбирать не самое популярное решение среди доступных, а хотя бы какое-нибудь среди подходящих. C — очень хороший язык, но используйте его только по назначению.
ClickHouse, кстати, тоже не создавался для записи временных рядов, он создавался для записи в него большого количества фактов (кликов) и для быстрой обработки аналитических запросов к этим кликам.
Я считаю уместным сравнивать проект автора с RRDtool, используя который можно писать time series. Инструментарий у этого проекта такой что хуже только в файлы вручную писать, черех fwrite. И если сравнивать проект Akumuli и RRDtool то вы удивитесь как все перевернется.
По поводу 400млн строк — это в секунду? В сутки? А с tarantool сравнивать будем? Он тоже быстро пишет :) Правда это Key Value + Application Server а не TSDB )) Я не буду спрашивать как много клиентов было, при записи этих 400М строк, очевидно что один. В это время, хотя бы на чтение, были запросы от других пользователей к SQLite? Ключевая возможность для TSDB — это запись с нескольких хостов, в противном случае это не TSDB а лог показаний счетчика на устройстве.
Причем логика агента может быть любой (вплоть до её полного отсутствия — когда вы не сохраняете и не храните сырые данные).
Ну и второй аспект — нам может не хватать RAM для хранения данных. В принципе, можно хранить временные ряды в Redis, я даже на гитхабе что-то похожее видел. Но это подойдет только для случая когда у пользователя небольшой поток или им нужно хранить только оперативные данные за последний день/час.
Когда временных рядов становится больше, вы просто ставите около еще одну такую же монолитную ноду?
Или же архитектура далека от монолитной ноды?
— Запись в прошлое, обновление старых данных и тд.
— Простая репликация, HA с полным набором данных на двух нодах и синхронизацией в случае, если одна из них уходила offline.
— Тут уже можно начинать думать про кластеризацию.
Сама проблема довольно сложна. Непонятно даже как раскидывать метрики между нодами, ведь запросы часто вытаскивают множество метрик и если распределять их случайным образом, то каждый запрос будет задействовать все узлы кластера (разделить на фактор репликации).
Akumuli — база данных временных рядов