时间序列数据的数据存储

4
我有一些科学测量数据,应该永久存储在某种数据存储中。
我正在寻找一种方法来存储来自 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

这将提供良好的读取性能,因为结果将是来自相对较小(通常少于一百万行)表的连续行数。
然而,RDBMS应该有100,000个表,在几分钟内使用。这似乎在常见系统中不可能。另一方面,由于数据中没有关系,RDBMS似乎不是正确的工具。
我已经可以通过使用以下“mickeymouse”系统证明单个服务器可以处理负载:
1. 每个传感器在文件系统中都有自己的文件。 2. 当数据到达时,打开其文件,追加数据,然后关闭文件。 3. 查询打开相应的文件,找到数据的起始和结束点,并读取中间的所有内容。
只需很少量的代码。性能取决于系统(存储类型、文件系统、操作系统),但似乎没有什么大的障碍。
然而,如果我走这条路,最终需要编写自己的分区、备份、将旧数据移动到存储(云)中更深处等代码。那么这听起来像是自己编写DBMS,这又像是重新发明轮子。
是否有一种标准的方式来存储我拥有的数据类型?一些聪明的NoSQL技巧吗?

是的,这并不是一个真正的SO问题,但它很有趣。请查看http://stackexchange.com/sites上的所有其他网站,例如“程序员”或“计算机科学”。我想说你想要的是非常高性能的。你可以使用像SQL Server或Oracle这样的“普通”系统来完成它。但你的速度目标很高。3秒钟内输出10亿行数据需要大量的处理能力、高级硬件和逻辑并行处理。云系统在传输过程中也会太慢。如果你可以放弃一些速度,那么问题就不那么难了,因为简单的数据结构会有所帮助,正如你已经知道的那样。 - Mike M
1
我试图改述问题以更清晰地描述问题。输出带宽不是问题,因为我每次只需要从一个传感器获取适度数量的数据。典型的查询可能会返回大约20,000个数据点。不需要花哨的硬件 - 至少初步基准测试表明这可以通过单个服务器完成。 - DrV
很好。在这种情况下,你的实现可能比使用哪个系统更重要。数据架构始终是关键:)。玩得开心! - Mike M
@DrV:你解决了这个问题吗?在你的意见中,哪种数据库管理系统最适合这些类型的问题? - Chintan Pathak
@DrV 这是一个快速而粗糙的解决方案。如何将您的传感器读数流式传输到诸如Kafka之类的队列,然后有一个或多个工作者将数据转储到parquet文件中?Parquet文件可以很容易地通过PowerBI等工具进行查询。 - dicemaster
2个回答

1

看起来这是一个相当简单的问题。1000亿条记录,每个记录12字节 -> 1.2TB,这甚至不是现代硬盘驱动器的大容量。在LMDB中,我会考虑为每个传感器使用一个子数据库。然后你的键/值只是32位时间戳/32位传感器读数,所有的数据检索将是简单的键范围扫描。你可以很容易地使用LMDB检索大约50M条记录/秒。(查看SkyDB的人正在这样做https://groups.google.com/forum/#!msg/skydb/CMKQSLf2WAw/zBO1X35alxcJ)


谢谢您的专业意见!我确实喜欢LMDB的实现方式,并且一直在考虑在这个应用程序中使用它,但我没有想到使用子数据库。我承认我对它们的无知,并且必须问一下,使用500个每个有200个子数据库或1个有100,000个子数据库是否有区别?(每秒50,000,000条记录确实令人印象深刻,但不幸的是我的数据将存储在磁盘上,所以我担心随机读取或写入的页面数量。) - DrV
1
LMDB是单写设计,因此您可以考虑将其拆分为500个数据库以支持500个并发写入者。除此之外,还有一个问题,即必须同时打开多少个子数据库 - 初始的mdb_dbi_open()实际上在打开的DBI表中进行线性搜索,因此对于100,000个可能会很慢。(但这也可能无关紧要,因为每次运行只需要打开一次。)除此之外没有真正的性能差异。 - hyc
1
InfluxDB是一种时间序列数据库,可以使用LMDB。使用LMDB的Sorted Duplicates功能也可以节省一些空间和时间,详情请参见我的评论。 - hyc

-1

尝试使用VictoriaMetrics作为用于大数据量时间序列数据库。

  • 它被优化用于存储和查询大量的时间序列数据。
  • 它使用基于LSM树的存储设计,因此可以在HDD上工作得很好,而不是SSD,并且具有低磁盘iops和带宽。
  • 它具有良好的压缩比,因此1000亿个典型数据点只需要不到100 GB的HDD存储空间。请阅读有关数据压缩的技术细节

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接