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