在阅读有关分片,分片键和块迁移的文档后,我仍然无法掌握一个概念。
任何试图描述为什么不选择自动增量分片键的概念的人告诉我,这是由于mongo将始终保持写入相同分片的结果,因此这会增加负载,因为那样shard将处理连续写入并同时迁移块。
我的问题是,为什么会这样?为什么自动递增值会导致写请求始终路由到一个特定的分片?分析的重点是mongos应该知道哪些碎片是“最小”平衡的,而是写入这个碎片,或者我理解它错了?
提前致谢
答案 0 :(得分:2)
当前的分片机制存在此问题。基本上,每个分片将提供其键位于连续范围内的数据。如果我们选择自动增量键,则所有写操作将仅路由到一个分片,该分片为密钥大于所有其他分片的数据提供服务。
这是使用自动增量键进行收集的问题。幸运的是,我们可以选择任何属性作为分片键。对于大多数情况,我们不会被迫使用“_id”作为分片键。如果object具有合适的属性,例如博客应用程序的“用户名”,我们可以将其用作分片键。如果没有合适的属性,我们可以为每个对象添加一个属性列作为分片键,可以使用一些简单的哈希算法计算该属性。例如,如果我们有一个自动增量_id,我们可以计算分片键,简单如下:
sharding_key = _id % 257
在你有超过257个分片之前,上面的哈希应该足够好了。
顺便说一下,自动生成的ObjectId不是分片密钥的好选择,因为它是基于时间的。
此外,MongoDB 2.3中还有一项新功能支持哈希密钥(请参阅https://jira.mongodb.org/browse/SERVER-2001和MongoDB 2.4 release note)。
答案 1 :(得分:2)
问题是如果使用单调增加的键,Mongo无法确定分片的关键范围。这是一个示例:
假设您有一个包含键10,20,30,40,50,60的集合 如果mongo必须创建两个分片,它可以假设键范围为:[10,30]和[31,60](或类似)。但是如果你继续写更大的键,它们总是会进入第二个范围。 Mongo将调整范围,但它永远不会知道下一个键是什么,它将始终进入最后一个范围。 另一方面,如果你使用一些具有良好分布的键,你的写序列将看起来更像:10,60,30,40,50 ......并且在写完两个第一个键之后,mongo将创建上述范围,并且您的下一个键将适合第一个或第二个。这将导致mongos之间的共享性能,并且也不会强迫mongo进行重新平衡。