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

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

Я ищу способ хранения измерений от 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?

1 ответ

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

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

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