mongodb 基本原理:分片(Sharding)

时间:2024-04-06 18:02:13

分片 是将数据分布在多台机器的方法。MongoDB 使用分片来提供海量数据的部署和高吞吐操作 .

这种数据库系统可以挑战单服务器的最高容量,例如高频率的查询可以将服务器的cpu容量发挥到极致。超出系统内存的数据集则会充分调用磁盘的IO。

面对系统扩充有两种方法:垂直扩展和水平扩展

垂直扩展

提高单台服务器的容量,例如使用更强的cpu,加内存,存储空间。技术的局限限制了单台机器面对高负载的能力。除此外云提供商的服务也有资源上限。所以垂直扩展有明显的天花板。

水平扩展

将系统的数据和负载分配到多台服务器,根据实际需要添加机器。即使单台机器的能力有限,每个机器分担一些负载,全局的能力比单台高性能机器要好。扩展容量仅需要添加机器即可,比增加单台机器的性能成本更低。代价是增加了架构和部署的复杂性。

mongodb 通过 分片  支持水平扩展

 

分片集群

mongodb 的分片集群由以下组成:

  • 分片 shard: 每个分片包含总量数据的子集,每个分片可以部署为一个副本set ( replica set).
  • mongos: 作为一个查询路由器, 给分片集群向客户端提供一个借口 .
  • config servers: 存储集群的元数据和配置. MongoDB 3.4, config servers 必须部署为 一个副本set (CSRS).

下图描述了分片集群中不同组件交互:

mongodb 基本原理:分片(Sharding)

MongoDB 在数据集层面将数据分片.

 

分片key 

mongodb 使用  shard key 来将数据集中的文档分到不同的shard中。shard key 由一个或多个字段组成,这些字段在数据集的每份文档都有.

在对数据集分片时要选择shardkey . 分片后,使用的 shard key不能变更  . 一个被分片的数据集只能有一个 shard key. 详见:Shard Key Specification.

对非空数据集分片时,数据集必须有一个以shardkey 开头的索引. 对空的数据集, mongodb 在其还没有合适的索引时会创建索引 . 详见:Shard Key Indexes.

shardkey的选择对性能、效率、扩展性会有影响。即使集群拥有再好的硬件和架构,它的shardkey 也可能成为瓶颈。 shardkey 的选择和它背后的 所以可能也会对 分片策略 sharding strategy  有影响 .

尽管不能修改shardkey用的字段,mongodb 4.2 开始,可以修改文档的shardkey的值,除非shardkey用的是 _id 。

 

数据块 Chunks

mongodb将数据分片为 Chunks。每个Chunk在shardkey上的范围是 [下限, 上限) 

 

负载均衡器(Balancer)与Chunk 平均分布

后台的Balancer 将在不同分片之间搬移 chunk 来保证分片的数据量平衡,详见: Data Partitioning with Chunks

 

分片的好处

读操作/ 写操作

mongodb 将读写请求的负载分散给各 分片。读写的负载都可以通过增加分片数来扩展

对于带shardkey或者复合shardkey前缀的查询,mongos 可以将请求路由到一个或一些分片中,targeted operations 相比 广播broadcasting  要高效的多。

 

存储容量

分片 将数据分散到不同的shard. 数据量增大时,更多的分片可以提高集群的容量.

 

高可用

分片集群中某些shard不可用时,另外的shard 依然可以处理读写请求

mongodb3.2 开始,可以将 config servers  部署为副本set  replica sets,有了CSRS,只要大多数副本set 可用,集群还能继续处理读写请求。

生产环境的shard 要部署为   replica sets,提供冗余和高可用性。

 

分片前的考虑

分片集群的架构和复杂性需要仔细的规划、实施与维护

为保证性能和效率,shardkey的选择要详细考虑。使用后不能修改shardkey,也不能对分片的集群去掉shard特性。详见:Choosing a Shard Key.

分片的限制: operational requirements and restrictions. 详见:Operational Restrictions in Sharded Clusters

若查询不带shardkey 或者复合shardkey的前缀,mongos 则发起广播 broadcast operation, 查询集群中所有shard,会引起慢操作。

 

分片数据集与不分片数据集

一个db可以同时有分片数据集和不分片数据集。分片的数据集分散在不同的shard中。不分片的数据集存在一个主shard中 primary shard. 每个db都有自己的 primary shard.

 

mongodb 基本原理:分片(Sharding)

 

分片集群的连接

要与分片集群中的数据集交互,必须先连上 mongos 路由器 .  分片集群和不分片集群都是。客户端不能直连某个shard 来读写。

mongodb 基本原理:分片(Sharding)

可通过  mongo shell 或者MongoDB driver 连接到 mongos

 

分片策略

mongodb 支持两种分片策略

Hashed 分片

要计算shardkey 对应值的hash值. 每个数据块 chunk 被分配一个hash 后的值的范围 .

当使用被hash的索引查询时,mongodb 字段计算hash值。

mongodb 基本原理:分片(Sharding)

即使某个范围内的shardkey的值接近,hash后的值可能不在同一个 chunk. 这种hash 的分布使得数据分布的更平均,尤其是数据集的数据的shardkey 值单调变化时。

然而,hash的分布意味着 shardkey的范围查询 不太可能路由到同一个shard, 可能路由到更多的集群,类似广播:broadcast operations。更多详见:Hashed Sharding 

 

范围 分片(Ranged Sharding) 

基于shardkey的值将数据分成多个范围,每个  chunk 分配到其中一个范围 

mongodb 基本原理:分片(Sharding)

shardkey 值接近的数据倾向于在同一个chunk,mongos 可以路由到包含所需数据的那些shards。

范围查询的效率依赖于shardkey的选择. 缺陷是数据分布可能不均匀,导致减少了分片的好处,导致性能瓶颈. 详见: shard key selection ; Ranged Sharding 

 

分片集群的Zones

分片集群中, 可以基于shardkey 创建数据的  zones . 可以将每个zone 与一个或多个shard 关联. 一个shard 可以与任意数量的 zone关联. 在一个平衡的集群中 , MongoDB 将一个zone下的 chunks 搬移到与该zone 关联的其他shard.

每个 zone 覆盖一个或多个 shard key 范围。 每个范围下界是闭区间上界是开区间.

mongodb 基本原理:分片(Sharding)

当定义一个新的范围给zone 覆盖时, 必须使用shardkey 包含的字段。 若使用复合shardkey,范围必须包含shardkey的前缀。 详见:shard keys in zones .

当选择shardkey时,要仔细考虑未来 使用zone 来分片的可能性。 

大多数情况下,zone 用于为跨数据中心的集群改进数据本地性 .

详见: zones

 

分片的校对(Collations in Sharding)

使用  shardCollection 命令:collation : { locale : "simple" } 来对数据集分片.

成功的分片要求是:

  • 数据集必须包含某个索引,该索引前缀是shardkey 
  • 该索引必须有 { locale: "simple" }

详见:shardCollection 

 

修改流(Change Streams)

MongoDB 3.6 开始,  应用可以订阅 数据集的修改.

 

事务(Transactions)

详见

 

转自: Sharding