Compression 什么';存储时间序列的有效方法是什么?

Compression 什么';存储时间序列的有效方法是什么?,compression,time-series,Compression,Time Series,我有大量可怕格式的数据:16.4GiB的zip文件包含csv文件。 每个csv包含如下行 TYPE,2014-07-02 04:04:23.806,0.94598,0.94607 基本上: A类型(共有14种不同类型,它们在未来可能会理想地增长) A时间戳(毫秒) 2个浮点数(最多小数点后5位),通常有一点分散 相同类型的所有浮点数在时间上接近时通常具有非常相似的值 时间戳之间的增量小于1s 数据跨度为5年 我总共有3091'472'167行,所以我们谈论的是数十亿。 主要操作是在部分或全

我有大量可怕格式的数据:16.4GiB的zip文件包含
csv
文件。 每个
csv
包含如下行

TYPE,2014-07-02 04:04:23.806,0.94598,0.94607
基本上:

  • A
    类型
    (共有14种不同类型,它们在未来可能会理想地增长)
  • A
    时间戳
    (毫秒)
  • 2个浮点数(最多小数点后5位),通常有一点分散
  • 相同
    类型的所有浮点数在时间上接近时通常具有非常相似的值
  • 时间戳之间的增量小于1s
  • 数据跨度为5年
我总共有3091'472'167行,所以我们谈论的是数十亿。 主要操作是在部分或全部数据集上循环(以便对数据运行算法),每月插入约2000万条记录(但插入数据不是我感兴趣的优化目标)

理想的解决方案是将它们存储在一个数据库中,这样我就可以轻松地查询它们,但一些粗略的计算表明,我需要Postgres(通过一些丑陋的技巧,可能会降低到18GiB)

我用我掌握的数据做了一些研究,发现: 生成包含
时间戳、FLOAT1、FLOAT2
的gzip文件将使我达到~14GiB 完全删除时间戳将使我的容量降至~5GB

节省空间的一个好方法是以有效的方式存储时间戳。 我在考虑创建一个树结构,其中每个节点都包含时间戳的一个数字,叶子包含最后一个数字和两个浮点数

我尝试过寻找像druid.io这样的解决方案,但看起来他们正在尝试为我的用例不需要的其他东西进行优化

有没有什么工具我不知道,它正是我想要的? 如果没有,存储时间序列数据的有效方法是什么


谢谢

一定要使用数据库。PostgreSQL时间戳字段每个为8字节。如果将
smallint
用于
TYPE
real
用于数据值(小数点后6位精度),则当前数据集每行18字节或超过55GB。没有索引或讨厌的黑客

人们似乎过于关注存储空间。千兆字节并不昂贵。您试图从存储中取出数据所花费的时间可能会更昂贵。时间戳字段在这方面非常有用,因为它提供了非常细粒度的索引,并允许数据库快速检索所需的记录

将数据放入数据库,将表的主键设置为
类型
时间戳
的组合,并投资一个SSD来保存数据。

  • 将数据分为数千段,按时间分组。我不知道时间的分布,但也许每小时有一个文件

  • 按时间戳将它们存储在子目录中。例如2014/07/02/04

  • 在文件名中添加开始时间戳。例如,
    2014-07-02 04:04:23.806.gz

  • 对于所有行,将类型作为索引存储在第一个字节中。这允许扩展到256种类型。如果这还不够,请将其设置为两个字节

  • 对于所有行,时间戳是一个两字节整数,浮点数是有符号的n字节整数,足以容纳105次的值。我假设这些浮点值的范围是有限的。每个字节四个字节就足够了

  • 对于第一行,时间戳为零,表示与该行时间和文件名的差异

  • 对于第一行,浮点值是实际值

  • 对于所有后续行,时间和浮点值是与前一行的差值。请注意,它们可以是负数

  • 交错值的最高有效字节,以最大化小增量的零运行

  • 使用压缩文件压缩每个文件。除了默认模式外,请尝试
    Z_FILTERED
    Z_HUFFMAN
    模式,查看压缩效果是更好还是更差


  • 在PostgreSQL方面,您还可以使用开放源代码的列式存储。这使您可以免费压缩、列式布局和跳过索引。与存储和磁盘I/O相关的好处包括:

  • 因为列值是按顺序存储的,所以可以获得更好的压缩比
  • 数据库只读取您正在查询的列,并跳过其余的列
  • cstore_fdw构建轻量级跳过索引。对于时间序列数据,这些索引会自动过滤不相关的数据
  • 有关更多信息:

    如果您还需要将查询扩展到多个CPU核/计算机,那么您可以使用可扩展的PostgreSQL:


    除了压缩和高效的数据布局之外,您还可以免费获得PostgreSQL的类型检查、数据操作功能和所有查询功能。

    这里没有足够的信息。假设每一行独立于其他行,您可能可以将每一行减少到17个字节(1+8+4+4)。为了进一步减少冗余,您需要对行之间的冗余进行一些非常重要的分析。从它听起来的样子来看,Gzip已经做得很好了(以它自己的方式)。谢谢你的回复!是的,这是真的,gzip做得很好,但是可能我可以在时间戳上做一些工作来节省一些空间。我只是想知道那些酷酷的孩子们是怎么压缩时间戳的(如果他们真的这么做了,因为我还没有找到任何东西)。除非你能对他们的取值范围做出假设,否则你无法“压缩”他们。例如,一个32位的时间戳会给你50天的范围,一个64位的时间戳会给你6亿年(!)。但即使您成功地将它们压缩到0位,您仍然是每行9个字节,这