MongoDB 使用与集合关联的分片键数据分区为特定分片所拥有的数据块。一个数据块由一个分片数据范围 成。每个数据块都具有基于分片键的包含下限和排除上限。
数据段可以表示的最小数据单位是单个唯一的分片键值。
初始数据段
已填充集合
分片操作会创建一个较大的初始数据段来覆盖所有分片键值。
创建初始数据段后,负载均衡器会在需要开始平衡数据时移动初始数据段的范围。
空集合
如果为空集合或不存在的集合定义了区域和区域范围。
分片操作会为定义的区域范围创建空数据块和任何其他数据块以覆盖分片键的整个范围,并根据区域范围执行初始数据块分布。数据块的初始创建和分布可以更快地设置区域分片。
在初始分布之后,负载均衡器将管理未来的数据段分布。
如果您没有为空集合或不存在的集合定义的区域和区域范围:
对于哈希分片:
分片操作创建空数据块以覆盖分片键值的整个范围,并执行初始数据块分配。默认情况下,该操作为每个分片创建 2 个数据块,并在集群中迁移。
在初始分布之后,负载均衡器将管理未来的数据段分布。
对于范围分片:
分片操作创建一个空数据段来覆盖分片键值的整个范围。
创建初始数据块后,负载均衡器会根据需要在分片之间迁移初始数据块,并管理未来的数据块分布。
范围大小
MongoDB 中的默认范围大小为 128 MB。可以增大或缩小数据段大小。考虑更改默认数据段大小的影响:
小范围会使数据分布更均匀,但代价是迁移更频繁,这会增加查询路由 (
mongos) 层的开销。较大的范围会导致迁移较少,从而减少查询路由层的网络和内部开销,但可能会导致数据分布不均。
范围大小会影响要迁移的每个范围的最大文档数。
对于大多数部署来说,稍微不均匀的数据分布比频繁迁移要好。
范围迁移
MongoDB 迁移分片集群中的数据范围,以便在分片之间均匀地分配分片集合的数据。 迁移可能是:
手动。仅在有限的情况下使用手动迁移,例如批量插入时分配数据。请参阅手动迁移数据段,了解详情。
有关分片集群负载均衡器的更多信息,请参阅分片集群负载均衡器。
均衡
负载均衡器是管理数据迁移的背景进程。如果最大分片和最小分片之间的数据不平衡超过迁移阈值,负载均衡器开始在集群中迁移数据。
重新分片以实现平衡
当您运行sh.shardCollection() 方法时,负载均衡器开始将集合数据分发到集群中的其他分片。单个分片一次只能参与一个数据块迁移。当MongoDB成功将一定范围的数据从一个分片复制到另一个分片时,源分片上的范围将被范围删除器标记为待删除。此进程缓慢且需要大量资源。
从MongoDB 8.0 开始,如果您的部署满足资源要求,建议您使用sh.shardAndDistributeCollection() 方法对集合分片。此方法封装 shardCollection 和 reshardCollection 命令以对集合分片,并立即将其重新分片为相同的键。这会导致MongoDB在各分片之间重新平衡数据,而无需等待负载均衡器。
有关更多信息,请参见重新分片到相同分片键。
不可再分割/巨型数据段
增长超过 指定的数据块大小但无法分割的数据块称为巨型块。最常见的原因是用数据块表示单个分片键值。巨型块可能会成为性能瓶颈,尤其是当分片键值出现频率较高时。
从 MongoDB 5.0 开始,您可以通过更改文档的分片键对集合重新分片。
refineCollectionShardKey 命令可实现更细粒度的数据分布,并可解析由于分片键关联基数不足而导致的巨型块。
要了解应该对集合进行重新分片还是优化分片键,请参阅更改分片键。
有关更多信息,请参阅: