Хранение данных для данных временных рядов

У меня есть данные научных измерений, которые следует постоянно хранить в каком-то хранилище данных.

Я ищу способ хранить измерения от 100 000 датчиков с накоплением данных измерений за годы до примерно 1 000 000 измерений на датчик. Каждый датчик выдает показания раз в минуту или реже. Таким образом, поток данных невелик (около 200 измерений в секунду в полной системе). Датчики не синхронизированы.

Сами данные представлены в виде потока троек: [отметка времени] [номер датчика] [значение], где все может быть представлено как 32-битное значение.

В простейшей форме этот поток будет сохранен как есть в одной таблице с тремя столбцами. Тогда запрос будет:

SELECT timestamp,value 
  FROM Data 
  WHERE sensor=12345 AND timestamp BETWEEN '2013-04-15' AND '2013-05-12'
  ORDER BY timestamp

К сожалению, для строковых СУБД это даст очень низкую производительность, так как объем данных велик, и данные, которые нам нужны, распределены по нему почти равномерно. (Попытка выбрать несколько сотен тысяч записей из миллиардов записей.) Что мне нужно с точки зрения производительности, так это разумное время отклика для человеческого потребления (данные будут отображаться в виде графика для пользователя), то есть несколько секунд плюс передача данных.

Другой подход - хранить данные с одного датчика в одной таблице. Тогда запрос будет выглядеть следующим образом:

SELECT timestamp,value 
  FROM Data12345 
  WHERE timestamp BETWEEN '2013-04-15' AND '2013-05-12'
  ORDER BY timestamp

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

Однако в СУБД должно быть 100 000 таблиц, которые используются в течение нескольких минут. Это не представляется возможным в обычных системах. С другой стороны, СУБД не кажется подходящим инструментом, поскольку в данных нет связей.

Я смог продемонстрировать, что один сервер может справиться с нагрузкой, используя следующую систему mickeymouse:

  1. У каждого датчика есть свой файл в файловой системе.
  2. Когда поступает фрагмент данных, его файл открывается, данные добавляются, а файл закрывается.
  3. Запросы открывают соответствующий файл, находят начальную и конечную точки данных и читают все, что между ними.

Очень мало строк кода. Производительность зависит от системы (типа хранилища, файловой системы, ОС), но особых препятствий нет.

Однако, если я пойду по этому пути, я в конечном итоге напишу свой собственный код для разделения, резервного копирования, перемещения старых данных глубже в хранилище (облако) и т. Д. Тогда это звучит как развертывание моей собственной СУБД, что звучит как новое изобретение колесо (снова).

Есть ли стандартный способ хранения данных, которые у меня есть? Какой-нибудь хитрый трюк с NoSQL?


person DrV    schedule 12.06.2014    source источник
comment
Да, это не совсем ТАК вопрос, но это интересно. Посетите все другие сайты на stackexchange.com/sites, например, о Программистах или Информатике. Я бы сказал, то, что вам нужно, - это очень высокая производительность. Вы могли бы сделать это с помощью стандартной системы, такой как SQL Server или Oracle. Но ваши цели по скорости непростые. 1 миллиард строк за 3 секунды == огромная вычислительная мощность, модное оборудование и логический параллелизм. Облачные системы также будут работать слишком медленно по сети. Если вы можете отказаться от скорости, это не так сложно, поскольку, как вы уже знаете, помогает простая структура данных.   -  person Mike M    schedule 13.06.2014
comment
Я попытался перефразировать вопрос, чтобы более четко описать проблему. Выходная полоса пропускания не является проблемой, так как мне нужно получать только умеренный объем данных с одного датчика за раз. Типичные запросы возвращают около 20 000 точек данных. Никакого необычного оборудования не требуется - по крайней мере, предварительные тесты показывают, что это можно сделать с одним сервером.   -  person DrV    schedule 13.06.2014
comment
Хороший. В этом случае ваша реализация, вероятно, важнее, чем какая система. Архитектура данных всегда является ключевым моментом :). Развлекайся!   -  person Mike M    schedule 13.06.2014


Ответы (2)


На самом деле это кажется довольно простой проблемой. 100 миллиардов записей, 12 байт на запись -> 1,2 ТБ - это даже не большой объем для современных жестких дисков. В LMDB я бы подумал об использовании subDB для каждого датчика. Тогда ваш ключ / значение - это всего лишь 32-битная временная метка / 32-битное считывание датчика, и все ваши извлечения данных будут простым сканированием диапазона на ключе. Вы можете легко получить порядка 50 миллионов записей в секунду с помощью LMDB. (Посмотрите, как ребята из SkyDB делают это https://groups.google.com/forum/#!msg/skydb/CMKQSLf2WAw/zBO1X35alxcJ)

person hyc    schedule 15.06.2014
comment
Спасибо за экспертное мнение! Мне нравится, как делается LMDB, и я думал об использовании его в этом приложении, но я не думал об использовании subDB. Я признаю свое незнание в отношении них и должен спросить, есть ли разница в использовании, скажем, 500 баз данных с 200 суббД каждая или одной базы данных и 100 000 суббд? (50000000 записей в секунду действительно впечатляют, но, к сожалению, мои данные будут на диске, поэтому меня беспокоит количество прочитанных или записанных случайных страниц.) - person DrV; 15.06.2014
comment
LMDB - это дизайн с одним записывающим устройством, поэтому вы можете рассмотреть возможность разделения на 500 баз данных, чтобы поддерживать 500 одновременных писателей. Помимо этого, возникает вопрос, сколько дочерних баз данных должно быть открыто одновременно - исходная mdb_dbi_open () фактически выполняет линейный поиск в таблице открытых DBI, поэтому он может быть медленным для 100000. (Но это также может не иметь значения, поскольку открытие нужно выполнять только один раз за запуск.) Кроме того, нет реальной разницы в производительности. - person hyc; 16.06.2014
comment
InfluxDB - это база данных временных рядов, которая может использовать LMDB - person hyc; 23.06.2014

Попробуйте VictoriaMetrics в качестве базы данных временных рядов для больших объемов данных.

  • Он оптимизирован для хранения и запроса больших объемов данных временных рядов.
  • Он использует низкие операции ввода-вывода и пропускную способность диска благодаря дизайн хранилища основан на деревьях LSM, поэтому он вполне может работать на HDD вместо SSD.
  • У него хорошая степень сжатия, поэтому для 100 миллиардов типичных точек данных потребуется менее 100 ГБ на жестком диске. Прочтите технические подробности о сжатии данных.
person valyala    schedule 12.06.2019