MongoDB Sharding Cluster分片集群

- 10个实例: 端口号为38017-38026
- configserver:3台构成的复制集(1主两从,不支持arbiter)38018-38020(复制集名字configsvr)
- sh1:38021-23(1主两从,其中一个节点为arbiter,复制集名字sh1)
- sh2:38024-26(1主两从,其中一个节点为arbiter,复制集名字sh2)
配置过程
- 以下操作均在
mangod
用户操作,无需修改目录权限
目录创建
| |
| mkdir -p /mongodb/38021/conf /mongodb/38021/log /mongodb/38021/data |
| mkdir -p /mongodb/38022/conf /mongodb/38022/log /mongodb/38022/data |
| mkdir -p /mongodb/38023/conf /mongodb/38023/log /mongodb/38023/data |
| mkdir -p /mongodb/38024/conf /mongodb/38024/log /mongodb/38024/data |
| mkdir -p /mongodb/38025/conf /mongodb/38025/log /mongodb/38025/data |
| mkdir -p /mongodb/38026/conf /mongodb/38026/log /mongodb/38026/data |
修改配置文件
| |
| cat > /mongodb/38021/conf/mongodb.conf<<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/38021/log/mongodb.log |
| logAppend: true |
| storage: |
| journal: |
| enabled: true |
| dbPath: /mongodb/38021/data |
| directoryPerDB: true |
| |
| wiredTiger: |
| engineConfig: |
| cacheSizeGB: 1 |
| directoryForIndexes: true |
| collectionConfig: |
| blockCompressor: zlib |
| indexConfig: |
| prefixCompression: true |
| net: |
| bindIp: 10.0.0.51,127.0.0.1 |
| port: 38021 |
| replication: |
| oplogSizeMB: 2048 |
| replSetName: sh1 |
| sharding: |
| clusterRole: shardsvr |
| processManagement: |
| fork: true |
| EOF |
| cp /mongodb/38021/conf/mongodb.conf /mongodb/38022/conf/ |
| cp /mongodb/38021/conf/mongodb.conf /mongodb/38023/conf/ |
| sed 's#38021#38022#g' /mongodb/38022/conf/mongodb.conf -i |
| sed 's#38021#38023#g' /mongodb/38023/conf/mongodb.conf -i |
| |
| #sh2 |
| cat > /mongodb/38024/conf/mongodb.conf<<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/38024/log/mongodb.log |
| logAppend: true |
| storage: |
| journal: |
| enabled: true |
| dbPath: /mongodb/38024/data |
| directoryPerDB: true |
| wiredTiger: |
| engineConfig: |
| cacheSizeGB: 1 |
| directoryForIndexes: true |
| collectionConfig: |
| blockCompressor: zlib |
| indexConfig: |
| prefixCompression: true |
| net: |
| bindIp: 10.0.0.51,127.0.0.1 |
| port: 38024 |
| replication: |
| oplogSizeMB: 2048 |
| replSetName: sh2 |
| sharding: |
| clusterRole: shardsvr |
| processManagement: |
| fork: true |
| EOF |
| |
| cp /mongodb/38024/conf/mongodb.conf /mongodb/38025/conf/ |
| cp /mongodb/38024/conf/mongodb.conf /mongodb/38026/conf/ |
| sed 's#38024#38025#g' /mongodb/38025/conf/mongodb.conf -i |
| sed 's#38024#38026#g' /mongodb/38026/conf/mongodb.conf -i |
启动所有节点
| mongod -f /mongodb/38021/conf/mongodb.conf |
| mongod -f /mongodb/38022/conf/mongodb.conf |
| mongod -f /mongodb/38023/conf/mongodb.conf |
| mongod -f /mongodb/38024/conf/mongodb.conf |
| mongod -f /mongodb/38025/conf/mongodb.conf |
| mongod -f /mongodb/38026/conf/mongodb.conf |
搭建复制集
| mongo --port 38021 admin |
| |
| config = {_id: 'sh1', members: [ |
| {_id: 0, host: '10.0.0.51:38021'}, |
| {_id: 1, host: '10.0.0.51:38022'}, |
| {_id: 2, host: '10.0.0.51:38023',"arbiterOnly":true}] |
| } |
| rs.initiate(config) |
| mongo --port 38024 admin |
| |
| config = {_id: 'sh2', members: [ |
| {_id: 0, host: '10.0.0.51:38024'}, |
| {_id: 1, host: '10.0.0.51:38025'}, |
| {_id: 2, host: '10.0.0.51:38026',"arbiterOnly":true}] |
| } |
| rs.initiate(config) |
config节点
创建目录
| mkdir -p /mongodb/38018/conf /mongodb/38018/log /mongodb/38018/data |
| mkdir -p /mongodb/38019/conf /mongodb/38019/log /mongodb/38019/data |
| mkdir -p /mongodb/38020/conf /mongodb/38020/log /mongodb/38020/data |
修改配置文件
| cat > /mongodb/38018/conf/mongodb.conf <<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/38018/log/mongodb.conf |
| logAppend: true |
| storage: |
| journal: |
| enabled: true |
| dbPath: /mongodb/38018/data |
| directoryPerDB: true |
| |
| wiredTiger: |
| engineConfig: |
| cacheSizeGB: 1 |
| directoryForIndexes: true |
| collectionConfig: |
| blockCompressor: zlib |
| indexConfig: |
| prefixCompression: true |
| net: |
| bindIp: 10.0.0.51,127.0.0.1 |
| port: 38018 |
| replication: |
| oplogSizeMB: 2048 |
| replSetName: configReplSet |
| sharding: |
| clusterRole: configsvr |
| processManagement: |
| fork: true |
| EOF |
| |
| cp /mongodb/38018/conf/mongodb.conf /mongodb/38019/conf/ |
| cp /mongodb/38018/conf/mongodb.conf /mongodb/38020/conf/ |
| sed 's#38018#38019#g' /mongodb/38019/conf/mongodb.conf -i |
| sed 's#38018#38020#g' /mongodb/38020/conf/mongodb.conf -i |
启动所有节点
| mongod -f /mongodb/38018/conf/mongodb.conf |
| mongod -f /mongodb/38019/conf/mongodb.conf |
| mongod -f /mongodb/38020/conf/mongodb.conf |
搭建复制集
- configserver可以是一个节点,官方建议复制集.configserver不能有arbiter
- 新版本中,要求必须是复制集.mongodb3.4之后,虽然要求config server为replica set,但是不支持arbiter
| mongo --port 38018 admin |
| |
| config = {_id: 'configReplSet', members: [ |
| {_id: 0, host: '10.0.0.51:38018'}, |
| {_id: 1, host: '10.0.0.51:38019'}, |
| {_id: 2, host: '10.0.0.51:38020'}] |
| } |
| rs.initiate(config) |
mongos节点
创建目录
mkdir -p /mongodb/38017/conf /mongodb/38017/log
修改配置文件
| cat >/mongodb/38017/conf/mongos.conf<<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/38017/log/mongos.log |
| logAppend: true |
| net: |
| bindIp: 10.0.0.51,127.0.0.1 |
| port: 38017 |
| sharding: |
| configDB: configReplSet/10.0.0.51:38018,10.0.0.51:38019,10.0.0.51:38020 |
| processManagement: |
| fork: true |
| EOF |
启动mongos
mongos -f /mongodb/38017/conf/mongos.conf
分片集群
| |
| mongo 10.0.0.51:38017/admin |
| |
| db.runCommand( { addshard : "sh1/10.0.0.51:38021,10.0.0.51:38022,10.0.0.51:38023",name:"shard1"} ) |
| db.runCommand( { addshard : "sh2/10.0.0.51:38024,10.0.0.51:38025,10.0.0.51:38026",name:"shard2"} ) |
| |
| |
| sh.status() |
| db.runCommand( { listshards : 1 } ) |
使用分片集群
RANGE分片配置测试
| #登录 |
| mongo --port 38017 admin |
| |
| #激活数据库分片功能 |
| db.runCommand( { enablesharding : "test" } ) |
| -- 创建索引 |
| use test |
| db.vast.ensureIndex( { id: 1 } ) |
| |
| -- 开启分片 |
| use admin |
| db.runCommand( { shardcollection : "test.vast",key : {id: 1} } ) |
| |
| -- 集合分片验证 |
| use test |
| for(i=1;i<1000000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); } |
| db.vast.stats() |
| |
| -- 分片结果测试 |
| -- 当数据量达到一定的量时(默认64MB),会将一半的数据迁移到另一个节点 |
| -- shard1 |
| mongo --port 38021 |
| db.vast.count(); |
| |
| -- shard2: |
| mongo --port 38024 |
| db.vast.count(); |
Hash分片配置测试
| #登录 |
| mongo --port 38017 admin |
| |
| #激活数据库分片功能 |
| db.runCommand( { enablesharding : "test2" } ) |
| -- 创建索引 |
| use test2 |
| db.vast.ensureIndex( { id: "hashed" } ) |
| |
| -- 开启分片 |
| use admin |
| sh.shardCollection( "test2.vast", { id: "hashed" } ) |
| |
| -- 集合分片验证 |
| use test2 |
| for(i=1;i<100000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); } |
| |
| -- 分片结果测试 |
| -- 当数据量录入时,会平均分配到各个节点 |
| -- shard1 |
| mongo --port 38021 |
| use test2 |
| db.vast.count(); |
| |
| -- shard2 |
| mongo --port 38024 |
| use test2 |
| db.vast.count(); |
管理性操作
- db.runCommand({ isdbgrid : 1}) : 当前库下,判断是否Shard集群
- db.runCommand({ listshards : 1}) :
use admin
,列出所有分片信息
- db.databases.find( { "partitioned": true } ) :
use config
,列出开启分片的数据库
- db.databases.find() :
use config
,列出开启分片的数据库
- db.collections.find().pretty() :
use config
,查看分片的片键
- db.printShardingStatus() : 查看分片的详细信息
- sh.status() : 查看分片的详细信息
- sh.getBalancerState() : 确认blance是否在工作
- db.runCommand( { removeShard: "shard2" } ) : 删除shard2节点(谨慎操作,删除操作一定会立即触发blancer,发生数据迁移)
balancer操作
mongos的一个重要功能,自动巡查所有shard节点上的chunk的情况,自动做chunk迁移
- 自动运行,会检测系统不繁忙的时候做迁移
- 在做节点删除的时候,立即开始迁移工作
- balancer只能在预设定的时间窗口内运行
- 有需要时可以关闭和开启blancer(备份的时候)
| -- 开启blancer |
| sh.stopBalancer() |
| -- 关闭blancer |
| sh.startBalancer() |
自定义 自动平衡进行的时间段
| |
| mongo |
| |
| use config |
| |
| sh.setBalancerState( true ) |
| |
| db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "3:00", stop : "5:00" } } }, true ) |
| |
| |
| sh.getBalancerWindow() |
| sh.status() |
关于集合的balancer
- sh.disableBalancing("students.grades") : 关闭某个集合的balancer
- sh.enableBalancing("students.grades") : 打开某个集合的balancer
备份恢复
- mongoexport/mongoimport : 导入/导出的是JSON格式或者CSV格式,用于异构平台迁移(mysql <--> mongodb),同平台跨大版本(mongodb2 -> mongodb3)
- mongodump/mongorestore : 导入/导出的是BSON格式,用于日常备份恢复时使用
JSON可读性强但体积较大,BSON则是二进制文件,体积小但对人类几乎没有可读性.在一些mongodb版本之间,BSON格式可能会随版本不同而有所不同,所以不同版本之间用mongodump/mongorestore可能不会成功,具体要看版本之间的兼容性.当无法使用BSON进行跨版本的数据迁移的时候,使用JSON格式即mongoexport/mongoimport是一个可选项.跨版本的mongodump/mongorestore个人并不推荐,实在要做请先检查文档看两个版本是否兼容(大部分时候是的)JSON虽然具有较好的跨版本通用性,但其只保留了数据部分,不保留索引,账户等其他基础信息,使用时应该注意
导出工具mongoexport
Mongodb中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件.可以通过参数指定导出的数据项,也可以根据指定的条件导出数据
- mongoexport --help : 查看帮助
- -h : 指明数据库宿主机的IP
- -u : 指明数据库的用户名
- -p : 指明数据库的密码
- -d : 指明数据库的名字
- -c : 指明collection的名字
- -f : 指明要导出列
- -o : 指明到导出的文件名
- -q : 指明导出数据的过滤条件
- --authenticationDatabase admin : 验证库信息
单表备份
| |
| |
| mongoexport -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -c log -o /mongodb/log.json |
| |
| |
| |
| mongoexport -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -c log --type=csv -f uid,name,age,date -o /mongodb/log.csv |
导入工具mongoimport
Mongodb中的mongoimport工具可以把一个特定格式文件中的内容导入到指定的collection中.该工具可以导入JSON格式数据,也可以导入CSV格式数据.具体使用如下所示
- mongoimport --help : 查看帮助
- -h : 指明数据库宿主机的IP
- -u : 指明数据库的用户名
- -p : 指明数据库的密码
- -d : 指明数据库的名字
- -c : 指明collection的名字
- -f : 指明要导入列
- --headerline : 指明第一行是列名,不需要导入
- -j : 要运行的插入操作数(并发操作,提升效率,默认为1)
- --numInsertionWorkers= : 要运行的插入操作数(并发操作,提升效率,默认为1)
单表恢复
| |
| mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -c log1 /mongodb/log.json |
| |
| #如果要导入CSV格式文件中的内容,则需要通过--type参数指定导入格式 |
| |
| mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -c log2 --type=csv --headerline --file /mongodb/log.csv |
| |
| #恢复csv格式的文件到log3 |
| mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -c log3 --type=csv -f id,name,age,date --file /mongodb/log1.csv |
异构平台迁移案例
mysql数据库下city表进行导出,导入到mongodb
| |
| vi /etc/my.cnf |
| |
| secure-file-priv=/tmp |
select * from world.city into outfile '/tmp/city.csv' fields terminated by ',';
| |
| vim /tmp/city.csv |
| |
| ID,Name,CountryCode,District,Population |
mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d world -c city --type=csv --headerline --file /tmp/city1.csv
mysql多表大量迁移
| |
| select * from world.city into outfile '/tmp/world_city.csv' fields terminated by ','; |
| |
| |
| |
| select concat("select * from ",table_schema,".",table_name ," into outfile '/tmp/",table_schema,"_",table_name,".csv' fields terminated by ',';") from information_schema.tables where table_schema ='world'; |
mysql导出csv
| select * from test_info |
| into outfile '/tmp/test.csv' |
| fields terminated by ',' |
| optionally enclosed by '"' |
| escaped by '"' |
| lines terminated by '\r\n'; |
mysql导入csv
| load data infile '/tmp/test.csv' |
| into table test_info |
| fields terminated by ',' |
| optionally enclosed by '"' |
| escaped by '"' |
| lines terminated by '\r\n'; |
导出工具mongodump和导入工具mongorestore
mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘.但是存在的问题时使用mongodump产生的备份不一定是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和Mongodb实时数据相等.另外在备份时可能会对其它客户端性能产生不利的影响
- mongodump --help : 查看帮助
- -h : 指明数据库宿主机的IP
- -u : 指明数据库的用户名
- -p : 指明数据库的密码
- -d : 指明数据库的名字
- -c : 指明collection的名字
- -o : 指明到要导出的文件名
- -q : 指明导出数据的过滤条件
- -j : 要并行转储的集合数(并发操作,提升效率,默认为4)
- --numParallelCollections= : 要并行转储的集合数(并发操作,提升效率,默认为4)
- --oplog : 备份的同时备份oplog
| |
| mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -o /mongodb/backup |
| |
| #备份world库 |
| mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -d world -o /mongodb/backup/ |
| |
| #备份1997sty库下的log集合 |
| mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -c log -o /mongodb/backup/ |
| |
| #压缩备份 |
| mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -o /mongodb/backup/ --gzip |
| mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -o /mongodb/backup/ --gzip |
| mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -c log -o /mongodb/backup/ --gzip |
导入工具mongorestore应用
| |
| mongorestore -uroot -p123456 --port 27017 --authenticationDatabase admin -d world /mongodb/backup/world |
| |
| #恢复1997sty库下的t1集合 |
| mongorestore -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty -c t1 /mongodb/backup/1997sty/log.bson |
| |
| # --drop表示恢复的时候把之前的集合drop掉(危险) |
| mongorestore -uroot -p123456 --port 27017 --authenticationDatabase admin -d 1997sty --drop /mongodb/backup/1997sty |
mongodump和mongorestore高级企业应用(--oplog)
- --oplog : 使用oplog拍摄时间点快照
- 这是replica set或者master/slave模式专用
- 在replica set中oplog是一个定容集合(capped collection),它的默认大小是磁盘空间的5%(可以通过--oplogSizeMB参数修改)
- 位于local库的db.oplog.rs,有兴趣可以看看里面到底有些什么内容
- 其中记录的是整个mongod实例一段时间内数据库的所有变更(插入/更新/删除)操作
- 当空间用完时新记录自动覆盖最老的记录
- 其覆盖范围被称作oplog时间窗口.需要注意的是,因为oplog是一个定容集合,所以时间窗口能覆盖的范围会因为你单位时间内的更新次数不同而变化
- 想要查看当前的oplog时间窗口预计值,可以使用
rs.printReplicationInfo()
命令
| |
| use local |
| db.oplog.rs.find().pretty() |
| |
| |
| |
| |
| |
| |
| |
| |
| test:PRIMARY> rs.printReplicationInfo() |
| configured oplog size: 2048MB < |
| log length start to end: 281479secs (78.19hrs) < |
| oplog first event time: Mon May 04 2020 12:45:30 GMT+0800 (CST) |
| oplog last event time: Thu May 07 2020 18:56:49 GMT+0800 (CST) |
| now: Thu May 07 2020 18:56:51 GMT+0800 (CST) |
oplog企业级应用
oplog 配合mongodump实现热备
| |
| mongodump --port 28017 --oplog -o /mongodb/backup |
| |
| #恢复 |
| mongorestore --port 28017 --oplogReplay /mongodb/backup |
故障恢复模拟
- 停应用
- 找测试库
- 恢复昨天晚上全备
- 截取全备之后找到误删除时间点的oplog,并恢复到测试库
- 将误删除表导出,恢复到生产库
模拟数据
| #登录数据库 |
| mongo --port 28017 admin |
| |
| -- 进入sty1997库,生成测试数据 |
| |
| use sty1997 |
| for(var i = 1 ;i < 20; i++) { |
| db.t1.insert({a: i}); |
| } |
对数据进行全量备份
| |
| |
| |
| mongodump --port 28017 --oplog -o /mongodb/backup |
添加增量数据
| for(var i = 21 ;i < 40; i++) { |
| db.t1.insert({a: i}); |
| } |
删除t1表
找到误操作时间点
| use local |
| db.oplog.rs.find({op:"c"}).pretty() |
| { |
| "ts" : Timestamp(1588852870, 2), |
| "t" : NumberLong(1), |
| "h" : NumberLong("5637878556167102522"), |
| "v" : 2, |
| "op" : "c", |
| "ns" : "sty1997.$cmd", |
| "ui" : UUID("4973c701-f243-41ac-a3a1-3239f9b774c7"), |
| "wall" : ISODate("2020-05-07T12:01:10.683Z"), |
| "o" : { |
| "drop" : "t1" |
| } |
| } |
备份现有的oplog.rs表
mongodump --port 28017 -d local -c oplog.rs -o /mongodb/backup
处理oplog.bson文件
| |
| cp /mongodb/backup/local/oplog.rs.bson /mongodb/backup/oplog.bson |
| |
| rm -rf /mongodb/backup/local/ |
恢复数据
mongorestore --port 28017 --oplogReplay --oplogLimit "1588852870:2" --drop /mongodb/backup/
分片集群的备份思路
你要备份什么
备份有什么困难和问题
- chunk迁移的问题,人为控制在备份的时候,避开迁移的时间窗口
- shard节点之间的数据不在同一时间点,选业务量较少的时候,可以在备份时将从节点移除,备份完成后再加入,保证数据一致性
0 条评论