Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs 菜单
Docs 主页
/

分片

分片是一种跨多台机器分布数据的方法。MongoDB 使用分片来支持超大数据集和高吞吐量操作的部署。

存在大型数据集或高吞吐量应用程序的数据库系统可能对单个服务器的容量构成挑战。例如,较高的查询速率可能会耗尽服务器的 CPU 容量。大于系统 RAM 的工作集大小会对磁盘驱动器的 I/O 容量造成压力。

有两种方法解决系统增长问题:垂直扩展和水平扩展。

垂直扩展通过使用更强大的 CPU、添加更多RAM或扩展存储来增加单个服务器的容量。现有技术和云提供商硬件配置为垂直扩展规定了实际的最大值。

横向扩展涉及将系统数据集和负载划分到多个服务器,以及根据需要添加更多服务器以增加容量。每台机器处理整体工作负载的一部分,这可能会导致单台机器的费用低于高端硬件。代价是基础架构和维护的复杂性增加。

您可以在用户界面中为 MongoDB Atlas 托管的部署 分片集群 。

MongoDB 分片集群由以下组件构成:

下图描述了分片集群内各组件之间的交互:

用于生产目的的示例分片集群示意图。实际包含 3 个配置服务器、2 个或更多“mongos”查询路由器以及至少 2 个分片。这些分片均为副本集。

MongoDB 在集合级别对数据进行分片,从而将集合数据分布到集群中的分片上。

MongoDB 使用分片键在分片之间分发集合的文档。 分片键由文档中的一个或多个字段组成。

分片集合中的文档可能缺少分片键字段。跨分片分发文档时,缺少的分片键字段将视为具有 null 值,但在路由查询时则不会。有关更多信息,请参阅缺少分片键字段

您在对集合进行分片时会选择分片键。

文档的分片键值决定了其在各分片中的分布。您可以更新文档的分片键值,除非您的分片键字段是不可变的 _id 字段。有关详细信息,请参阅更改文档的分片键值

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

分片键及其后备索引的选择也会影响集群可以使用的分片策略。

提示

MongoDB 将数据分片为数据段。每个数据段都有一个基于分片键、包含下限且不包含上限的范围。

为了在集群中的所有分片之间实现均匀的数据分布,负载均衡器在背景运行以跨分片迁移范围。

MongoDB 在分片集群中的分片之间分配读写工作负载,支持每个分片处理集群操作的子集。通过添加更多的分片,读写工作负载都可以在集群中横向扩展。

对于包含分片键或复合分片键前缀的查询,mongos 可将查询定向到特定分片或一组分片。这些有针对性的操作通常比向集群中的每个分片进行广播更为有效。

mongos 可支持对冲读,从而最大限度地降低延迟。

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

按副本集部署配置服务器和分片,可提高可用性。

即使一个或多个分片副本集变为完全不可用,分片集群仍可继续执行部分读取和写入操作。换言之,即便无法访问不可用分片上的数据,针对可用分片的读取或写入仍可成功完成。

需要对分片集群基础架构的需求和复杂性进行仔细规划、执行和维护。

集合被分片后,MongoDB 就不再提供对分片集合进行取消分片的方法。

虽然您可以稍后对集合重新分集合,但请仔细考虑分片键的选择,以避免可扩展性和性能问题。

要了解集合分片操作的要求和限制,请参阅分片集群中的操作限制。

如果查询含分片键或复合分片键的前缀,mongos 则会执行广播操作,从而查询分片集群中的所有分片。这些分散/聚集查询可能会长时间运行。

从 MongoDB 5.1 开始,在启动、重新启动或添加含 sh.addShard()分片服务器时,必须设置集群范围的写关注 (CWWC)

如果未设置 CWWC,并且将分片配置成默认写关注{ w : 1 },将无法启动或添加分片服务器并返回错误。

请参阅默认写关注计算,详细了解如何计算默认写关注。

注意

如果您与 MongoDB 签订了有效的支持合同,请考虑联系您的客户代表,以获取分片集群规划和部署方面的帮助。

数据库可混合使用分片和未分片集合。分片集合会进行分区并分布在集群的各个分片上。未分片集合则存储在主分片上。每个数据库均有自己的主分片。

主分片的示意图。主分片包含非分片集合以及分片集合中文档的数据段。分片 A 为主分片。

您必须连接到mongos路由器才能与分片集群中的任何集合交互。这包括分片的和未分片集合。客户端永远不应连接到单个分片来执行读取或写入操作。

应用程序/驱动程序向 mongos 发出查询以进行非分片集合和分片集合的图表。未显示配置服务器。

您可像使用 mongosh 或 MongoDB 驱动程序以连接到 mongod 一样来连接 mongos

MongoDB 支持两种分片策略,可在多个分片集群之间分配数据。

哈希分片计算分片键字段值的哈希值。然后,根据哈希分片键键值,为每个数据块分配一个范围。

提示

在使用哈希索引解析查询时,MongoDB 会自动计算哈希值。应用程序无需计算哈希值。

基于哈希的分割示意图。

哈希值不太可能股票相同的数据数据块,从而提供更均匀的数据分布,尤其是对于单调变化的分片键。

然而,哈希分布意味着对分片键的基于范围的查询不太可能以单个分片为目标,从而导致更多的集群范围的广播操作。

请参阅哈希分片以了解更多信息。

范围分片根据分片键将数据划分为多个范围,为每个数据块分配这些范围之一。

分片键值空间被分割为较小范围或数据块的示意图。

具有“相近”数值的一系列分片键更有可能位于同一个数据段上。这允许进行有针对性的操作,因为 mongos 只能将操作路由到包含所需数据的分片。

范围分片的效率取决于所选分片键。考虑不周的分片键可能会导致数据分布不均,从而抵消分片的某些好处甚或导致性能瓶颈。请参阅针对基于范围的分片的分片键选择

有关更多信息,请参阅范围分片

区域可改善跨多个数据中心的分片的集群的数据局部性。

在分片集群中,可以根据分片键创建分片数据区域。您可以将每个区域与集群中的一个或多个分片相关联。一个分片可以与任意数量的区域关联。在均衡的集群中,MongoDB 仅将区域覆盖的数据段迁移到与该区域相关联的分片。

每个区域涵盖分片键值的一个或多个范围。某一区域所覆盖的每个范围始终包括其下边界,而不包括其上边界。

分片集群中基于可用区域的数据分布图
点击放大

为要覆盖的区域定义范围时,必须使用分片键中包含的字段。如果使用的是复合分片键,此范围则须包含分片键的前缀。请参阅区域中的分片键以了解更多信息。

选择分片键时,请考虑未来潜在的区域使用。

提示

在对空的或不存在的集合进行分片之前设置区域和区域范围可更快地设置分区分片。

请参阅区域以了解更多信息。

使用带 collation : { locale : "simple" } 选项的 shardCollection 命令对具有默认排序规则的集合进行分片。要成功进行分片,必须满足以下条件:

  • 集合必须具有其前缀为分片键的索引

  • 索引必须具有排序规则 { locale: "simple" }

使用排序规则创建新集合时,请确保在对集合分片之前满足这些条件。

注意

对分片集合的查询会继续使用为集合配置的默认排序规则。要使用分片键索引的 simple 排序规则,请在查询的排序规则文档中指定 {locale : "simple"}

有关分片和排序规则的更多信息,请参阅 shardCollection

从 MongoDB 3.6 开始,变更流 可用于副本集和分片集群。变更流允许应用程序访问实时数据变化,而无需实时跟踪 oplog ,这可能相当复杂且容易出错。应用程序可以使用变更流来订阅一个或多个集合上的所有数据变更。

分布式事务支持分片的集群上的多文档事务。

在事务进行提交前,在事务中所做的数据更改在事务外不可见。

不过,当事务写入多个分片时,并非所有外部读取操作都需等待已提交事务的结果在各个分片上可见。例如,如果事务已提交并且写入 1 在分片 A 上可见,但写入 2 在分片 B 上尚不可见,则读关注 "local" 处的外部读取可以在不看到写入 2 的情况下读取写入 1 的结果。

有关分片如何与聚合结合使用的更多信息,请阅读《实用MongoDB聚合》电子书中的分片章节。

后退

本地数据库

获得技能徽章

免费掌握“分片策略”!

了解详情

在此页面上