Мне нужно сохранять 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:.....], ......]
Редактировать:
Пространство важнее, чем распаковка скорости и вычислений. Так как пространство очень ограниченное.
Таким образом, у вас есть 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 для доступа к данным.
Если вы не используете файлы на одном языке, избегайте языковых форматов и структур. Всегда.
Если вы используете два или более языков, используйте обычный текстовый формат данных, например JSON
или же XML
это может быть легко (часто изначально) проанализировано большинством языков и инструментов.
Если вы следуете этому совету и сохраняете простой текст, тогда используйте сжатие хранимого файла — так вы сэкономите место. Типичный, хорошо структурированный JSON
очень хорошо сжимается (при условии простого текстового содержимого).
Еще раз, выберите формат сжатия, такой как gzip, который широко поддерживается в языках или их основных библиотеках. PHP, например, имеет встроенную функцию gzopen()
и python имеет lib \ gzip.py в стандартной библиотеке python.
Я сомневаюсь, что это возможно без чрезвычайно эффективного сжатия.
6TB / 10 year/ 365 days / 24 hrs / 250 files = 270 KB per file.
В идеальном случае. На самом деле размер кластера имеет значение.
Если у вас есть 36 000 «маленьких массивов» для размещения в каждом файле, у вас есть только 7 байтов на массив, что недостаточно для хранения даже одного объекта datetime.
Одна мысль, которая приходит мне в голову, если вы хотите сэкономить место. Вам лучше хранить только значения и сбрасывать метки времени. Создайте файлы только с данными и убедитесь, что вы создали своего рода индекс (формулу), который при заданной отметке времени (год / месяц / день / час / мин / сек …) приводит к положению данных внутри файла ( и, конечно, файл, который вы должны пойти). Даже если вы проверите дважды, вы обнаружите, что если вы используете «умную» схему именования файлов, вы можете избежать хранения информации о году / месяце / дне / часе, поскольку частью индекса может быть имя файла. Все зависит от того, как вы реализуете свою «индексную» систему, но, переходя к экстремальной версии, вы можете забыть о временных метках и сосредоточиться только на данных.
Что касается формата данных, как уже упоминалось, я бы окончательно выбрал независимый от языка формат XML, JSON … Кто знает, какие языки и возможности у вас будут через десять лет;)