数据备份、数据恢复:
常用导出方法
[root@localhostbin]# ./mongoexport -d my_mongodb -c user -o user.dat
参数说明:
-d指明使用的库,“my_mongodb”
-c指明要导出的表,“user”
-o指明要导出的文件名,“user.dat”
导出的方式使用的是JSON的样式
导出CSV格式的文件
[root@localhostbin]#./mongoexport -d my_mongodb -c user --csv
-fuid,username,age -o user_csv.dat
参数说明:
-csv指要要导出为csv格式
-f指明需要导出哪些例
更详细的用法可以mongoexport–help 查看
导入JSON数据
[root@localhostbin]# ./mongoimport -d my_mongodb -c user user.dat
导入cvs
[root@localhostbin]#./mongoimport -d my_mongodb -c user --type csv --headerline
--fileuser_csv.dat
参数说明:
-type 指明要导入的文件格式
-headerline表明不导入第一行,因为第一行是列名
-file指明要导入的文件路径
注意:CSV格式良好,主流数据库都支持导出为CSV的格式,所以这种格式非常利于异构数据迁移。
数据备份命令mongodump:
例:备份my_mongodb数据库
[root@localhostbin]# ./mongodump -d my_mongodb
此时会在当前目录下默认创建一个dump目录,用于存放备份出来的文件,也可以指定备份存放的目录,后面加上-o my_mongodb_dump
数据恢复命令mongorestore
如需验证可先删除my_mongodb库,或指明–drop参数,就可以在恢复的时候先删除然后再向插入数据。
[root@localhostbin]# ./mongorestore -d my_mongodb my_mongodb_dump/*
建立系统root用户
在admin库中新添一个用户root:
>use admin
>db.addUser("root","111")
>db.auth("root","111")
1
数据库管理员只能管理本数据库
超级管理员可以进入其他数据库反之不行
启动时指定--auth参数
建立只读权限用户
monogDB也支持为某个特定的数据库来设置用户,如我们为test库设一个只读的用户user_reader
>db.addUser("user_reader", "user_pwd", true)
/usr/local/mongodb/bin/mongo -u yunduan localhost:27017/admin -p
MongoDB的主从集群分为两种:
Master-Slave复制(主从)
只需要在某一个服务启动时加上--master参数,而另一个服务加上--slave与--source参数,即可实现同步。MongoDB的最新版本已经不推荐使用这种方法了。
ReplicaSets 复制(副本集)
MongoDB在1.6版本开发了replicaset,主要增加了故障自动切换和自动修复成员节点,各个DB之间数据完全一致,最为显著的区别在于,副本集没有固定的主节点,它是整个集群选举出得一个主节点,当其不工作时变更其他节点强烈推荐使用。
故障转移
副本集比传统的Master-Slave有改进的地方就是它可以进行故障的自动转移,如果我们停掉复制集中的一个成员,那么剩余成员会再自动选举出一个成员,做为主库。
部署ReplicaSets
启动两个实例:
1)、创建数据文件存储路径
[root@localhost~]# mkdir -p /data/data/r0
[root@localhost~]# mkdir -p /data/data/r1
2)、创建日志文件路径
[root@localhost~]# mkdir -p /data/log
3)、创建主从key文件用于标识集群的私钥的完整路径,如果各个实例的keyfile内容不一致,程序将不能正常用。
[root@localhost~]# mkdir -p /data/key
[root@localhost~]# echo "this is rs1 super secret key" > /data/key/r0
[root@localhost~]# echo "this is rs1 super secret key" > /data/key/r1
[root@localhost~]# chmod 600 /data/key/r*
4)、启动2个实例
./mongod--replSet rs1 --keyFile /data/key/r0 --fork --port 28010 --dbpath/data/data/r0 --logpath=/data/log/r0.log --logappend
./mongod--replSet rs1 --keyFile /data/key/r1 --fork --port 28011 --dbpath/data/data/r1 --logpath=/data/log/r1.log –logappend
--replSetrs1副本集的名字
5)、配置及初始化ReplicaSets
[root@localhostbin]# ./mongo -port 28010 --成员IP及端口,priority=1指PRIMARY
config_rs1= {
_id:'rs1',
members:[
{_id:0, host: 'localhost:28010', priority:1},
{_id:1, host: 'localhost:28011',priority:2}//priority 数字越大优先级越高
]
}
>rs.initiate(config_rs1); --初始化配置
{
"info": "Config now saved locally. Should come online in about aminute.",
"ok": 1
}
6)、查看复制集状态
>rs.status()
{
"set": "rs1",
"date": ISODate("2012-05-31T09:49:57Z"),
"myState": 1,
"members": [
{
"_id": 0,
"name": "localhost:28010",
"health": 1, --1表明正常;0表明异常
"state": 1, -- 1表明是Primary;2 表明是Secondary;
"stateStr": "PRIMARY", --表明此机器是主库
"optime": {
"t": 1338457763000,
"i": 1
},
"optimeDate": ISODate("2012-05-31T09:49:23Z"),
"self": true
}
主从操作日志oplog
MongoDB的ReplicaSet 架构是通过一个日志来存储写操作的,这个日志就叫做”oplog”。
oplog.rs是一个固定长度的cappedcollection,它存在于”local”数据库中,用于记录ReplicaSets操作日志。
oplog的大小是可以通过mongod的参数”--oplogSize”来改变oplog的日志大小
rs1:PRIMARY>show collections
oplog.rs
system.replset
rs1:PRIMARY>db.oplog.rs.find()
{"ts" : { "t" : 1338457763000, "i" : 1}, "h" : NumberLong(0), "op" : "n","ns" : "", "o" : { "msg":"initiating set" } }
Oplog内容样例:
字段说明
ts:某个操作的时间戳
op:操作类型,如下:
i:insert d: delete u: update
ns:命名空间,也就是操作的collectionname
o:document的内容
查看master的oplog元数据信息:
rs1:PRIMARY>db.printReplicationInfo()
configuredoplog size: 47.6837158203125MB
loglength start to end: 1351secs (0.38hrs)
oplogfirst event time: Thu May 31 2012 17:49:23 GMT+0800 (CST)
oploglast event time: Thu May 31 2012 18:11:54 GMT+0800 (CST)
now:Thu May 31 2012 18:21:58 GMT+0800 (CST)
字段说明:
configuredoplog size: 配置的oplog文件大小
loglength start to end: oplog日志的启用时间段
oplogfirst event time: 产生时间oploglast
eventtime: 最后一个事务日志的产生时间
now:现在的时间
查看slave的同步状态
字段说明:
rs1:PRIMARY>db.printSlaveReplicationInfo()
source:localhost:28011
syncedTo:Thu May 31 2012 18:11:54 GMT+0800 (CST)= 884secs ago (0.25hrs)
source:从库的IP及端口
syncedTo:目前的同步情况,延迟了多久等信息
主从配置信息
在local库中不仅有主从日志oplog集合还有一个集合用于记录主从配置信息system.replset
rs1:PRIMARY>use local
switchedto db local
rs1:PRIMARY>show collections
oplog.rs
system.replset
rs1:PRIMARY>db.system.replset.find()
从这个集合中可以看出,ReplicaSets的配置信息,也可以在任何一个成员实例上执行rs.conf()来查看配置信息
管理维护ReplicaSets
读写分离、
从库要是进行查询,分担主库的大量的查询请求
1)、先向主库中插入一条测试数据
2)、在从库进行查询等操作,当查询时报错了,说明是个从库且不能执行查询的操作
3)、让从库可以读,分担主库的压力
执行db.getMongo().setSlaveOk(),我们就可查询从库了
Sharding分片
这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB集群。
MongoDB的数据分块称为chunk。每个chunk都是Collection中一段连续的数据记录,通常最大尺寸是200MB,超出则生成新的数据块
要构建一个MongoDBSharding Cluster,需要三种角色:
ShardServer
即存储实际数据的分片,每个Shard可以是一个mongod实例,也可以是一组mongod实例构成的ReplicaSet。
ConfigServer
为了将一个特定的collection存储在多个shard中,需要为该collection指定一个shardkey。
RouteProcess
这是一个前端路由,客户端由此接入,然后询问ConfigServers 需要到哪个Shard上查询或保存记录,再连接相应的Shard进行操作,最后将结果返回给客户端
1) 启动Shard Server:
mkdir -p /data/shard/s0 --创建数据目录
mkdir -p /data/shard/s1
mkdir -p /data/shard/log --创建日志目录
/Apps/mongo/bin/mongod --shardsvr --port 20000 --dbpath /data/shard/s0 --fork
–logpath /data/shard/log/s0.log --directoryperdb --启动Shard Server实例1
/Apps/mongo/bin/mongod --shardsvr --port 20001 --dbpath /data/shard/s1 --fork
--logpath /data/shard/log/s1.log --directoryperdb --启动Shard Server实例2
2) 启动Config Server:
mkdir -p /data/shard/config --创建数据目录
/Apps/mongo/bin/mongod --configsvr --port 30000
--dbpath /data/shard/config --fork --logpath /data/shard/log/config.log
--directoryperdb --启动Config Server实例
3)启动RouteProcess:
/Apps/mongo/bin/mongos--port 40000
--configdblocalhost:30000 --fork –logpath /data/shard/log/route.log
--chunkSize1 --启动RouteServer 实例
mongos启动参数中,chunkSize这一项是用来指定chunk的大小的,单位是MB,默认大小为200MB,为了方便测试Sharding效果,我们把chunkSize指定为1MB。
4)配置Sharding
接下来,我们使用MongoDBShell登录到mongos,添加Shard节点
[root@localhost~]# /Apps/mongo/bin/mongo admin --port 40000 --此操作需要连接admin库
>db.runCommand({ addshard:"localhost:20000" }) --添加ShardServer
{"shardAdded" : "shard0000", "ok" : 1 }
>db.runCommand({ addshard:"localhost:20001" })
{"shardAdded" : "shard0001", "ok" : 1 }
>db.runCommand({ enablesharding:"test" }) --设置分片存储的数据库
{"ok" : 1 }
>db.runCommand({ shardcollection: "test.users", key: { _id:1}}) --设置分片的集合名称,且必须指定ShardKey,系统会自动创建索引
{"collectionsharded" : "test.users", "ok": 1 }
5)验证Sharding正常工作
我们已经对test.users表进行了分片设置,我们插入一些数据看下结果
>use test
switchedto db test
>for (var i = 1; i <= 500000; i++)
db.users.insert({"name":"caida","age":24,"addr":"Beijing"})
>db.users.stats()
{
"sharded": true, --说明此表已被shard
…
"shard0000": { --在此分片实例上约有24.5M数据
"ns": "test.users",
"count": 254889,
"size": 24469344,
"avgObjSize": 96,
…
"shard0001": { --在此分片实例上约有23.5M数据
"ns": "test.users",
"count": 245111,
"size": 23530656,
6)我们看一下磁盘上的物理文件情况
[root@localhostbin]# ll /data/shard/s0/test --此分片实例上有数据产生
总计262420
-rw-------1 root root 16777216 06-03 15:21 test.0
-rw-------1 root root 33554432 06-03 15:21 test.1
-rw-------1 root root 67108864 06-03 15:22 test.2
-rw-------1 root root 134217728 06-03 15:24 test.3
-rw-------1 root root 16777216 06-03 15:21 test.ns
[root@localhostbin]# ll /data/shard/s1/test --此分片实例上有数据产生
-rw-------1 root root 16777216 06-03 15:21 test.0
-rw-------1 root root 33554432 06-03 15:21 test.1
-rw-------1 root root 67108864 06-03 15:22 test.2
-rw-------1 root root 134217728 06-03 15:23 test.3
-rw-------1 root root 16777216 06-03 15:21 test.ns
看上述结果,表明test.users集合已经被分片处理了,但是通过mongos路由,我们并感觉不到是数据存放在哪个shard的chunk上的,这就是MongoDB用户体验上的一个优势,即对用户是透明的