我们从大量主机收集并存储仪器数据。 我们的存储是MongoDB - 带有副本的几个分片。一切都存储在一个大型集合中。 我们插入的每个文档都是基于时间的观察,具有一些属性(测量)。时间戳是最重要的属性,因为所有查询至少都基于时间。文档永远不会更新,因此它是一个纯粹的写入查找模型。现在它与数十亿个文档合作得很好。
现在,
我们希望增长一点并持有长达12个月的数据,这可能相当于一个可怕的万亿+观察(文件)。 如果将所有东西都倾倒在一个怪异的集合中是我最好的选择,或者有一种更聪明的方法可以解决这个问题。 我的意思是更聪明 - 使用更少的硬件,同时仍然提供快速插入和(重要的)快速查询。 所以我考虑将大型集合分成更小的部分,希望获得索引,插入和查询速度的记忆。
我查看了分片,但是时间戳分片听起来像个坏主意,因为所有写入都会进入一个节点,取消分片的好处。 插入率非常高,因此我们需要分片才能在此处正常工作。 我还考虑过每个月创建一个新的集合,然后为用户查询选择一个相关的集合。 超过12个月的馆藏将被删除或存档。 还可以选择每月创建一个全新的数据库,并进行类似的轮换。 其他选择?或者也许一个大型系列是 选项,以实现真正的大发展?
请在类似应用中分享您的经验和注意事项。
答案 0 :(得分:2)
这实际上取决于您的查询的用例。
如果它是可以聚合的东西,我会说通过预定的map / reduce函数执行此操作,并将较小的数据大小存储在单独的集合中。
如果所有内容都应该在同一个集合中,并且应该同时查询所有数据以生成所需的结果,那么您需要使用Sharding。然后,根据查询的数据大小,您可以使用内存映射/减少甚至在应用程序层执行此操作。
正如你自己所指出的,基于时间的Sharding是一个非常糟糕的主意。它使所有写入转到一个分片,因此定义分片键。 MongoDB Docs,对此有一个非常好的解释。
如果您可以详细说明查询的具体需求,则可以更容易地提出建议。
希望它有所帮助。
答案 1 :(得分:2)
我认为按月收集会帮助你获得一些提升,但我想知道为什么你不能使用时间戳的小时字段进行分片。您可以添加一个列,该列将保留时间戳的HOUR部分,当您对其进行分片时,将会很好地共享,因为您每天都在重复。我没有测试过,但认为它可以帮到你
答案 2 :(得分:0)
建议继续单一收藏,正如@Devesh小时基于碎片的建议应该没问题,需要照顾新的'小时钥匙'同时查询以获得更好的性能。