centos mongodb 第十九节课 分片集群

centos mongodb 第十九节课   分片集群

 

 《MongoDB基础、运维与性能优化》

 

分片键介绍
MongoDB 数据库使用分片键在分片之间分发集合的文档,分片键由文档中的一个或多个字段组成,分片集合中的文档可能缺少分片键字段。当跨分片分发文档时,缺少的分片键字段时将被视为 null 值,但在路由查询时则不会。

从 MongoDB 5.0 版本开始,就可以通过更改集合的分片键对集合重新分片。此外,还可以通过向现有分片键添加后缀字段或添加新字段来优化分片键。文档的分片键值决定了其在各分片中的分布。我们可以更新文档的分片键值,除非分片键字段是不可变的_id字段。

分片键索引用于对已填充的集合进行分片,该集合必须具有以分片键开头的索引。对空集合进行分片时,如果该集合还没有指定分片键的适当索引,MongoDB 数据库会创建支持索引。

MongoDB 数据库将数据分片为数据段,每个数据段都有一个基于分片键、包含下限且不包含上限的范围。为了实现数据在集群中所有分片上的均匀分布,负载均衡器会在后台运行,以便在各分片之间迁移范围。

 

 

 

 


分片的优点
MongoDB 数据库分片具有如下几项优点。
1)读取/写入优点
MongoDB 在分片集群中的分片之间分配读写工作负载,支持每个分片处理集群操作的子集。通过添加更多的分片,读写工作负载都可以在集群中横向扩展。
对于包含分片键或复合分片键前缀的查询,mongos 可将查询定向到特定分片或一组分片。这些有针对性的操作通常比向集群中的每个分片进行广播更为有效。

2)存储容量优点
分片将数据分布在集群中的分片上,从而允许每个分片包含整个集群数据的子集。随着数据集的增长,更多的分片会增加集群的存储容量。

3)高可用性优点
按副本集来部署配置服务器和分片,可提高可用性。即使一个或多个分片副本集变为完全不可用,分片集群仍可继续执行部分读取和写入操作。换言之,即便无法访问不可用分片上的数据,针对可用分片的读取或写入仍可成功完成。

 

 

 

 


分片集群的组成
MongoDB 数据库在集合级别对数据进行分片,从而将集合数据分布到集群中的分片上。
MongoDB 分片集群由以下组件构成。
分片:每个分片都包含分片数据的一个子集。每个分片都必须作为一个副本集进行部署。
mongos:mongos 充当查询路由器,在客户端应用程序和分片集群之间提供接口。
配置服务器:配置服务器会存储集群的元数据和配置设置。配置服务器必须以副本集(CSRS)的形式部署。

分片集群内各组件之间的交互

 QQ截图20261011201215

 

 

 


生产配置
最多只能部署 30 个 mongos 路由器。

在生产配置中,常用的分片集群架构如图 12.2 所示。

 QQ截图20261011201910

 

 

 

 

 


分片键索引
MongoDB 分片键可以是单个索引字段,也可以是复合索引涵盖的多个字段,复合索引决定了集合文档在集群分片中的分布。
MongoDB 将分片键值(或哈希分片键值)的取值区间划分为不重叠的分片键值(或哈希分片键值)范围。每个分片键值范围都与一个数据块相关联,MongoDB 会尝试在集群中的各个分片之间均匀分配这些数据块。分片键与数据段分发的有效性有直接关系。
MongoDB 中的所有分片集合都必须具有支持分片键的索引。索引可以是分片键上的索引,也可以是复合索引,其中分片键是索引的前缀。如果集合为空,则 sh.shardCollection() 会在分片键上创建索引(如果此类索引尚不存在)。如果集合不为空,则必须先创建索引,然后才能使用 sh.shardCollection()进行分片。如果索引是唯一支持分片键的非隐藏索引,则无法将其删除或隐藏。
MongoDB 可以对分片键值范围内的分片键索引执行唯一性约束。通过在分片键上使用唯一索引,MongoDB 将确保整个键的组合的唯一性,而不是分片键的各个组成部分。对于分片键值范围内的分片集合,只有以下索引是唯一的:
分片键上的索引。
一个复合索引,其中分片键是前缀。
默认_id索引。

只有当_id字段也是分片键时,分片集群才会在整个集群中对_id字段执行唯一性约束。如果_id字段不是分片键,或者只是分片键的前缀,则唯一性约束只适用于存储文档的分片。这意味着两个或多个文档可以具有相同的_id值,前提是其出现在不同的分片上。如果_id字段不是分片键,MongoDB 希望应用程序确保所有分片上_id值的唯一性。

 

如果是唯一索引约束,则意味着以下几点:
对于即将被分片的集合,如果该集合还有其他的唯一索引,则无法对其进行分片。
对于已分片的集合,无法在其他字段上创建唯一索引。
唯一索引为缺少索引字段的文档存储空值,即缺少的索引字段将被视为 null 索引键值的另一个实例。

要确保分片键值的唯一性,需要将 unique 参数设置为 true 值传递给 sh.shardCollection()方法,详细说明如下:
如果集合为空,sh.shardCollection()会在分片键上创建唯一索引(条件是这种索引尚不存在)。
如果集合不为空,则必须先创建索引,然后才能使用 sh.shardCollection()进行分片。

尽管可以有以分片键为前缀的唯一复合索引,但如果使用 unique 参数,则集合必须在分片键上有唯一索引。另外,不能在哈希索引上指定唯一约束。

 

 

 

 

将集合分片

MongoDB 必须指定要进行分片的集合的完整命名空间和分片键,才能对其进行分片。我们可以使用 mongosh 方法 sh.shardCollection()对集合进行分片:

sh.shardCollection(<namespace>, <key>)

第 1 个参数 namespace 指定设计人员想要对其进行分片的集合的完整命名空间("<database>.<collection>")
第 2 个参数 key 指定文档{<shard key field1>: <1|"hashed">, ...},其中 1 表示基于范围的分片,"hashed"表示哈希分片。

关于分片键字段与字段值,具体描述如下。
1、缺少的分片键字段:分片集合中的文档可能缺少分片键字段。缺失的分片键与值为 null 的分片键属于同一范围。
2、更改文档的分区密钥值:可以更新文档的分片键值,除非分片键字段是不可变的 _id 字段。
3、更改集合的分片键:从 MongoDB 5.0 版本开始,可以通过更改文档的分片键对集合重新分片。设计人员可以通过向现有分片键添加后缀字段来优化分片键。

 


分片键选择因素
MongoDB 分片键的选择会影响数据段的创建和在可用分片间的分配。数据的分布会影响分片集群内操作的效率和性能。
理想的分片键可以让 MongoDB 在整个集群中均匀地分发文档,同时也有利于实施常见的查询模式。
在选择分片键时,需要考虑以下几点:
1、分片键的关联基数。-》分片数,巨型数据块
2、分片键值出现的频率。-》数据分布,均匀/倾斜
3、潜在的分片键是否单调递增。-》数据热点
4、分片查询模式。
5、分片键限制。

如果频繁更改文档的分片键值,以使该值位于不同分片拥有的分片键范围,则可能会影响集群性能,因为不停在分片之间迁移文档会损耗性能。

(1)分片键的关联基数
分片键的关联基数决定了负载均衡器可以创建的最大数据段数。尽可能选择关联基数高的分片键。
关联基数低的分片键会降低集群中水平扩展的有效性。在任何给定时间,每个唯一的分片键值只能存在于一个数据段上。

现在考虑一个数据集,其包含带有 continent 字段的用户数据。如果选择在 continent 上进行分片,世界上只有7个大陆,则分片键的关联基数将为 7。关联基数为 7 意味着分片集群内的数据段不能超过 7 个,每个数据段存储一个唯一的分片键值。这也会将集群中的有效分片数限制为 7,即添加 7 个以上的分片不会带来任何好处。如果数据模型要求在关联基数较低的键上进行分片,可考虑使用字段的复合索引来增加关联基数。

QQ截图20261019225226

(2)分片键频率
分片键频率表示给定分片键值在数据中出现的频率。如果多数文档仅包含可能的分片键值的一部分,则存储具有这些值的文档的数据段可能会成为集群内的瓶颈。此外,随着这些数据段的增长,它们可能会成为不可分割的数据段,因为它们无法被进一步分割。这会降低集群内横向扩展的有效性。如果数据模型要求在具有高频值的键上进行分片,可以考虑使用唯一或低频率值的复合索引。

QQ截图20261019225117

(3)分片键单调变化
针对单调增加或减少的值的分片键,更有可能将插入操作分布到集群内的单个数据段中。之所以发生这种情况,是因为每个集群都有一个捕获范围上限为 maxKey 的数据段,maxKey 始终是所有值中最高的值。同样,还有一个捕获范围下限为 minKey 的数据段,minKey 始终是所有值中最低的值。如果分片键值总是增加的,则所有新的插入操作都会路由到以 maxKey 为上限的数据段。如果分片键值总是减少的,则所有新的插入操作都会路由到以 minKey 为下限的数据段。包含该上下限数据段的分片会成为写入操作的瓶颈。为优化数据分布,包含全局 maxKey(或 minKey)的数据段不会位于同一分片。在分割数据段时,具有 maxKey(或 minKey)数据段的新数据段会位于不同的分片。如果分片键值单调递减,则所有插入操作都将改为路由到 Chunk A。如果数据模型需要对单调变化的键进行分片,可以考虑使用哈希分片。

 QQ截图20261019230806


关于分片查询模式的使用,理想的分片键可将数据均匀地分布在分片集群中,同时也有利于实施常见的查询模式。在选择分片键时,可考虑最常使用的查询模式以及给定分片键能否涵盖这些模式。在分片集群中,如果查询包含分片键,则 mongos 仅会将这些查询路由到包含相关数据的分片。如果查询不包含分片键,则这些查询会被广播到所有分片以进行评估。这些类型的查询称为 “分散 - 聚合” 查询。每个请求涉及多个分片的查询效率较低,并且向集群添加更多分片时无法实现线性扩展。
这不适用于针对大量数据进行操作的聚合查询。在这些情况下,“分散 - 聚合” 查询可能是一种有用的方法,因为它允许查询在所有分片上并行运行。

 

 

 

 

 

 

f

posted @ 2026-10-11 20:04  huangchaolilli  阅读(0)  评论(0)    收藏  举报