一、概述
分片是一种将数据分布在多个 机器。MongoDB使用分片来支持具有非常大数据的部署 集和高吞吐量操作。
具有大型数据集或高吞吐量应用程序的数据库系统可以 挑战单个服务器的容量。例如,高查询率可以 耗尽服务器的 CPU 容量。工作集大小大于 系统的 RAM 会给磁盘驱动器的 I/O 容量带来压力。
有两种方法可以解决系统增长问题:垂直和水平 缩放。
垂直扩展涉及增加单个服务器的容量,例如 如使用更强大的 CPU、添加更多 RAM 或增加 存储空间。可用技术的限制可能会限制单个 机器对于给定的工作负载来说足够强大。此外 基于云的提供商具有基于可用硬件的硬天花板 配置。因此,垂直缩放有一个实际最大值。
水平扩展涉及划分系统数据集并加载 多台服务器,根据需要添加其他服务器以增加容量。 虽然单台机器的整体速度或容量可能不高,但每台 机器处理整体工作负载的子集,可能提供更好的 比单个高速高容量服务器的效率。扩展 部署容量只需要根据需要添加额外的服务器, 这可能比单台机器的高端硬件更低的总成本。 代价是基础设施和维护的复杂性增加 部署。
MongoDB支持水平扩展分片。
二、分片集群
MongoDB分片集群由以下组件组成:
- 分片:每个分片包含分片数据的一个子集。每个碎片都可以作为副本集部署。
- mongos:mongos充当查询路由器,在客户端应用程序和分片集群之间提供接口。从MongoDB 4.4开始,mongos可以支持对冲读取以最小化延迟。
- 配置服务器:配置服务器存储集群的元数据和配置设置。
下图描述了 分片集群:
MongoDB在收集级别,分发 跨集群中的分片收集数据。
1、分片键
MongoDB使用to 跨分片分发集合的文档。分片键 由文档中的一个或多个字段组成。
- 从版本 4.4 开始,分片集合中的文档可以是 缺少分片键字段。缺少分片键字段被视为 跨分片分发文档时具有空值,但 路由查询时不行。
- 在版本 4.2 及更早版本中,分片键字段必须存在于每个 分片集合的文档。
在以下情况下选择分片键对集合进行分片。
- 从MongoDB 5.0开始,您可以通过更改集合的碎片密钥来重新整理集合。
- 从MongoDB 4.4开始,您可以通过向现有分片密钥添加后缀字段来细化分片密钥。
- 在MongoDB 4.2及更早版本中,切分后无法更改切分密钥的选择。
文档的碎片键值决定了它在碎片中的分布。
- 从MongoDB 4.2开始,您可以更新文档的切分密钥值,除非切分密钥字段是不可变的_id字段。有关详细信息,请参见更改文档的碎片键值。
- 在MongoDB 4.0及更早版本中,文档的切分键字段值是不可变的。
分片索引
要对填充的集合进行切分,集合必须具有以切分键开头的索引。当对空集合进行分片时,如果该集合尚未为指定的分片键创建适当的索引,MongoDB将创建支持索引。请参见碎片关键索引。
分片键策略
分片键的选择会影响性能、效率和可扩展性 的分片集群。具有最佳硬件和 基础设施可能会因分片键的选择而成为瓶颈。的选择 分片键及其支持索引也会影响分片策略您的集群可以使用。
2、块
MongoDB将数据分片到块.每 块具有基于的包容性下限和排除上限范围分片键。
3、平衡器甚至块分布
试图实现块在所有 集群中的分片,一个平衡器在后台运行到 迁移块横跨碎片.
4、分片的优势
读/写
MongoDB将读写工作负载分布在碎片在分片集群,允许每个分片 处理群集操作的子集。读取和写入工作负载都可以 通过添加更多分片在集群中水平扩展。
对于包含分片键或前缀的查询复合分片键,mongos可以将查询定位在 特定分片或分片集。这些目标 操作通常比广播到集群中的每个分片。
从MongoDB 4.4开始,mongos可以支持对冲 读以最大程度地减少延迟。
存储容量
分片将数据分布在碎片在 集群,允许每个分片包含总集群数据的一个子集。如 数据集增长,额外的分片增加了 簇。
高可用性
配置服务器和分片作为副本集的部署提供 提高了可用性。
即使一个或多个分片副本集变得完全不可用, 分片集群可以继续执行部分读写。 也就是说,当无法访问不可用分片上的数据时, 针对可用分片的读取或写入仍然可以成功。
5、分片前的注意事项
分片集群基础架构要求和复杂性要求 仔细规划、执行和维护。
一旦集合被分片,MongoDB不提供任何方法来 解分 分片集合。
虽然你可以重新分片您的收藏稍后,请务必仔细考虑您的分片键选择 避免可伸缩性和性能问题。
如果查询不包含分片键或前缀复合分片键,mongos执行 一个广播操作,查询分片集群中的所有分片。这些分散/收集查询可以 是长时间运行的操作。
从 MongoDB 5.1 开始,当启动、重新启动或添加分片服务器跟sh.addShard()这集群范围写入关注点 (CWWC)必须设置。
如果未设置且分片已配置 这样CWWC默认写入关注点是分片服务器将无法启动或添加 并返回错误。{ w : 1 }
看默认写入关注点计算为 有关如何计算默认写入关注点的详细信息。
6、分片和非分片集合
数据库可以混合使用分片集合和非分片集合。分片 收藏是分区并分布在碎片在群集中。未分片的集合存储在主分片.每个数据库都有自己的主分片。
7、连接到分片集群
您必须连接到mongos路由器才能与碎片集群中的任何集合进行交互。这包括分片和未分片的集合。为了执行读或写操作,客户端不应连接到单个碎片。
您可以使用mongosh或MongoDB驱动程序以与mongod相同的方式连接mongos。
8、分片策略
MongoDB支持两种分片策略,用于跨分片集群分发数据。
哈希分片
哈希分片涉及计算分片密钥字段值的哈希。然后,根据散列的碎片键值为每个块分配一个范围。
虽然一系列分片键可能“接近”,但它们的哈希值不太可能 要在同一上块.基于哈希值的数据分布 促进更均匀的数据分布,特别是在数据集中 分片键更改单调。
但是,散列分布意味着对分片键进行基于范围的查询 不太可能以单个分片为目标,从而导致集群范围更大广播操作
远程分片
范围分片涉及将数据划分为基于范围 分片键值。每块然后根据 分片键值。
9、分片集群中的可用区
分区可以帮助改善跨越多个数据中心的分片集群的数据位置。
在分片集群中,可以基于分片密钥创建分片数据区域。您可以将每个分区与集群中的一个或多个碎片相关联。碎片可以与任意数量的区域关联。在一个平衡集群中,MongoDB只将一个区域覆盖的块迁移到与该区域关联的那些碎片。
每个区域包含一个或多个碎片键值范围。区域覆盖的每个范围始终包括其下边界,不包括其上边界。
您必须使用分片键定义新的时 要覆盖的区域的范围。如果使用复合碎片 键,则范围必须包含分片键的前缀。看分片键 在区域中了解更多信息。
10、分片中的排序规则
使用shardCollection命令,可以选择对具有collation : { locale : "simple" }默认排序规则.成功的 分片要求:
- 集合必须具有前缀为分片键的索引
- 索引必须具有排序规则{ locale: "simple" }
使用排序规则创建新集合时,请确保满足以下条件 在对集合进行分片之前满足。
11、事务
从MongoDB 4.2开始,随着分布式事务的引入,多文档事务在分片集群上可用。
在事务提交之前,事务中所做的数据更改在事务外部是不可见的。
然而,当事务写入多个碎片时,并非所有外部读取操作都需要等待提交事务的结果在碎片中可见。例如,如果提交了一个事务,并且写1在碎片a上可见,但写2在碎片B上尚不可见,则外部读时关注点“本地”可以读取写1的结果,而不会看到写2。