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