上节咱们遗留了两个问题还没解决:
- 从节点每个上面的数据都是对数据库全部拷贝,从节点压力会不会过大?
- 数据压力大到机器支撑不了的时候是否会自动扩展
在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会出现一台机器硬件瓶颈问题的。而mongodb主打的就是海量数据架构,“分片”就用这个来解决这个问题。
分片,是将一个逻辑数据拆分到不同的服务器。每个拆分的数据都是独立的,
分片好处:
1分片使得集群中每个切片操作数据量减少,同时集群的操作能力增加也提高了吞吐量
2分片减少了每个服务器需要存储的数据量。随着集群的的增长每个分片存储更少的数据
如何分片
Mongodb支持通过配置文件做分片集群
我们通过一张图可以看出
分片集群由三部分组成:Router(mongos)config Server, shard (Replica Sets,副本集)
Shard: 这就是分片了,存储数据,用于提供高可用性和一致性。
Mongos:路由服务器,数据库集群的入口,所有请求通过mongos进行协调,不需要在应用程序中添加一个路由选择,mongos自己便是一个请求分发中心,负责把对象请求转发到对应的分片服务器上。
ConfigServer :顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos就能继续准确路由。在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,这个可不能丢失!就算挂掉其中一台,只要还有存货,mongodb集群就不会挂掉。
实战
1 首先准备3各mongodb数据库,分别作为配置服务器,分片1和分片2,都存储在一个机器上,对应端口不同
2 规划端口,配置服务器 2000,路由服务器 1000,分片A 8091,分片B 8092,
3 各个服务器的配置信息
3.1 首先是创建配置服务器
configuration.conf
dbpath =J:\java\mongopointcut\conf\database
port =2000
bind_ip=127.0.0.1
Configuration.bat
mongod --configconfiguration.conf
3.2创建路由器服务器,并连接配置服务器,路由器是调用mongos命令
mongos --port 1000--configdb 127.0.0.1:2000
connectonMongos.bat
mongo127.0.0.1:1000/admin
3.3创建分片服务器配置
shardA.conf
dbpath=J:\java\mongopointcut\pointcut2\database
port=8092
bind_ip=127.0.0.1
connictShartA.bat
mongod --config shardA.conf
loginShartA.bat
mongo127.0.0.1:8091/admin
ShartB.conf
dbpath=J:\java\mongopointcut\pointcut2\database
port=8092
bind_ip=127.0.0.1
mongod--config ShartB.conf
4登录服务器
4.1 首先登录配置服务器,在登录路由服务器。在启动各个分片服务器
在路由器服务器中添加分片服务器。但是mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。
db.runCommand({addshard:"127.0.0.1:8091",allowLocal:true})
db.runCommand({addshard:"127.0.0.1:8092",allowLocal:true})
这里要注意的是,在addshard中,我们也可以添加副本集,这样能达到更高的稳定性
4.2片已经集群了,但是mongos不知道如何切分数据
开启数据库分片功能,命令很简单 enablesharding(),这里我就开启foobar数据库。
指定集合中分片的片键,这里我就指定为bar.id字段,也就是片键,在mogondb中设置片键
通过查看配置服务器,可以看到
5查看效果
我们添加90万条的数据
function add(){
vari=0;
for(;i<200000;i++){
db.bar.insert({"age":i+10,"name":"jim"})
}
}
通过printshardingSttus查看分片情况
mongos> showcollections
bar
person
system.indexes
mongos>db.bar.stats()
{
"sharded" : true,
"systemFlags" : 1,
"userFlags" : 1,
"ns" :"foobar.bar",
"count" :931672, //总计条数
"numExtents" : 19,
"size" : 104347264,
"storageSize" : 144752640,
"totalIndexSize" : 36334144,
"indexSizes" : {
"_id_" : 36334144
},
"avgObjSize" : 112,
"nindexes" : 1,
"nchunks" : 7,
"shards" : {
"shard0000" : {
"ns" :"foobar.bar",
"count" : 352282, //分片1
"size" :39455584,
"avgObjSize": 112,
"storageSize": 58441728,
"userFlags" : 1,
"totalIndexSize" : 13441344,
"indexSizes": {
"_id_" : 13441344
},
"ok" : 1
},
"shard0001" : {
"ns" :"foobar.bar",
"count" : 579390, //分片2
"size" :64891680,
"avgObjSize": 112,
"totalIndexSize" : 22892800,
"indexSizes": {
"_id_" : 22892800
},
"ok" : 1
}
},
"ok" : 1
}
可以看到数据分到俩个分片中,shard1352282,shard2 579390,总数931672,已经成功。
小结:
通过分片的测试我们认识到分片存储减少了数据库的拷贝,同时增加了集群的吞吐量,同时分片也是副本集的一种增强,它是在副本集的基础上进行改善的。