Mongodb导出与导入
1: 导入/导出可以操作的是本地的mongodb服务器,也可以是远程的.
所以,都有如下通用选项:
-h host 主机
--port port 端口
-u username 用户名
-p passwd 密码
2: mongoexport 导出json格式的文件
问: 导出哪个库,哪张表,哪几列,哪几行?
-d 库名
-c 表名
-f field1,field2...列名
-q 查询条件
-o 导出的文件名
-- csv 导出csv格式(便于和传统数据库交换数据)
例:
[root@localhost mongodb]# ./bin/mongoexport -d test -c news -o test.json connected to: 127.0.0.1 exported 3 records [root@localhost mongodb]# ls bin dump GNU-AGPL-3.0 README test.json THIRD-PARTY-NOTICES [root@localhost mongodb]# more test.json { "_id" : { "$oid" : "51fc59c9fecc28d8316cfc03" }, "title" : "aaaa" } { "_id" : { "$oid" : "51fcaa3c5eed52c903a91837" }, "title" : "today is sataday" } { "_id" : { "$oid" : "51fcaa445eed52c903a91838" }, "title" : "ok now" }
例2: 只导出goods_id,goods_name列
./bin/mongoexport -d test -c goods -f goods_id,goods_name -o goods.json
例3: 只导出价格低于1000元的行
./bin/mongoexport -d test -c goods -f goods_id,goods_name,shop_price -q ‘{shop_price:{$lt:200}}’ -o goods.json
注: _id列总是导出
Mongoimport 导入
-d 待导入的数据库
-c 待导入的表(不存在会自己创建)
--type csv/json(默认)
--file 备份文件路径
例1: 导入json
./bin/mongoimport -d test -c goods --file ./goodsall.json
例2: 导入csv
./bin/mongoimport -d test -c goods --type csv -f goods_id,goods_name --file ./goodsall.csv ./bin/mongoimport -d test -c goods --type csv --headline -f goods_id,goods_name --file ./goodsall.csv
mongodump 导出二进制bson结构的数据及其索引信息
-d 库名
-c 表名
-f field1,field2...列名
例:
mongodum -d test [-c 表名] 默认是导出到mongo下的dump目录
规律:
1:导出的文件放在以database命名的目录下
2: 每个表导出2个文件,分别是bson结构的数据文件, json的索引信息
3: 如果不声明表名, 导出所有的表
mongorestore 导入二进制文件
例:
./bin/mongorestore -d test --directoryperdb dump/test/ (mongodump时的备份目录)
二进制备份,不仅可以备份数据,还可以备份索引,
备份数据比较小.
Mongodb的用户管理
注意:
A)在mongodb中,有一个admin数据库, 牵涉到服务器配置层面的操作,需要先切换到admin数据.
即 use admin , -->相当于进入超级用户管理模式.
B)mongo的用户是以数据库为单位来建立的, 每个数据库有自己的管理员.
C) 我们在设置用户时,需要先在admin数据库下建立管理员---这个管理员登陆后,相当于超级管理员.
1: 查看用户
2: 添加用户
命令:db.addUser();
简单参数: db.addUser(用户名,密码,是否只读)
注意: 添加用户后,我们再次退出并登陆,发现依然可以直接读数据库?
原因: mongodb服务器启动时, 默认不是需要认证的.
要让用户生效, 需要启动服务器时,就指定 --auth 选项.
这样, 操作时,就需要认证了.
例:
1: 添加用户
> use admin > db.addUser(‘sa’,’sa’,false);
2: 认证
> use test > db.auth(用户名,密码);
3: 修改用户密码
> use test > db.changeUserPassword(用户名, 新密码);
3:删除用户
> use test > db.removeUser(用户名);
注: 如果需要给用户添加更多的权限,可以用json结构来传递用户参数
例:
> use test >db.addUser({user:'guan',pwd:'111111',roles:['readWrite,dbAdmin']});
replication set复制集
replicattion set 多台服务器维护相同的数据副本,提高服务器的可用性.
Replication set 设置全过程
0:创建目录
mkdir -p /data/r0 /data/r1 /data/r2
1:启动3个实例,且声明实例属于某复制集
./bin/mongod --port 27017 --dbpath /data/r0 --smallfiles --replSet rsa --fork --logpath /var/log/mongo17.log ./bin/mongod --port 27018 --dbpath /data/r1 --smallfiles --replSet rsa --fork --logpath /var/log/mongo18.log ./bin/mongod --port 27019 --dbpath /data/r2 --smallfiles --replSet rsa --fork --logpath /var/log/mongo19.log
2:配置
rsconf = { _id:'rsa', members: [ {_id:0, host:'192.168.1.201:27017' } ] }
3: 根据配置做初始化
rs.initiate(rsconf);
4: 添加节点
rs.add('192.168.1.201:27018');
rs.add('192.168.1.201:27019');
5:查看状态
rs.status();
6:删除节点
rs.remove('192.168.1.201:27019');
7:主节点插入数据
>use test
>db.user.insert({uid:1,name:'lily'});
8:连接secondary查询同步情况
./bin/mongo --port 27019 >use test >show tables rsa:SECONDARY> show tables; Sat Aug 17 16:03:55.786 JavaScript execution failed: error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
8.1 出现上述错误,是因为slave默认不许读写
>rs.slaveOk(); >show tables
#看到与primary 一致的数据
分片
1:在3台独立服务器上,分别运行 27017,27018,27019实例, 互为副本集,形成3套repl set
2: 在3台服务器上,各配置config server, 运行27020端口上
3: 配置mongos
./bin/mongos --port 30000 \ --dbconfig 192.168.1.201:27020,192.168.1.202:27020,192.168.1.203:27020
4:连接路由器
./bin/mongo --port 30000
5: 添加repl set为片
>sh.addShard(‘192.168.1.201:27017’); >sh.addShard(‘192.168.1.203:27017’); >sh.addShard(‘192.168.1.203:27017’);
6: 添加待分片的库
>sh.enableSharding(databaseName);
7: 添加待分片的表
>sh.shardCollection(‘dbName.collectionName’,{field:1});
Field是collection的一个字段,系统将会利用filed的值,来计算应该分到哪一个片上.
这个filed叫”片键”, shard key
mongodb不是从单篇文档的级别,绝对平均的散落在各个片上
而是N篇文档,形成一个块"chunk",
优先放在某个片上,
当这片上的chunk,比另一个片的chunk,区别比较大时, (>=3) ,会把本片上的chunk,移到另一个片上, 以chunk为单位,
维护片之间的数据均衡
问: 为什么插入了10万条数据,才2个chunk?
答: 说明chunk比较大(默认是64M)
在config数据库中,修改chunksize的值.
问: 既然优先往某个片上插入,当chunk失衡时,再移动chunk,
自然,随着数据的增多,shard的实例之间,有chunk来回移动的现象,这将带来什么问题?
答: 服务器之间IO的增加,
接上问: 能否我定义一个规则, 某N条数据形成1个块,预告分配M个chunk,
M个chunk预告分配在不同片上.
以后的数据直接入各自预分配好的chunk,不再来回移动?
答: 能, 手动预先分片!
以shop.user表为例
1: sh.shardCollection(‘shop.user’,{userid:1}); //user表用userid做shard key
2: for(var i=1;i<=40;i++) { sh.splitAt('shop.user',{userid:i*1000}) } // 预先在1K 2K...40K这样的界限切好chunk(虽然chunk是空的), 这些chunk将会均匀移动到各片上.
3: 通过mongos添加user数据. 数据会添加到预先分配好的chunk上, chunk就不会来回移动了.