MongoDB分片
- 分片就是将数据库进行拆分,将大型集合分隔到不同服务器上。比如,本来100G的数据,可以分割成10份存储到10台服务器上,这样每台机器只有10G的数据。
- 通过一个mongos的进程(路由)实现分片后的数据存储与访问,也就是说mongos是整个分片架构的核心,对客户端而言是不知道是否有分片的,客户端只需要把读写操作转达给mongons即可。
- 虽然分片会把数据分隔到很多台服务器上,但是每一个节点都是需要有一备用角色的,这样能保证数据的高可用。
- 当系统需要更多空间或者资源的时候,分片可以让我们按需方便扩展,只需要把mongodb服务的机器加入到分片集群中即可。
- mongos:数据库集群请求的入口,所有的请求都通过mongos进程协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。
- config server:配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从config server加载配置信息,以后如果配置服务器信息变化会通知到所有的mongos更新自己的状态,这样mongos就能继续准确路由。在生产环境通常有多个config server配置服务器,因为它存储了分片路由的元数据,防止数据丢失
- shard:存储了一个集合部分的MongoDB实例,每个分片是单独的mongodb服务或者副本集,在生产环境中,所有的分片都应该是副本集。
MongoDB分片搭建
- 使用三台机器,安装mongodb-org,开启mongod服务 http://blog.51cto.com/13480443/2085721
A机器:192.168.221.10,config server(SECONDARY) ,shard1(PRIMARY),shard2(ARBITER),shard3(SECONDARY)
B机器:192.168.221.20 ,config server(SECONDARY),shard1(SECONDARY),shard2(PRIMARY),shard3(ARBITER)
C机器:192.168.221.50 ,config server(PRIMARY),shard1(ARBITER),shard2(SECONDARY),shard3(PRIMARY)
端口分配:mongos 20000、config server 21000、shard1 27001、shard2 27002、shard3 27003
- 三台机器上创建目录
mkdir -p /data/mongodb/{{config,shard1,shard2,shard3}/{data,log},mongos/log}
- 三台机器上搭建config server,开启服务,创建副本集ifconfigs
mkdir /etc/mongodb/
vim /etc/mongodb/config.conf
bpath = /data/mongodb/config/data
logpath = /data/mongodb/config/log/configsrv.log
logappend = true
bind_ip = 0.0.0.0 # 绑定你的监听ip
port = 21000
fork = true
configsvr = true #declare this is a config db of a cluster;
replSet=configs #副本集名称
maxConns=20000 #设置最大连接数
mongod -f /etc/mongodb/config.conf
mongo --host 192.168.221.50 --port 21000
> config = { _id: "configs", members: [ {_id : 0, host : "192.168.221.10:21000"},{_id : 1, host : "192.168.221.20:21000"},{_id : 2, host : "192.168.221.50:21000"}] }
> rs.initiate(config)
> rs.status();
"name" : "192.168.221.10:21000",
"stateStr" : "SECONDARY",
..................................
"name" : "192.168.221.20:21000",
"stateStr" : "SECONDARY",
...................................
"name" : "192.168.221.50:21000",
"stateStr" : "PRIMARY",
......................................
- 三台机器上创建分片
shard1的配置
//三台机器都执行这样的操作
vim /etc/mongodb/shard1.conf
pidfilepath = /var/run/mongodb/shard1.pid
dbpath = /data/mongodb/shard1/data
logpath = /data/mongodb/shard1/log/shard1.log
logappend = true
bind_ip = 192.168.221.10 //各自绑定自己的ip
port = 27001
fork = true
replSet=shard1
shardsvr = true
maxConns=20000
mongod -f /etc/mongodb/shard1.conf
mongo --port 27001 --host 192.168.221.10
> config = {_id:"shard1",members:[{_id:0,host:"192.168.221.10:27001"},{_id:1,host:"192.168.221.20:27001"},{_id:2,host:"192.168.221.50:27001",arbiterOnly:true}]}
> rs.initiate(config)
以上实现了A机器 shard1(PRIMARY),B机器 shard1(SECONDARY),C机器 shard1(ARBITER)
shard2的配置
vim /etc/mongodb/shard2.conf
pidfilepath = /var/run/mongodb/shard2.pid
dbpath = /data/mongodb/shard2/data
logpath = /data/mongodb/shard2/log/shard2.log
logappend = true
bind_ip = 192.168.221.10
port = 27002
fork = true
replSet=shard2
shardsvr = true
maxConns=20000
mongod -f /etc/mongodb/shard2.conf
mongo --port 27002 --host 192.168.221.20
> config = { _id: "shard2", members: [ {_id : 0, host : "192.168.221.10:27002",arbiterOnly:true},{_id : 1, host : "192.168.221.20:27002"},{_id : 2, host : "192.168.221.50:27002"}] }
> rs.initiate(config)
以上实现了A机器shard2(ARBITER),B机器shard2(PRIMARY),C机器shard2(SECONDARY)
shard3的配置
vim /etc/mongodb/shard3.conf
pidfilepath = /var/run/mongodb/shard3.pid
dbpath = /data/mongodb/shard3/data
logpath = /data/mongodb/shard3/log/shard3.log
logappend = true
bind_ip = 192.168.221.50
port = 27003
fork = true
replSet=shard3
shardsvr = true
maxConns=20000
mongod -f /etc/mongodb/shard3.conf
mongo --port 27003 --host 192.168.221.50
> config={_id:"shard3",members:[{_id:0,host:"192.168.221.10:27003"},{_id:1,host:"192.168.221.20:27003",arbiterOnly:true},{_id:2,host:"192.168.221.50:27003"}]}
> rs.initiate(config)
以上实现了A机器shard3(SECONDARY),B机器shard3(ARBITER),C机器shard3(PRIMARY) 注意:ARBITER是不能初始化副本集的,即执行>rs.initate(config)会报错
- 配置路由服务器(三台机都这样操作)
vim /etc/mongodb/mongos.conf
pidfilepath = /var/run/mongodb/mongos.pid
logpath = /data/mongodb/mongos/log/mongos.log
logappend = true
bind_ip = 192.168.221.20 # 绑定你的监听ip
port = 20000
fork = true
configdb = configs/192.168.221.10:21000, 192.168.221.20:21000, 192.168.221.50:21000
maxConns=20000
mongos -f /etc/mongodb/mongos.conf
登录任意一台机器的20000端口,把所有分片和路由串联起来
mongo --port 20000 --host 192.168.221.10
mongos> sh.addShard("shard1/192.168.221.10:27001,192.168.221.20:27001,192.168.221.50:27001")
mongos> sh.addShard("shard2/192.168.221.10:27002,192.168.221.20:27002,192.168.221.50:27002")
mongos> sh.addShard("shard3/192.168.221.10:27003,192.168.221.20:27003,192.168.221.50:27003")
mongos> sh.status()
- 分片测试
连接mongondb的20000端口,进入admin库,指定要分片的数据库
mongo --port 20000 --host 192.168.221.20
mongos> sh.enableSharding("testdb");
指定数据库里要分片的集合和片键
mongos> sh.shardCollection("testdb.table1",{id:1})
进入testdb库,插入数据
mongos> use testdb
mongos> for(var i=1;i<=10000;i++) db.table1.save({id:i,test1:"testval1"})
查看状态
mongos> db.table1.stats();
mongos> use admin
mongos> db.runCommand(enableSharding:"testdb1")
mongos> db.runCommand({shardcollection:"testdb1.table1",key:{id:1}})
mongos> for(var i=1;i<=10000;i++) db.table1.save({id:i,test1:"val1"})
mongos> sh.status();
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5aa8c1d7712eaf789b641e15")
}
shards:
{ "_id" : "shard1", "host" : "shard1/192.168.221.10:27001,192.168.221.20:27001", "state" : 1 }
{ "_id" : "shard2", "host" : "shard2/192.168.221.20:27002,192.168.221.50:27002", "state" : 1 }
{ "_id" : "shard3", "host" : "shard3/192.168.221.10:27003,192.168.221.50:27003", "state" : 1 }
active mongoses:
"3.6.3" : 2
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 }
config.system.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks:
shard1 1
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0)
{ "_id" : "testdb", "primary" : "shard2", "partitioned" : true }
testdb.table1
shard key: { "id" : 1 }
unique: false
balancing: true
chunks:
shard2 1
{ "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard2 Timestamp(1, 0)
{ "_id" : "testdb1", "primary" : "shard1", "partitioned" : true }
testdb1.table1
shard key: { "id" : 1 }
unique: false
balancing: true
chunks:
shard1 1
{ "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0)
mongodb的备份与恢复
备份指定库,所有库,指定库中的集合
mongodump --port 20000 --host 192.168.221.50 -d testdb -o /tmp/testdb //会在指定目录下生成与库名一样的目录
mongodump --port 20000 --host 192.168.221.50 -o /tmp/alldb
mongodump --port 20000 --host 192.168.221.50 -d testdb -c table1 -o /tmp/table //此目录下会生成一个testdb目录
将集合导出为一个json格式的文件
mongoexport --port 20000 --host 192.168.221.50 -d testdb -c table1 -o /tmp/table1.json
备份所有数据库(除config,admin库),恢复(除config,admin库)所有库
mongodump --port 20000 --host 192.168.221.50 -o /tmp/allDB
mongo --port 20000 --host 192.168.221.50
mongos> use db1;
mongos> db.dropDatabase();
mongos> use testdb1;
mongos> db.dropDatabase();
mongos> show dbs;
admin 0.000GB
config 0.001GB
mongos>
bye
rm -rf allDB/config/ allDB/admin/
mongorestore --port 20000 --host 192.168.221.50 --drop /tmp/allDB/
恢复指定库
mongorestore --port 20000 --host 192.168.221.50 -d apengdb --drop /tmp/allDB/db1/ //将db1库恢复到apengdb库(不需要创建)
恢复某个集合中的数据
mongoexport --port 20000 --host 192.168.221.50 -d db1 -c table1 -o /tmp/table1.json
mongo --port 20000 --host 192.168.221.50
mongos> use db1;
mongos> db.table1.drop();
mongoimport --port 20000 --host 192.168.221.50 -d db1 -c table1 --file=/tmp/table1.json