Docs 菜单
Docs 主页
/
MongoDB Manual

分片

在此页面上

  • 分片集群
  • 分片键
  • 数据段
  • 负载均衡器和均匀数据分布
  • 分片的优点
  • 分片前的考虑因素
  • 分片和非分片集合
  • 连接到分片集群
  • 分片策略
  • 分片集群中的区域
  • 分片中的排序规则
  • Change Streams
  • 事务
  • 了解详情

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

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

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

Vertical Scaling(垂直扩展)涉及增大单个服务器的容量,例如使用更强大的 CPU、添加更多 RAM 或增加存储空间量。可用技术所存在的限制可能会导致单个机器对给定工作负载来说不够强大。此外,基于云的提供商存在基于可用硬件配置的硬上限。因此,垂直扩展存在实际的最大值。

Horizontal Scaling(横向扩展)涉及将系统数据集和负载划分到多个服务器,以及按需增加服务器以提高容量。虽然单个机器的总体速度或容量可能不高,但每个机器均可处理总体工作负载的一部分,因此可能会比单个高速、高容量服务器提供更高的效率。扩展部署的容量只需按需添加额外的服务器,而这可能会比单个机器的高端硬件的整体成本更低。但代价在于它会增大部署的基础设施与维护的复杂性。

MongoDB 支持通过分片进行水平扩展

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

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

  • 分片:每个分片都包含分片数据的一个子集。每个分片都必须作为一个副本集进行部署。

  • mongos mongos充当查询路由器,在客户端应用程序和分片集群之间提供接口。 mongos可以支持对冲读,以最大限度地减少延迟。

  • 配置服务器:配置服务器会存储集群的元数据和配置设置。 从 MongoDB 3.4 开始,配置服务器必须作为副本集 (CSRS) 部署。

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

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

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

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

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

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

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

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

分片键的选择会影响分片集群的性能、效率和可扩展性。 具有最佳硬件和基础架构的集群可能会因为选择分片键而遇到瓶颈。 分片键及其后备索引的选择也会影响集群可以使用的分片策略

提示

另请参阅:

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

为了实现数据在集群中所有分片上的均匀分布,负载均衡器会在后台运行,以便在各分片之间迁移范围

提示

另请参阅:

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

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

mongos可以支持对冲读,以最大限度地减少延迟。

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

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

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

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

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

虽然您可在后续对集合重新分片,但请务必仔细考虑分片键的选择,以免出现可扩展性与性能问题。

提示

另请参阅:

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

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

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

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

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

注意

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

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

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

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

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

您可以使用 或 MongoDBmongos mongodmongosh驱动程序 以与连接到 相同的方式连接到 。

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

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

提示

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

基于哈希的分割示意图。

虽然分片键的范围可能“相近”,但它们的哈希值却不太可能位于同一数据段。基于哈希值的数据分配可促进更均匀的数据分布,尤其是在分片键单调变化的数据集中。

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

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

范围分片涉及根据分片键值将数据划分为多个范围。然后,根据分片键值为每个数据段分配一个范围。

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

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

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

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

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

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

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

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

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

在选择分片键时,应考虑将来可能使用区域的情况。

提示

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

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

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

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

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

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

注意

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

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

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

随着分布式事务的引入,可以在分片集群上使用多文档事务。

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

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

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

← 副本集成员状态