选择分片键
分片键的选择会影响分片的创建和数据块在可用分片之间的分布。数据的分布会影响分片集群中操作的有效性和性能。
理想的分片键允许MongoDB在集群中均匀地分配文档,同时也有利于常见的查询模式。
在选择您的分片键时,请考虑以下因素:
注意
从MongoDB 5.0开始,您可以使用更改分片键并使用
reshardCollection
命令重新分配您的数据。您可以使用
refineCollectionShardKey
命令来细化集合的分片键。该refineCollectionShardKey
命令将后缀字段或字段添加到现有键中,以创建新的分片键。除非分片键字段是不可变的
_id
字段,否则您可以更新文档的分片键值。
重要
如果您经常更改文档的分片键值,使其值位于不同分片拥有的分片键范围内,则可能会由于在分片之间迁移文档所涉及的资源而影响集群性能。有关详细信息,请参阅使用数据块的数据分区和db.collection.updateOne().
分片键基数
分片键的基数决定了平衡器可以创建的最大数据块数量。尽可能选择具有高基数的分片键。具有低基数的分片键会降低集群水平扩展的有效性。
每个唯一的分片键值在任何给定时间只能存在于单个分片中。考虑一个包含用户数据的continent
字段的数据集。如果您选择在continent
上分片,则分片键将具有7
的基数。基数7
表示在分片集群中不能有超过7
个分片,每个分片存储一个唯一的分片键值。这限制了集群中有效分片数也为7
,添加超过七个分片不会带来任何好处。
以下图像展示了使用字段X
作为分片键的分片集群。如果X
具有低基数,插入数据的分布可能看起来像以下这样
如果您的数据模型需要在基数较低的关键上进行分片,考虑使用字段的索引组合
来增加基数。
高基数的分片键本身并不能保证数据在分片集群中的均匀分布。分片键的频率
以及潜在的单调变化分片键值
也影响了数据的分布。
分片键频率
分片键的频率
表示给定分片键值在数据中出现的频率。如果大多数文档只包含可能分片键值的一个子集,那么存储具有这些值的文档的分片可能会成为集群中的瓶颈。此外,随着这些分片变大,它们可能成为无法进一步分割的不可分割的分片
,因为它们无法再分割。这降低了集群中水平扩展的有效性。
以下图像展示了使用字段X
作为分片键的分片集群。如果X
的某些值出现频率很高,插入数据的分布可能看起来像以下这样
如果您的数据模型需要在具有高频值的关键上进行分片,考虑使用具有唯一或低频值的组合索引
。
低频率的分片键本身并不能保证数据在分片集群中的均匀分布。分片键的基数
以及潜在的单调变化分片键值
也影响了数据的分布。
单调变化的分片键
在单调增加或减少的值上的分片键更有可能将插入操作分发到集群中的单个分片中。
这是因为每个集群都有一个包含具有上界MaxKey
的范围的分片。 maxKey
总是比较为高于所有其他值。同样,还有一个包含具有下界MinKey
的范围的分片。minKey
总是比较为低于所有其他值。
如果分片键值始终增加,所有新的插入都会路由到具有maxKey
作为上界的分片。如果分片键值始终减少,所有新的插入都会路由到具有minKey
作为下界的分片。包含该分片的分片成为写操作的性能瓶颈。
为了优化数据分布,包含全局maxKey
(或minKey
)的分片不会留在同一个分片中。当一个分片被分割时,具有maxKey
(或minKey
)的分片位于不同的分片中。
以下图像展示了使用字段X
作为分片键的分片集群。如果X
的值是单调增加的,插入的分布可能看起来像以下这样
如果分片键值是单调减少的,那么所有插入都会路由到Chunk A
。
如果您的数据模型需要根据单调变化的键进行分片,请考虑使用哈希分片。
一个不单调变化的分片键本身并不能保证数据在分片集群中的均匀分布。《分片键的基数》和《分片键的频率》也影响了数据的分布。
分片查询模式
理想的分片键能够在分片集群中均匀地分配数据,同时也有助于常见的查询模式。在选择分片键时,请考虑您的最常见查询模式以及给定的分片键是否覆盖了这些模式。
在分片集群中,如果查询包含分片键,则mongos
只会将查询路由到包含相关数据的分片。当查询不包含分片键时,查询将被广播到所有分片以进行评估。这类查询称为散射聚合查询。涉及每个请求多个分片的查询效率较低,并且当集群中添加更多分片时,其扩展性不会线性增加。
这并不适用于在大量数据上运行的聚合查询。在这些情况下,散射聚合可以是一个有用的方法,它允许查询在所有分片上并行运行。
使用7.0中的分片键分析器找到您的分片键
从7.0版本开始,MongoDB使选择分片键变得更加容易。您可以使用analyzeShardKey
,该命令计算用于评估未分片或分片集合的分片键的指标。这些指标基于样本查询,使您能够根据数据驱动的方式选择分片键。
启用查询采样
要分析分片键,必须在目标集合上启用查询采样。有关更多信息,请参阅
要监控查询采样过程,使用 $currentOp
阶段。例如,请参阅 采样查询。
分片键分析命令
要分析分片键,请参阅
analyzeShardKey
数据库命令
analyzeShardKey
返回有关分片键特征及其读写分布的指标。这些指标基于采样查询。