mongodb分片

什么叫做分片

Sharding is the process of storing data records across multiple machines and is MongoDB’s approach to meeting the demands of data growth. As the size of the data increases, a single machine may not be sufficient to store the data nor provide an acceptable read and write throughput. Sharding solves the problem with horizontal scaling. With sharding, you add more machines to support data growth and the demands of read and write operations.

mongodb的官方文档上面对分片做了一些简单的说明,基本上可以提炼出这么几个关键字:

  • 多机器存储数据
  • 更高的的读写性能
  • 水平扩展

这这里就不再过多的讨论概念,优缺点等问题,本文定位于快速搭建一个简单完整的分片集群环境。

mongodb 的Shard机制需要这么几个对象:

  • 分片数据服务器
  • 配置服务器
  • 路由服务器

下面开始进行搭建工作。

1. 准备服务器配置

我们的分片测试服务器全部放在本机,结构是这样的:

| 服务器 | port |
| :——:| :——-:|:——-: |
| shard server s0|20001|
| shard server s1|20002|
| config server |30000|
| route server |40000|

因为启动mongod实例需要大量参数,我建议全部写到配置文件里面,然后统一通过-f file.conf参数启动。
我建了一个文件夹/data/mongo-shard/conf,针对每个服务器分别写了一份配置文件:
Alt text
分别来看看:
分片服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 1. 分片服务器 s0.conf
dbpath = /data/mongo-shard/data/shard-s0
port=20000

logpath =/data/mongo-shard/log/s0.log
logappend = true

fork = true
rest = true

shardsvr = true
directoryperdb = true

//2. 分片服务器 s1.conf
dbpath = /data/mongo-shard/data/shard-s1
port=20001

logpath =/data/mongo-shard/log/s1.log
logappend = true

fork = true
rest = true

shardsvr = true
directoryperdb = true

// 3. 配置服务器 config.conf
dbpath = /data/mongo-shard/data/config
port=30000

logpath =/data/mongo-shard/log/config.log
logappend = true

fork = true
rest = true

configsvr = true
directoryperdb = true

// 4. 路由服务器 route.conf
configdb = 127.0.0.1:30000 ##路由监听的配置服务器
port=40000

logpath =/data/mongo-shard/log/route.log
logappend = true

fork = true
chunkSize = 1 ##分片大小为1M

2. 启动服务器

分别将分片服务器,配置服务器,路由服务器一一启动

1
2
3
4
5
6
7
8
9
//分片服务器
mongod -f /data/mongo-shard/conf/s0.conf;
mongod -f /data/mongo-shard/conf/s1.conf

//配置服务器
mongod -f /data/mongo-shard/conf/config.conf;

//路由服务器
mongos -f /data/mongo-shard/conf/route.conf

检查一下是否都正常:
Alt text
启动没有问题,可以进行后续操作了。

3. 进行分片配置

3.1 首先,连接到路由服务器上面的admin库

1
mongo admin -port 40000

3.2 分片配置

执行以下命令

1
2
db.runCommand({addshard:"127.0.0.1:20000"});
db.runCommand({addshard:"127.0.0.1:20001"});

如果一切正常,shell将返回:
Alt text
到此,分片配置已经完成。

3.3 对库表进行分片

分片最终还是要作用在具体的库表上,现在我们对test.user进行分片操作,此时user还不存在。

1
2
3
4
5
// test数据库启用分片
db.runCommand({enablesharding:"test"});

// 对user进行分片,并制定分片的Key为 _id
db.runCommand({shardcollection:"test.user",key:{_id:1}});

此时还看不到任何现象,我们可以往test.user中插入一些数据,看看分片情况。

1
2
3
4
5
6
7
8
9
10
11
use test;

for(var i=0;i<100000;i++){
var sex = i%2;
var age = i / 100 ;
var u = {
"name":"name_"+i,
"sex":sex,"age":age
};
db.user.insert(u);
}

这个过程有些慢,一方面是因为数据来比较大,另一方面是因为插入的同时也在进行分片操作。

执行完毕以后,可以验证分片是否运行了。
首先看看user的当前情况

1
db.user.stats();

Alt text
Alt text

可以看到user确实已经分片了,数据分布在两个分片服务器上面。

刚刚提到user是先分片后插入数据,其实对于已经存在数据的Collection进行分片操作也是一样的效果,只要执行shardcollection命令,mongodb会自动把数据搬移到不同的分片上。

4. 分片的运维

分片的维护工作也是很重要的一部分,现在看看这些常用的命令。

4.1 查看所有分片服务器

db.runCommand({listshards:1});
Alt text

4.2 查看分片信息

printShardingStats();
Alt text

4.3 判断当前连接环境是否是Sharding

db.runCommand({isdbgrid:1});
Alt text

4.4 新增sharding节点

db.runCommand({addshard:”localhost:20003”});

4.5 删除sharding节点

db.runCommand({removeshard:”localhost:20003”});

5 后续

现在的生产环境中是不会使用这么简单的分片架构的,一般是会把分片服务器这部分做成复制集,只要就比较好的保证数据的完整性了。