1、基础概念
mongodb分片介绍
-
一般用得比较少,需要较多的服务器,还有三种的角色
-
一般把mongodb的副本集应用得好就足够用了,可搭建多套mongodb复本集
为什么要用mongodb分片技术?
-
mongodb副本集可以解决数据备份、读性能的问题,但由于mongodb副本集是每份数据都一模一样的,无法解决数据量过大问题
-
mongodb分片技术能够把数据分成两份存储,假如shijiange.myuser里面有1亿条数据,分片能够实现5千万左右存储在data1,5千万左右存储在data2
-
data1、data2需要使用副本集的形式,预防数据丢失
mongodb分片集群三种角色介绍
-
router角色,mongodb的路由,提供入口,使得分片集群对外透明。router不存储数据,类似LVS或nginx代理。
-
configsvr角色 ,mongodb的配置角色,存储元数据信息。分片集群后端有多份存储,读取数据该去哪个存储上读取,依赖于配置角色。配置角色建议使用副本集,因为如果这个角色丢了,就相当于书的目录丢了,找起来非常的麻烦。
-
shardsvr角色 ,mongodb的存储角色,存储真正的数据,建议使用副本集
依赖关系
当用户通过router角色插入数据时,需要从configsvr知道这份数据插入到哪个节点,然后执行插入动作插入数据到sharedsvr
当用户通过router角色获取数据时,需要从configsvr知道这份数据是存储在哪个节点,然后再去sharedsvr获取数据
mongodb分片集群的搭建说明
-
使用同一份mongodb二进制文件
-
修改对应的配置就能实现分片集群的搭建
mongodb分片集群实战环境搭建说明
configsvr #使用28017,28018,28019三个端口来搭建
router #使用27017,27018,27019三个端口来搭建
shardsvr #使用29017,29018,29019,29020四个端口来搭建,两个端口一个集群,生产环境肯定是要三个端口
2、configsvr角色
mongodb配置角色的搭建,配置文件路径/data/mongodb/28017/mongodb.conf
//三个实例:28017,28018,28019
systemLog:
destination: file
logAppend: true
path: /data/mongodb/28017/mongodb.log
storage:
dbPath: /data/mongodb/28017/
journal:
enabled: true
processManagement:
fork: true
net:
port: 28017
bindIp: 127.0.0.1
replication:
replSetName: zhanghe #明确副本集的名字
sharding:
clusterRole: configsvr #明确角色
mongodb配置服务集群的启动跟单例的启动方式一致,都是使用mongod
分片集群的配置角色副本集搭建
config = { _id:"zhanghe",
configsvr: true,
members:[
{_id:0,host:"127.0.0.1:28017"},
{_id:1,host:"127.0.0.1:28018"},
{_id:2,host:"127.0.0.1:28019"}
]
}
rs.initiate(config)
验证是否搭建成功
/usr/local/mongodb/bin/mongo 127.0.0.1:28017
rs.status()
3、router角色
router说明:
mongodb中的router角色只负责提供一个入口,不存储任何的数据
//router角色的搭建,配置文件/data/mongodb/27017/mongodb.conf,27017,27018,两个实例即可
//没有存储项,因为不存储数据
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27017/mongodb.log
processManagement:
fork: true
net:
port: 27017
bindIp: 127.0.0.1
sharding:
configDB: zhanghe/127.0.0.1:28017,127.0.0.1:28018,127.0.0.1:28019
//router的启动,用mongos启动,而不是mongod
/usr/local/mongodb/bin/mongos -f /data/mongodb/27017/mongodb.conf
/usr/local/mongodb/bin/mongos -f /data/mongodb/27018/mongodb.conf
router最重要的配置
-
指定configsvr的地址,使用副本集id+ip端口的方式指定
-
配置多个router,任何一个都能正常的获取数据
router的验证:
需要等到数据角色搭建完才能够进行验证
4、sharedsvr角色
数据角色
分片集群的数据角色里面存储着真正的数据,所以数据角色一定得使用副本集,而且一定要有多个副本集,一个副本集存储一部分数据,另一个副本集存储另一部分数据,并不把所有的数据都存储在一个副本集上,这样的话,读取的速度会加快,这才是分片集群本来的意义。
数据服务两个集群说明
29017、29018数据角色zhanghe1
29019、29020数据角色zhanghe2
//mongodb的数据角色搭建,配置文件/data/mongodb/29017/mongodb.conf
//29017,29018,29019,29020,两两为一组
systemLog:
destination: file
logAppend: true
path: /data/mongodb/29017/mongodb.log
storage:
dbPath: /data/mongodb/29017/
journal:
enabled: true
processManagement:
fork: true
net:
port: 29017
bindIp: 127.0.0.1
replication:
replSetName: zhanghe1
sharding:
clusterRole: shardsvr
//启动四个数据实例
/usr/local/mongodb/bin/mongod -f /data/mongodb/29017/mongodb.conf
/usr/local/mongodb/bin/mongod -f /data/mongodb/29018/mongodb.conf
/usr/local/mongodb/bin/mongod -f /data/mongodb/29019/mongodb.conf
/usr/local/mongodb/bin/mongod -f /data/mongodb/29020/mongodb.conf
//数据角色zhanghe1
config = { _id:"zhanghe1",
members:[
{_id:0,host:"127.0.0.1:29017"},
{_id:1,host:"127.0.0.1:29018"}
]
}
rs.initiate(config)
//数据角色zhanghe2
config = { _id:"zhanghe2",
members:[
{_id:0,host:"127.0.0.1:29019"},
{_id:1,host:"127.0.0.1:29020"}
]
}
rs.initiate(config)
真实的生产环境当中使用情况:
zhanghe1至少要占用三台服务器,zhanghe2至少要占用三台服务器,而配置角色最好也要三台服务器,router角色无所谓可以复用一下,也就是说真实的生产环境至少也得需要9台服务器来搭建分片集群。
5、分片集群的使用
//将两个分片集群连接到路由角色里面配置,addshard的意思是增加数据
/usr/local/mongodb/bin/mongo 127.0.0.1:27017
mongos>sh.addShard("zhanghe1/127.0.0.1:29017,127.0.0.1:29018")
mongos>sh.addShard("zhanghe2/127.0.0.1:29019,127.0.0.1:29020")
mongos>sh.status()
shards:
{ "_id" : "zhanghe1", "host" : "zhanghe1/127.0.0.1:29017,127.0.0.1:29018", "state" : 1 }
{ "_id" : "zhanghe2", "host" : "zhanghe2/127.0.0.1:29019,127.0.0.1:29020", "state" : 1 }
默认添加数据都没有分片存储,mongs会随便指一个数据集群,如下操作是在路由角色里面
mongos> sh.status()
databases:
chunks:
zhanghe1 1
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : zhanghe1 Timestamp(1, 0)
{ "_id" : "zhang", "primary" : "zhanghe1", "partitioned" : false, "version" : { "uuid" : UUID("b10f7a10-464c-44ee-894e-43473a81c189"), "lastMod" : 1 } }
//插入一些数据,这些数据只会存储到zhanghe1里面,zhanghe2是没有的,sh.status()内容所示
use zhang
for(i=1; i<=500;i++){
db.myuser.insert( {name:'mytest'+i, age:i} )
}
db.dropDatabase() #验证完后删除
针对某个数据库的某个表使用hash分片存储,分片存储就会同一个colloection(表)分配两个数据角色
use admin
db.runCommand( { enablesharding :"zhang"}); #zhang是库名
db.runCommand( { shardcollection : "zhang.myuser",key : {_id: "hashed"} } ) #myuser是表名,id是表中的字段,这表名把myuser表中的id字段进行分片存储
//查看一下,partitioned(分片)已经开启,一部分数据分布在zhanghe1,一部分数据分布在zhanghe2
mongos> sh.status()
{ "_id" : "zhang", "primary" : "zhanghe2", "partitioned" : true, "version" : { "uuid" : UUID("31c4271d-7b80-41f2-8a96-97ff6b7f6e79"), "lastMod" : 1 } }
zhanghe1 2
zhanghe2 2
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : NumberLong("-4611686018427387902") } on : zhanghe1 Timestamp(2, 2)
{ "_id" : NumberLong("-4611686018427387902") } -->> { "_id" : NumberLong(0) } on : zhanghe1 Timestamp(2, 3)
{ "_id" : NumberLong(0) } -->> { "_id" : NumberLong("4611686018427387902") } on : zhanghe2 Timestamp(2, 4)
{ "_id" : NumberLong("4611686018427387902") } -->> { "_id" : { "$maxKey" : 1 } } on : zhanghe2 Timestamp(2, 5)
插入数据校验,分布在两个数据角色上
use zhang
for(i=1; i<=500;i++){
db.myuser.insert( {name:'mytest'+i, age:i} )
}
效果如下所示:
//在router上查看是500条正好
mongos> db.myuser.count()
500
左边为数据集群:zhanghe1,右边数据集群是zhanghe2:
两边的数量也不一样。
如果配置集群坏了一台,并不是会影响router的任何使用,还有两台备用,但是如果数据集群坏了一台的话,就会影响router的使用,因为我们的数据集群单个集群只有两个实例,这样不行,如果单台集群有三个实例,那就没问题了,我们在生产环境上单个集群肯定要使用三个实例的。
我们有两个路由入口,在哪一个操作都是可以的。