MongoDB分⽚介绍
分⽚的⽬的 . ⾼数据量和吞吐量的数据库应⽤会对单机的性能造成较⼤压⼒,⼤的查询量会将单机的CPU耗尽,⼤
的数据量对单机的存储压⼒较⼤,最终会耗尽系统的内存⽽将压⼒转移到磁盘IO上。 . 为了解决这些问题,有两个
基本的⽅法: 垂直扩展和⽔平扩展。 垂直扩展:增加更多的CPU和存储资源来扩展容量。 ⽔平扩展:
将数据集分布在多个服务器上。⽔平扩展即分⽚。
分⽚集群的构造
- mongos :数据路由,和客户端打交道的模块。 mongos本身没有任何数据,他也不知道该怎么处理这数据,去找config server
- config server:所有存、取数据的⽅式,所有shard节点的信息,分⽚功能的⼀些配置信息。可以理解为真实数据的元数据。
- shard:真正的数据存储位置,以chunk为单位存数据。 Mongos本身并不持久化数据, Sharded cluster
所有的元数据都会存储到Config Server,⽽⽤户的数据会议分散存储到各个shard。 Mongos启动后,会从配置服务器加载元数据,开始提供服务,将⽤户的请求正确路由到对应的碎⽚。
部署
环境:单台多实例
- configsvr: 使⽤28017、 28018、 28019端⼝
- router : 使⽤27017、 27018、 27019端⼝
- shardsvr :使⽤29017、 29018、 29019、 29020端⼝
configsvr
创建:28017/28018/28019三个文件存放相关配置
MongoDBconf:三个节点端口号不同其余一样
systemLog:
destination: file
logAppend: true
path: /data/mongodb/28017/mongodb.log
storage:
dbPath: /data/mongodb/28017/
journal:
enabled: true
processManagement:
fork: true
pidFilePath: /data/mongodb/28017/mongodb.pid
net:
port: 28017
bindIp: 0.0.0.0
replication: ##副本集
replSetName: testconf
sharding: ##分片角色
clusterRole: configsvr
启动实例
mongo -f 28017/mongodb.conf
mongo -f 28018/mongodb.conf
mongo -f 28019/mongodb.conf
创建分片集群副本集
三个实例分别登录mongo:
mongo --port 28017、mongo --port 28018、mongo --port 28019
#28017
> config ={_id:"testconf",
... 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"}]
... }
{
"_id" : "testconf",
"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)
testconf:PRIMARY> rs.status()
##其余两个实例要声明自己为从
testconf:SECONDARY> rs.slaveOk()
router
mongodb中的router⻆⾊只负责提供⼀个⼊⼝,不存储任何的数据
MongoDBconf:三台实例修改相应端口
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27017/mongodb.log
processManagement:
fork: true
pidFilePath: /data/mongodb/27017/mongodb.pid
net:
port: 27017
bindIp: 0.0.0.0
sharding: ##指定configsvr的地址,使⽤副本集id+ip端⼝
configDB: testconf/127.0.0.1:28017,127.0.0.1:28018,127.0.0.1:28019
启动服务使用mongos命令
mongos -f 27017/mongodb.conf
mongos -f 27018/mongodb.conf
mongos -f 27019/mongodb.conf
#等待数据角色搭建完在进行验证
shardsvr
分⽚集群的数据⻆⾊⾥⾯存储着真正的数据,所以数据⻆⾊⼀定得使⽤副本集多个数据⻆⾊,这里使用4个实例创建两个副本集
##29017与29018修改相应端口
systemLog:
destination: file
logAppend: true
path: /data/mongodb/29017/mongodb.log
storage:
dbPath: /data/mongodb/29017/
journal:
enabled: true
processManagement:
fork: true
pidFilePath: /data/mongodb/29017/mongodb.pid
timeZoneInfo: /usr/share/zoneinfo
net:
port: 29017
bindIp: 0.0.0.0
replication:
replSetName: testdata1 ##第一个副本集id
sharding:
clusterRole: shardsvr
##29019与29020修改相应端口
systemLog:
destination: file
logAppend: true
path: /data/mongodb/29019/mongodb.log
storage:
dbPath: /data/mongodb/29019/
journal:
enabled: true
processManagement:
fork: true
pidFilePath: /data/mongodb/29019/mongodb.pid
timeZoneInfo: /usr/share/zoneinfo
net:
port: 29019
bindIp: 0.0.0.0
replication:
replSetName: testdata2 ##第二个副本集id
sharding:
clusterRole: shardsvr
启动4个实例:
mongod -f /data/mongodb/29017/mongodb.conf
mongod -f /data/mongodb/29018/mongodb.conf
mongod -f /data/mongodb/29019/mongodb.conf
mongod -f /data/mongodb/29020/mongodb.conf
分别登陆到mongo配置副本集
##29017
> config={_id:"testdata1",members:[{_id:0,host:"127.0.0.1:29017"},
... {_id:1,host:"127.0.0.1:29018"}]}
{
"_id" : "testdata1",
"members" : [
{
"_id" : 0,
"host" : "127.0.0.1:29017"
},
{
"_id" : 1,
"host" : "127.0.0.1:29018"
}
]
}
> rs.initiate(config)
testdata1:PRIMARY>
##29018
testdata1:SECONDARY> rs.slaveOk()
##29019
> config={_id:"testdata2",members:[{_id:0,host:"127.0.0.1:29019"},
... {_id:1,host:"127.0.0.1:29020"}]}
{
"_id" : "testdata2",
"members" : [
{
"_id" : 0,
"host" : "127.0.0.1:29019"
},
{
"_id" : 1,
"host" : "127.0.0.1:29020"
}
]
}
> rs.initiate(config)
testdata2:PRIMARY>
##29020
testdata2:SECONDARY> rs.slaveOk()
验证分片集群
router角色
##mongo --port 27017
##加入副本集test1、test2
mongos> sh.addShard("testdata1/127.0.0.1:29017,127.0.0.1:29018")
mongos> sh.addShard("testdata2/127.0.0.1:29019,127.0.0.1:29020")
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5ea175a084ec9d97d8d522e8")
}
shards:
{ "_id" : "testdata1", "host" : "testdata1/127.0.0.1:29017,127.0.0.1:29018", "state" : 1 }
{ "_id" : "testdata2", "host" : "testdata2/127.0.0.1:29019,127.0.0.1:29020", "state" : 1 }
active mongoses:
"4.2.3" : 3
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
此时添加数据是没有分片效果的,需要在路由角色上操作开启分片的数据库
mongos> use admin
switched to db admin
mongos> db.runCommand({enablesharding:"mytest"})
{
"ok" : 1,
"operationTime" : Timestamp(1587647184, 5),
"$clusterTime" : {
"clusterTime" : Timestamp(1587647184, 5),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
##指定集合以哈希方式进行分片
mongos> db.runCommand({shardcollection:"mytest.test1",key:{_id:"hashed"}})
{
"collectionsharded" : "mytest.test1",
"collectionUUID" : UUID("4562c0d5-2f19-42aa-8c58-3a1bad158e0e"),
"ok" : 1,
"operationTime" : Timestamp(1587647298, 28),
"$clusterTime" : {
"clusterTime" : Timestamp(1587647298, 28),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
插入数据验证
mongos> use mytest
switched to db mytest
mongos> for (i=1;i<=1000;i++){db.test1.insert({name:"mytest1",age:i})}
WriteResult({ "nInserted" : 1 })
mongos> db.test1.find().count()
1000
此时查看shardsvr角色是否分片成功
##29017
testdata1:PRIMARY> use mytest
switched to db mytest
testdata1:PRIMARY> db.test1.find().count()
498
##29019
testdata2:PRIMARY> use mytest
switched to db mytest
testdata2:PRIMARY> db.test1.find().count()
502
验证router挂掉一台后是否有影响。
##27017
mongos> use admin
switched to db admin
mongos> db.shutdownServer()
##27018
mongo --port 27018
mongos> show dbs
admin 0.000GB
config 0.002GB
mytest 0.000GB
##路由没有配置副本集挂掉了也没有影响,在启动一台配置一样就可,路由并不存放数据。