存储60亿个浮点数,方便文件访问

Storing 6 billion floats for easy access in files

我需要在 python 中使用 [date, float, float, float] 的 36000 个小数组每小时保存 250 个数据文件,我可以使用 PHP 轻松读取这些文件。这需要 运行 至少 10 年,存储空间为 6tb。

保存这些单个文件的最佳方式是什么,我在想 pythonstruct.但是对于大数据量的工作来说,它开始看起来很糟糕?

数据示例

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

编辑: Space,比解包速度和计算更重要。由于 space 非常有限。

除非您使用相同语言的文件,否则请避免特定于语言的格式和结构。总是。

如果您要在 2 种或多种语言之间切换,请使用常见的纯文本数据格式,例如 JSONXML,大多数语言和工具都可以轻松(通常是本地)解析它们.

如果您遵循此建议并存储纯文本,则对存储的文件使用压缩——这就是您保存 space 的方式。典型的结构良好 JSON 往往压缩得很好(假设文本内容简单)。

再次选择一种压缩格式,如 gzip,它被语言或其核心库广泛支持。例如,PHP 有一个原生函数 gzopen(),而 python 在标准 python 库中有 lib\gzip.py。

我怀疑没有非常有效的压缩是可能的。

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

理想情况下。实际上,集群的字大小很重要。

如果每个文件有 36,000 个“小数组”,那么每个数组只有 7 个字节,这不足以单独存储适当的 datetime 对象。

所以你有 250 个某种类型的数据提供者,它们每秒提供 10 个样本(float,float,float)。

由于您没有具体说明您的限制是什么,所以还有更多选择。


二进制文件

您可以使用 struct 编写 3*36000 个浮点数的固定数组文件,每个文件 4 个字节,每个文件 432.000 个字节。您可以在目录名称中编码小时,在文件名中编码数据提供者的 ID。

如果您的数据不是太随机,一个合适的压缩算法应该削减足够的字节,但如果您不想丢失数据,您可能需要某种延迟压缩。

numpy

用结构打包的另一种方法是numpy.tofile, which stores the array directly to file. It is fast, but always stores data in C format, where you should take care if the endian is on target machine is different. With numpy.savez_compressed你可以在一个 npz 存档中存储多个数组,同时压缩它。

JSON、XML、CSV

上述任何一种格式都是一个不错的选择。另外值得一提的是 JSON-lines format,其中每一行都是 JSON 编码的记录。这是为了启用流式写入,您可以在每次写入后保留有效的文件格式。

它们易于阅读,语法开销随着压缩而消失。只是不要进行字符串连接,使用真正的序列化程序库。

(SQL) 数据库

说真的,为什么不使用真实的数据库呢?

显然,您需要对数据进行一些处理。每秒 10 个样本,没有人会需要这么多数据,所以你必须进行聚合:最小值、最大值、平均值、平均值、总和等。数据库已经具备所有这些,结合其他功能,它们可以为你节省一个大量的时间你可以花在写这么多脚本和文件抽象上。更不用说文件管理变得多么麻烦。

数据库是可扩展的,并受多种语言支持。您使用 Python 在数据库中保存日期时间,使用 PHP 读取日期时间。无需担心如何对数据进行编码。

数据库支持索引以加快查找速度。

我个人最喜欢的是 PostgreSQL,它有很多不错的功能。它支持 BRIN index, a lightweight index, perfect for huge datasets with naturally ordered fields, such as timestamps. If you're low on disk, you can extend it with cstore_fdw, a columnar oriented datastore, which supports compression. And if you still want to use flat files, you can write a foreign data wrapper (also possible with Python) 并且仍然使用 SQL 来访问数据。

如果您想保存,我想到了一个想法 space。您最好只存储值并丢弃时间戳。生成仅包含数据的文件,并确保您创建了一种给定时间戳(year/month/day/hour/min/sec...)的索引(公式)导致数据在文件中的位置(当然还有文件你必须去)。甚至,如果你检查两次,你会发现如果你对文件使用 "smart" 命名方案,你可以避免存储有关 year/month/day/hour 的信息,因为索引的一部分可能是文件名。这一切都取决于您如何实施 "index" 系统,但推到一个极端的版本,您可能会忘记时间戳并只关注数据。

关于数据格式,如前所述,我肯定会继续采用与语言无关的格式,如 XML、JSON...谁知道十年后你会使用哪些语言和可能性 ;)