Mongodb中的时间序列存储

时间:2017-03-14 04:26:41

标签: mongodb time-series

我有大约1000个传感器在白天输出数据。每个传感器每天输出大约100,000个点。当我查询数据时,我只对在给定日期从给定传感器获取数据感兴趣。我不做任何跨传感器查询。时间间隔不均匀,我需要保持时间分辨率,所以我不能做像每秒1点的数组。

我打算多年来存储数据。我想知道哪种方案是最好的:

  1. 每天/传感器对对应一个集合,因此每天向我的数据库添加1000个大约100,000个文档的集合
  2. 每个传感器对应一个集合。我有固定数量的1000个集合,每天增加大约100,000个文档。
  3. 1 似乎直观地更快地进行查询。我使用的是mongoDb 3.4,它对数据库中的集合数量没有限制。

    2 看起来更干净但我担心收藏会变得庞大,随着每个收藏的增长,查询会逐渐变慢

    我赞成 1 ,但我可能错了。有什么建议吗?

    更新

    我遵循了

    的建议

    https://bluxte.net/musings/2015/01/21/efficient-storage-non-periodic-time-series-mongodb/

    我没有每次测量存储一个文档,而是一个包含128个测量,startDate,nextDate的文档。它减少了文档的数量,从而减少了索引大小,但我仍然不确定如何组织集合。

    当我查询数据时,我只想要(日期,传感器)对的数据,这就是我认为 1 可能加速读取的原因。我目前在我的数据库中有大约20,000个集合,当我查询所有集合的列表时,需要很长时间才能让我认为拥有这么多集合并不是一个好主意。

    您怎么看?

5 个答案:

答案 0 :(得分:5)

我肯定会建议使用 2 ,原因如下:

  1. MongoDB's sharding旨在应对越来越大的单个集合,并且可以根据需要在单独的服务器中拆分集合中的数据。它没有相同的功能来分割不同服务器中 many collection 中存在的数据。
  2. MongoDB旨在能够有效地查询非常大的集合,即使数据分布在多个服务器上,只要您可以选择与您最常见的读取查询匹配的合适shard key即可。在您的情况下,那将是传感器+日期。
  3. 使用 1 方法,您的应用程序需要完成一项繁琐的工作,即知道要查询哪个集合,以及(可能)找到该集合的位置。方法 2 ,配置良好的分片,意味着the mongos process does that hard work for you

答案 1 :(得分:3)

虽然MongoDB对集合没有限制,但我尝试了类似于2的方法,但是从所有传感器值转移到单个集合,因为它更易于管理。

您计划的数据收集非常重要。你有没有考虑过减少音量的方法?在我的系统中,我压缩相同值的运行并且仅存储更改,我还可以通过跳过共线中点并稍​​后插值来减小音量,例如,我想知道时间值是什么' t&#39 ;。各种不同的传感器可能需要不同的压缩算法(例如,像恒温器设定点的阶梯式传感器与表示像温度一样的连续量的传感器)。拥有一个大型集合还可以在数据过大时轻松丢弃数据。

如果可以guarantee unique timestamps,您也可以将时间戳用作_id字段。

Sensor data

答案 2 :(得分:2)

  

当我查询数据时,我只对从a获取数据感兴趣   在给定的一天给出传感器。我不做任何跨传感器查询。

但这就是卡桑德拉的好处! 请参阅this articlethis one

真的,在我们的一个项目中,我们遇到了遗留的MongoDB和类似于你的场景,除了每天的新数据量甚至更低。 我们尝试更改数据结构,在多个MongoDB集合上粒化数据,更改副本集配置等。 但随着数据的增加,我们仍然感到失望,但性能下降 具有不可预测的负载和读取数据请求会影响写入响应。
使用Cassandra,我们有快速写入和数据检索,用肉眼可以看到性能效果。如果您需要复杂的数据分析和聚合,您可以始终使用Spark(Map-reduce)作业。 此外,考虑到未来,Cassandra提供了直接的可扩展性。

我认为,只要它适合,保留遗产的东西就是好的,但如果不合适,那么改变技术堆栈会更有效。

答案 3 :(得分:1)

如果我理解正确,您计划动态创建集合,即在上午12点,您将拥有新的集合。我猜MongoDB对此是一个错误的选择。如果在MongoDB中需要,您无法跨集合查询文档,则必须编写复杂的机制来检索数据。在我看来,你应该考虑弹性搜索。您可以在哪里创建索引(集合),如sensor-data-s1-3-14-2017。在这里,您可以跨索引进行通配符搜索。 (例如:sensor-data-s1 *或sensor-data- *)。有关通配符搜索,请参阅here

如果您想使用MongoDB,我的建议是使用选项2并对集合进行分片。在进行分片时,请考虑您的查询模式,以便获得最佳性能,并且不会在此期间降低性能。

答案 4 :(得分:0)

方法#1不酷,加速的关键是划分(碎片)和规则。假设的信号数量达到100000.

因此,将一个信号放在一个集合中,将分片信号放在节点上以加快读取速度。多个集合或信号可以位于同一节点上。

这将如何协助

  • 通常对于信号处理,时间跨度像过程信号一样使用3天,在这种情况下,你可以并行读取信号的3个节点,并进行并行的apache spark处理。

  • 交叉信号处理:通常大多数信号处理算法对2个或更多信号使用相同的周期进行分析,如互相关以及这些(2或更多信号)并行获取它也可以快速并且可以并行处理单个信号的矿石处理。