Хранение 6 миллиардов поплавков для легкого доступа к файлам

Мне нужно сохранять 250 файлов данных в час с 36000 маленьких массивов [date, float, float, float] в python, которые я могу легко прочитать с помощью PHP. Это должно работать как минимум 10 лет на 6 ТБ памяти.

Что является лучшим способом сохранить эти отдельные файлы, я думаю, Python struct. Но это начинает выглядеть плохо для работы с большими объемами данных?

пример данных

a = [["2016:04:03 20:30:00", 3.423, 2.123, -23.243], ["2016:23:.....], ......]

Редактировать:
Пространство важнее, чем распаковка скорости и вычислений. Так как пространство очень ограниченное.

3

Решение

Таким образом, у вас есть 250 поставщиков данных, которые предоставляют 10 выборок в секунду (float, float, float).

Поскольку вы не указали, какие у вас есть ограничения, есть больше вариантов.


Двоичные файлы

Вы можете написать файлы с фиксированным массивом 3 * 36000 с плавающей запятой структура, по 4 байта каждый дает вам по 432.000 байтов на файл. Вы можете кодировать час в имени каталога и идентификатор поставщика данных в имени файла.

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

NumPy

Альтернативой упаковке со структурой является numpy.tofile, который хранит массив непосредственно в файл. Это быстро, но всегда хранит данные в формате C, где вы должны позаботиться о том, чтобы на конечной машине был другой порядок байтов. С numpy.savez_compressed Вы можете хранить несколько массивов в одном архиве npz, а также сжимать их одновременно.

JSON, XML, CSV

Хорошим вариантом является любой из упомянутых форматов. Также стоит упомянуть Формат JSON-строк, где каждая строка является записью в кодировке JSON. Это позволяет включить потоковую запись, при которой вы сохраняете правильный формат файла после каждой записи.

Они просты для чтения, а синтаксические издержки исчезают при сжатии. Просто не делайте конкатенацию строк, используйте реальную библиотеку сериализаторов.

(SQL) База данных

Серьезно, почему бы не использовать реальную базу данных?

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

Базы данных расширяемы и поддерживаются многими языками. Вы сохраняете datetime в базе данных с Python, вы читаете datetime с PHP. Нет проблем с тем, как вам придется кодировать ваши данные.

Базы данных поддерживают индексы для более быстрого поиска.

Мой личный фаворит — PostgreSQL, который имеет ряд приятных функций. Поддерживает Индекс BRIN, легкий индекс, идеально подходящий для огромных наборов данных с естественно упорядоченными полями, такими как метки времени. Если у вас мало диска, вы можете расширить его с помощью cstore_fdw, ориентированное на столбцы хранилище данных, которое поддерживает сжатие. И если вы все еще хотите использовать плоские файлы, вы можете написать обёртка сторонних данных (также возможно с Python) и по-прежнему использовать SQL для доступа к данным.

3

Другие решения

Если вы не используете файлы на одном языке, избегайте языковых форматов и структур. Всегда.

Если вы используете два или более языков, используйте обычный текстовый формат данных, например JSON или же XML это может быть легко (часто изначально) проанализировано большинством языков и инструментов.

Если вы следуете этому совету и сохраняете простой текст, тогда используйте сжатие хранимого файла — так вы сэкономите место. Типичный, хорошо структурированный JSON очень хорошо сжимается (при условии простого текстового содержимого).

Еще раз, выберите формат сжатия, такой как gzip, который широко поддерживается в языках или их основных библиотеках. PHP, например, имеет встроенную функцию gzopen() и python имеет lib \ gzip.py в стандартной библиотеке python.

2

Я сомневаюсь, что это возможно без чрезвычайно эффективного сжатия.

6TB / 10 year/ 365 days / 24 hrs / 250 files = 270 KB per file.

В идеальном случае. На самом деле размер кластера имеет значение.

Если у вас есть 36 000 «маленьких массивов» для размещения в каждом файле, у вас есть только 7 байтов на массив, что недостаточно для хранения даже одного объекта datetime.

1

Одна мысль, которая приходит мне в голову, если вы хотите сэкономить место. Вам лучше хранить только значения и сбрасывать метки времени. Создайте файлы только с данными и убедитесь, что вы создали своего рода индекс (формулу), который при заданной отметке времени (год / месяц / день / час / мин / сек …) приводит к положению данных внутри файла ( и, конечно, файл, который вы должны пойти). Даже если вы проверите дважды, вы обнаружите, что если вы используете «умную» схему именования файлов, вы можете избежать хранения информации о году / месяце / дне / часе, поскольку частью индекса может быть имя файла. Все зависит от того, как вы реализуете свою «индексную» систему, но, переходя к экстремальной версии, вы можете забыть о временных метках и сосредоточиться только на данных.

Что касается формата данных, как уже упоминалось, я бы окончательно выбрал независимый от языка формат XML, JSON … Кто знает, какие языки и возможности у вас будут через десять лет;)

0