
一、介绍
二、架构
三、集群配置
四、添加分片
五、Collection启用分片
六、Balance
七、那些坑

一、介绍
sharding是指将一个collection根据一定的规则拆分,分散存储到多台服务器中,每台服务器只存储一个collection中的一部分数据。数据集分布式负载存储,可以减少单台服务器的存储压力、充分利用各个片的资源,提高整个数据库的系能。一个collection被分成多个chunk(数据块),每个chunk包含多个document。
二、架构
mongos:请求路由,mongos隐藏分片细节,客户端不需要知道collection分布式存储在哪些片里。mongos根据config配置知道数据和片的对应关系,接收客户端发来的请求,把请求自动转分到对应的片上,然后汇集每个片的响应数据,最后把汇集结果返回给客户端
config servers:配置服务器存储分片元数据、集群配置:collection的数据块、每个数据块包含的document范围、每个数据块存储在哪个分片上等
shard:每个分片只包含分片collection的一部分数据。shard可以是单个mongodb也可以是一个复制集(replica),建议用复制集,提高分片的稳定性

三、集群配置
为了简化操作,分片有三个mongodb:est1、test2、test3,生产建议每个分片都是用复制集)、一个路由mongos(test1)、一个配置服务(test1,3.4以上的版本必须使用复制集作为配置服务)
1、shard:
test1、test2、test3创建同样的mongodb.conf配置文件:

然后在test1、test2、test3服务器上启动mongodb:
mongod -f mongodb.conf
2、config servers:
test1服务器创建mongodbconf.conf配置文件:

启动config server:
mongod -f mongodbconf.conf
3、mongos:
test1服务器上启动mongos:

configdb:指定配置服务器
port:mongos端口
fork:mongos后台运行
logpath:mongos日志文件
四、添加分片
1、访问monogs:mongo test1:27037
2、增加三个数据库分片实例:
use admin;
db.runCommand({addShard: "test1:27017"});
db.runCommand({addShard: "test2:27017"});
db.runCommand({addShard: "test3:27017"});
或者下面命令:
sh.addShard("test3:27017");
3、验证shard是否加到集群:
方法一、sh.status()命令的输出结果可以看到
方法二、配置数据库里查看:use config;db.shards.find()
五、Collection启用分片
1、对数据库启用分片
use admin;
db.runCommand( { enablesharding :"test_db"});
2、创建索引,分片的片键有索引后才能分片
user test_db;
db.cl_test1.ensureIndex({"uid":1});
查看创建的索引:db.cl_test1.getIndexes()
3、对collection进行分片
sh.shardCollection("test_db.cl_test1", {"uid" : 1})
或者下面的命令:
use admin;
db.runCommand({shardcollection:"test_db.cl_test1",key:{"uid":1}})
4、验证分片
方法一:sh.status();输出结果能看到数据是分布在哪些分片上。
或者直接查询chunks:

六、Balance
Balance是Mongo的负载均衡工具,负责拆分、合并、移动Chunks,保证分片集合的chunks负载均衡存储在整个集群中;Balance是一个后台进程,监控每一个shard中的块数量,当一个分片里的chunks文件超过了阀值,就会自动在集群内移动chunks,以到达每个分片中的chunks数据量相等。默认的块是64M。
块的拆分是为了避免块增长太快,当块达到了块的大小或者达到了块中最大文档数;MongoDB根据片键的值拆分块,一个快可能拆分成多个块。
七、那些坑
1、热点问题:如果片键选择不适当,分片后的数据可能会较集中,查询请求也会集中在一些特定chunks,会导致整个集群出现瓶颈。假设根据uid分片,如果一个用户有很多行为数据,当查询这个用户时,会引起单台shard热点问题,解决方法是可以根据多个键hash作为片键,如day+uid;Hash分片会把数据均匀分布
2、如果块太大,balance就不能再拆分、移动chunk:块中的文档数超过250000个或者块的大小超过了集合平均文档大小的1.3倍。这样会导致负载不均衡,需要选择好片键
3、balance执行时会影响集群工作效率,建议设定在请求量小的时间段内执行




