部署Sharding分片

时间:2023-02-02 22:44:30

这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding 的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB 集群。

MongoDB 的数据分块称为 chunk。每个 chunk 都是 Collection 中一段连续的数据记录,通常最大尺寸是 200MB,超出则生成新的数据块。

要构建一个 MongoDB Sharding Cluster,需要三种角色:

  • Shard Server

即存储实际数据的分片,每个Shard 可以是一个mongod 实例,也可以是一组mongod 实例构成的Replica Set。为了实现每个Shard 内部的auto-failover,MongoDB 官方建议每个Shard为一组Replica Set。

  • Config Server

为了将一个特定的collection 存储在多个shard 中,需要为该collection 指定一个shard key,例如{age: 1} ,shard key 可以决定该条记录属于哪个chunk。Config Servers 就是用来存储:所有shard 节点的配置信息、每个chunk 的shard key 范围、chunk 在各shard 的分布情况、该集群中所有DB 和collection 的sharding 配置信息。

  • Route Process

这是一个前端路由,客户端由此接入,然后询问Config Servers 需要到哪个Shard 上查询或保存记录,再连接相应的Shard 进行操作,最后将结果返回给客户端。客户端只需要将原本发给mongod 的查询或更新请求原封不动地发给Routing Process,而不必关心所操作的记录存储在哪个Shard 上。

下面我们在同一台物理机器上构建一个简单的 Sharding Cluster:
架构图如下:

部署Sharding分片

启动Shard Server

部署Sharding分片

启动Config Server

部署Sharding分片

启动Route Process

部署Sharding分片

mongos 启动参数中,chunkSize 这一项是用来指定chunk 的大小的,单位是MB,默认大小为200MB,为了方便测试Sharding 效果,我们把chunkSize 指定为 1MB。

配置Sharding

接下来,我们使用MongoDB Shell 登录到mongos,添加Shard 节点

部署Sharding分片

验证Sharding正常工作

我们已经对test.users 表进行了分片的设置,下面我们们插入一些数据看一下结果

部署Sharding分片

部署Sharding分片

我们看一下磁盘上的物理文件情况

部署Sharding分片

看上述结果,表明test.users 集合已经被分片处理了,但是通过mongos 路由,我们并感觉不到是数据存放在哪个shard 的chunk 上的,这就是MongoDB 用户体验上的一个优势,即对用户是透明的。

管理维护Sharding

列出所有的Shard Server

部署Sharding分片

查看Sharding信息

部署Sharding分片

判断是否是Sharding

部署Sharding分片

对现有的表进行Sharding

刚才我们是对表test.users 进行分片了,下面我们将对库中现有的未分片的表test.users_2 进行分片处理

表最初状态如下,可以看出他没有被分片过:

部署Sharding分片

对其进行分片处理:

部署Sharding分片

再次查看分片后的表的状态,可以看到它已经被我们分片了

新增Shard Server

刚才我们演示的是新增分片表,接下来我们演示如何新增Shard Server

启动一个新Shard Server 进程

部署Sharding分片

配置新Shard Server

部署Sharding分片

查看分片表状态,以验证新Shard Server

部署Sharding分片

我们可以发现,当我们新增Shard Server 后数据自动分布到了新Shard 上,这是由MongoDB
内部自已实现的。

移除Shard Server

有些时候有于硬件资源有限,所以我们不得不进行一些回收工作,下面我们就要将刚刚启用的Shard Server 回收,系统首先会将在这个即将被移除的Shard Server 上的数据先平均分配到其它的Shard Server 上,然后最终在将这个Shard Server 踢下线, 我们需要不停的调用db.runCommand({"removeshard" : "localhost:20002"});来观察这个移除操作进行到哪里了:

部署Sharding分片

部署Sharding分片

最终移除后,当我们再次调用db.runCommand({"removeshard" : "localhost:20002"});的时候系统
会报错,已便通知我们不存在20002 这个端口的Shard Server 了,因为它已经被移除掉了。
接下来我们看一下表中的数据分布:

部署Sharding分片

可以看出数据又被平均分配到了另外2 台Shard Server 上了,对业务没什么特别大的影响。