?MongoDB Sharding

1.MongoDB Sharding 简介

分片(Sharding)是一种跨多台服务器分发数据的方法。 MongoDB使用分片技术来支持具有非常大的数据集和高吞吐量操作的部署。

单台服务器所能提供的资源和容量很难满足具有大型数据集或高吞吐量应用程序的需求, 例如,高查询率会耗尽服务器的CPU容量。数据集的大小大于系统的RAM会过度使用磁盘驱动器的I / O容量。

一般来讲,解决系统性能增长的方法有两种:垂直扩展和水平扩展

垂直扩展涉及增加单个服务器的容量,例如使用更强大的CPU,添加更多RAM或增加存储空间量。单台服务器的容量和资源扩展到一定程度就会有瓶颈, 此外,基于云的提供商提供的可用的硬件配置具有上限。

 水平扩展涉及划分数据集并加载多个服务器,添加其他服务器以根据需要增加容量。虽然单个服务器的总体速度或容量可能不高,但每台机器处理整个工作负载的子集,可能提供比单个高速大容量服务器具有更高的效率。

MongoDB支持通过分片 (Sharding) 进行水平扩展。 

2. 分片集群 (Sharding Cluster)

MongoDB分片集群包含以下组件:

分片(Shard):每个分片包含分片数据的子集。 每个分片都可以部署为副本集 (Replica Set)。

Mongos:mongos充当查询路由器,提供客户端应用程序和分片集群之间的接口。

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

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

1542290741944473.png

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

Mongos本身并不持久化数据,Sharded cluster所有的元数据都会存储到Config Server,而用户的数据则会分散存储到各个shard。Mongos启动后,会从config server加载元数据,开始提供服务,将用户的请求正确路由到对应的Shard。

3. Shard Keys

为了在集合中分发文档,MongoDB使用Shard Key对集合进行分区。 Shard Key由目标集合中每个文档中存在的不可变字段组成的。

在对集合进行分片时,选择合适的Shard Key 十分重要。 分片后无法更改Shard Key的选择。 分片集合只能有一个Shard Key。 

Shard Key的选择会影响分片集群的性能,效率和可伸缩性。 具有好的硬件和基础结构的集群可能会因选择Shard Key而碰到性能瓶颈。 选择分片键及其支持索引也会影响群集可以使用的分片策略。

4. Chunk

MongoDB将分片数据划分为Chunk。 每个块都具有基于Shard Key的一个范围。 MongoDB使用分片集群平衡器来进行跨分片集群中的分片迁移块。 平衡器尝试会尝试在集群中的所有分片上实现块的均衡平衡。MongoDB 默认的 chunk size 为64MB,如果 chunk 超过64MB 并且不能分解(比如所有文档 的 shard key 都相同),则会被标记为jumbo chunk ,balancer 不会迁移这样的 chunk,从而可能导致负载不均衡,这样的情况应该尽量避免。

MongoDB平衡器是一个后台进程,用于监视每个分片上的Chunk数量。 当给定分片上的Chunk数量达到特定迁移阈值时,平衡器会尝试在分片之间自动迁移Chunk,并在每个分片中达到相同数量的Chunk。分片群集的平衡过程对用户和应用程序层完全透明的,但在执行过程时可能会对性能产生一些影响。

1542290815172070.png

5. 分片的优点

读/写

MongoDB在分片集群中的分片之间分配读写负载,允许每个分片处理集群操作的部分请求。 通过添加更多分片,可以在集群中水平扩展读取和写入时的工作负载。

对于包含Shard Key的查询,mongos可以在特定分片或分片集上定位查询,这些特定的操作要比向群集中的每个分片都请求数据更加有效。

存储容量

分片在集群中的分片之间分配数据,允许每个分片包含总集群数据的一部分。 随着数据集的增长,额外的分片会增加群集的存储容量。

高可用性

即使一个或多个分片不可用,分片集群也可以继续执行部分读/写操作。 虽然在停机期间无法访问不可用分片上的数据集,但是针对可用分片的读取或写入仍然是可以的。在生产环境中,应将各个分片部署为副本集 (Replica Set),从而提供更高的冗余和可用性。

6.Sharded和Non-Sharded Collections

MongoDB数据库可以同时使用分片和未分片的集合。 分片集合在集群中的分片上进行分区和分布。 没有分片的集合存储在主分片 (Primary Shard)上。 每个数据库都有自己的主分片。

1542290895209836.png

连接到分片集群

必须连接到mongos路由器才能与分片群集中的任何集合进行交互。 这包括分片和未分片的集合。 客户端不会连接到单个分片以执行读取或写入操作。如下图所示:

1542290930459060.png

7. 分片策略

MongoDB支持两种分片策略,用于跨分片群集分发数据。

HASH 分片

HASH分片涉及计算Shard Key字段值的Hash 值。 然后,基于散列的分片键值为每个Chunk分配一个范围。

1542290972510636.png

虽然一系列的Shard Key可能很接近,但它们的Hash Value不太可能在同一Chunk上。 基于散列值的数据分布有助于更均匀的数据分布,尤其是在Shard Key变化不大的数据集中。但是,散列分布意味着对Shard Key的基于范围的查询不太可能以单个分片为目标,从而导致更多群集范围的查询请求。

Shard Key范围分片

范围分片涉及到基于分片键值将数据划分为范围,然后根据分片键值为每个Chunk分配一个范围。

1542291011759488.png

Shard Key值很接近的可能驻留在同一Chunk上, 这样的优点是允许有针对性的操作对于该Chunk,因为mongos可以将操作需求仅路由到包含所需数据的分片。范围分片的效率取决于所选的分片键。 考虑不好的分片键可能导致数据分布不均匀,可能会抵消分片的某些好处,或者可能导致性能瓶颈。 如shard key 某个值的文档特别多,这样导致单个 chunk 特别大(及 jumbo chunk),会影响chunk 迁移及负载均衡。

一个好的Shard Key 的选择应该遵循下列原则

Shard key 分布足够离散;

写请求均匀分布在各个分片上;

尽量避免 scatter-gather 查询,最好定位到特定分片请求上。

?MongoDB Sharding

发表评论

邮箱地址不会被公开。 必填项已用*标注

10 × 一 =

滚动到顶部