Хранение данных для данных временных рядов
У меня есть некоторые научные данные измерений, которые должны постоянно храниться в каком-либо хранилище данных.
Я ищу способ хранения измерений от 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:
- Каждый датчик имеет свой собственный файл в файловой системе.
- Когда часть данных поступает, ее файл открывается, данные добавляются, и файл закрывается.
- Запросы открывают соответствующий файл, находят начальную и конечную точки данных и читают все, что находится между ними.
Очень мало строк кода. Производительность зависит от системы (тип хранилища, файловая система, ОС), но, похоже, нет никаких серьезных препятствий.
Однако, если я пойду по этому пути, я в конечном итоге напишу свой собственный код для разделения, резервного копирования, перемещения старых данных вглубь хранилища (облака) и т. Д. Затем это звучит как свертывание моей собственной СУБД, что звучит как переизобретение колесо (снова).
Есть ли стандартный способ хранения данных, которые у меня есть? Какой-нибудь умный трюк NoSQL?
1 ответ
Похоже, довольно простая проблема на самом деле. 100 миллиардов записей, 12 байт на запись -> 1,2 ТБ - это даже не большой объем для современных жестких дисков. В LMDB я бы рассмотрел использование subDB для каждого датчика. Тогда ваш ключ / значение будет считываться только 32-битной меткой времени /32-битным датчиком, и все ваши данные будут просто сканироваться по ключу. Вы можете легко получить порядка 50 миллионов записей в секунду с помощью LMDB. (Смотрите, ребята из SkyDB делают именно это https://groups.google.com/forum/)
Попробуйте VictoriaMetrics в качестве базы данных временных рядов для больших объемов данных.
- Он оптимизирован для хранения и запроса больших объемов данных временных рядов.
- Он использует низкие операции ввода-вывода и пропускную способность диска благодаря конструкции хранилища, основанной на деревьях LSM, поэтому он может неплохо работать на HDD вместо SSD.
- У него хорошая степень сжатия, поэтому для 100 миллиардов типичных точек данных потребуется менее 100 ГБ на жестком диске. Прочтите технические подробности о сжатии данных.