【问题标题】:MongoDB - single huge collection of raw data. Split or not?MongoDB - 单一庞大的原始数据集合。分还是不分?
【发布时间】:2013-04-04 16:56:10
【问题描述】:

我们从大量主机收集和存储检测数据。 我们的存储是 MongoDB——几个带有副本的分片。一切都存储在一个大型集合中。 我们插入的每个文档都是基于时间的观察,具有一些属性(测量值)。时间戳是最重要的属性,因为所有查询都至少基于时间。文档永远不会更新,所以它是一个纯粹的 write-in-look-up 模型。现在它可以很好地处理数十亿个文档。

现在,

我们希望增长一点,并保存长达 12 个月的数据,这些数据可能达到可怕的万亿以上观察(文档)。 如果将所有东西都倾倒到一个巨大的集合中是最好的选择,或者有更聪明的方法来解决它,我一直在徘徊。 我的意思是更智能 - 使用更少的硬件,同时仍然提供快速插入和(重要的是)快速查询。 所以我考虑将大集合拆分成更小的部分,希望在索引、插入和查询速度方面获得内存。

我研究了分片,但按时间戳分片听起来是个坏主意,因为所有写入都将进入一个节点,从而取消了分片的好处。 插入率非常高,所以我们需要分片才能在这里正常工作。 我还考虑过每个月创建一个新集合,然后为用户查询挑选一个相关集合。 超过 12 个月的收藏将被删除或存档。 还可以选择每月创建全新的数据库并进行类似的轮换。 其他选择?或者也许一个大集合是THE真正变大的选择?

请分享您在类似应用中的经验和注意事项。

【问题讨论】:

  • 您的查询范围是否基于时间?
  • 是的,时间是所有查询的主要参数。此外,用户可以选择其他属性。例如,“给我取上周日的特定来源的红色或温度低于零时的东西”。
  • @Dima 最后,你的决定是什么?你走哪条路?
  • @Bogdan Burim,我去创建“分区”来存储受时间跨度限制的少量数据。在我的例子中,一个“分区”可以保存几天的数据。在我的情况下,分区是一个单独的数据库,但使用集合也是有意义的。我想我选择了数据库,因为它们在很大时更容易丢弃。到目前为止效果很好。
  • @Dima 感谢您分享您的经验!

标签: mongodb


【解决方案1】:

这实际上取决于您查询的用例。

如果它是可以聚合的东西,我会说通过预定的 map/reduce 函数来做到这一点,并将较小的数据大小存储在单独的集合中。

如果一切都应该在同一个集合中,并且应该同时查询所有数据以生成所需的结果,那么您需要使用分片。然后根据查询的数据大小,您可以使用内存映射/减少,甚至可以在应用程序层进行。

正如您自己所指出的,基于时间的分片是一个非常糟糕的主意。它使所有写入都转到一个分片,因此请定义您的分片键。 MongoDB Docs,对此有很好的解释。

如果您可以详细说明您对查询的具体需求,那么提出建议会更容易。

希望对你有帮助。

【讨论】:

  • 该集合包含纯原始数据 - 一些传感器的读数。每个读数都是一堆扁平的名称-值对,它们构成一个文档。查询可以通过任何属性组合来完成,但时间总是存在的,并且是集合中的主要索引。我们已经使用分片来通过它们的来源传播这些观察结果。但是这些东西的剪切量让我怀疑单一收藏是否是正确的选择。
  • 您有哪些查询类型?您可以聚合旧记录并仅使用聚合值进行查询,还是需要为每个查询从头开始计算?还有你多久执行一次查询?
【解决方案2】:

我认为每月收集将帮助您提高一些能力,但我想知道为什么您不能使用时间戳的小时字段进行分片。您可以添加一个包含时间戳的 HOUR 部分的列,并且当您对它进行分片时,它将很好地共享,因为您每天都有重复的小时。我还没有测试它,但认为它会帮助你

【讨论】:

  • 实际上,当您提到“使用时间戳的小时字段进行分片”时,它敲响了警钟。我没有想过这个。我只是将绝对时间视为分片键。谢谢!
【解决方案3】:

建议继续进行单个收集,正如@Devesh 基于小时的分片所建议的那样,在查询时需要处理新的“小时键”以获得更好的性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2017-02-28
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多