我无法理解MongoDB分片集群中的分片键概念,因为我刚开始学习MongoDB。
引用MongoDB文档:
块是分配给a的分片键值的连续范围 特别是碎片。当它们超出配置的块大小时,a mongos将块分成两个块。
似乎chuck大小与特定分片相关,而不是与群集本身相关。我对吗?
说到分片键的基数:
考虑使用状态字段作为分片键:
状态键的值 持有美国州的特定地址文件。这个领域很低 基数为所有在州内具有相同值的文档 字段必须位于同一个分片,即使是特定的状态 块超过了最大块大小。
由于状态字段的可能值有限,MongoDB可能会在少量固定块之间不均匀地分配数据。
我的问题是分片键如何与块大小相关。
在我看来,只有两个分片服务器,就不可能分发数据,因为状态字段中的相同值必须位于同一个分片上。有三个文档的状态如 Arizona , Indiana 和 Maine ,数据如何在两个分片之间分配?
答案 0 :(得分:6)
为了理解您的问题的答案,您需要了解基于范围的分区。如果您有N个文档,它们将被分区为块 - 确定分割点的方式基于您的分片键。
使用分片键作为文档中的某个字段,将考虑分片键的所有可能值,并且所有文档将(逻辑上)分割为块/范围,具体取决于每个文档的分片键的值。 / p>
在你的例子中,“状态”有50个可能的值(好吧,可能更像52)所以最多只能有52个块。默认块大小为64MB。现在想象一下,你正在分割一个包含一千万个文件的集合,每个文件各1K。每个块不应包含超过65K的文档。一千万个文件应分成150多个块,但我们只有52个不同的值用于分片键!所以你的块会非常大。为什么这是一个问题?好吧,为了在分片之间自动平衡块,系统需要在分片之间迁移块,如果块太大,则无法移动。而且由于它不能被拆分,你将陷入不平衡的集群。
答案 1 :(得分:0)
分片键和块大小之间肯定存在关系。您想要选择具有高级基数的分片键。也就是说,您需要一个可以具有许多可能值的分片键,而不是像State这样基本上只锁定到50个可能值的值。像这样的低基数分片键可能导致只包含一个分片键值的块,因此在平衡操作中不能分割并移动到另一个分片。
分片密钥的高基数(如人的电话号码而不是其州或邮政编码)对于确保均匀分发数据至关重要。低基数分片键可能会导致更大的块(因为您有更多连续的值需要保存在一起),这些不能被拆分。