Mongo replica set方案可以在多台机器同步数据, 如果PRIMARY机器挂掉, 其他SECONDARY机器可以选出一台新的PRIMARY, 流量可以切换到新机器, 从而实现高可用.

1. 先备份数据

1
2
# MONGO_DOCKER 替换为真正运行的docker
docker exec -it MONGO_DOCKER mongodump --db db_store --username nolan --password 'PASSWORD' --authenticationDatabase admin

备份数据在docker里 /data/dump, 拷到主机某个目录, 后面恢复数据会用到

2. 创建数据文件夹

1
2
3
4
cd /nfs_data
mkdir mongo_9690
mkdir mongo_9692
mkdir mongo_9694

3. 生成keyfile

1
2
3
4
5
6
cd /nfs_data
openssl rand -base64 756 > keyfile
chmod 400 keyfile
cp keyfile mongo_9690
cp keyfile mongo_9692
cp keyfile mongo_9694

4. 先启动不带keyfile的docker

1
2
3
4
5
6
7
# 集群名字是rs1, 后面也要用到, 注意保持一致
# AI02
docker run -p 9690:27017 --restart always -v /nfs_data/mongo_9690:/data --name mongo_9690 -d mongo mongod --bind_ip_all --replSet rs1
# AI03
docker run -p 9692:27017 --restart always -v /nfs_data/mongo_9692:/data --name mongo_9692 -d mongo mongod --bind_ip_all --replSet rs1
# AI04
docker run -p 9694:27017 --restart always -v /nfs_data/mongo_9694:/data --name mongo_9694 -d mongo mongod --bind_ip_all --replSet rs1

5. 修改keyfile的用户为mongodb(在docker里)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# AI02
docker exec -it mongo_9690 /bin/bash
cd data
chown mongodb:mongodb keyfile
exit
# AI03
docker exec -it mongo_9692 /bin/bash
cd data
chown mongodb:mongodb keyfile
exit
# AI04
docker exec -it mongo_9694 /bin/bash
cd data
chown mongodb:mongodb keyfile
exit

6. 删掉docker, 重建带有keyfile的docker

1
2
3
4
5
6
7
8
9
# AI02
docker rm -f mongo_9690
docker run -p 9690:27017 --restart always -v /nfs_data/mongo_9690:/data --name mongo_9690 -d mongo mongod --bind_ip_all --replSet rs1 --keyFile /data/keyfile
# AI03
docker rm -f mongo_9692
docker run -p 9692:27017 --restart always -v /nfs_data/mongo_9692:/data --name mongo_9692 -d mongo mongod --bind_ip_all --replSet rs1 --keyFile /data/keyfile
# AI04
docker rm -f mongo_9694
docker run -p 9694:27017 --restart always -v /nfs_data/mongo_9694:/data --name mongo_9694 -d mongo mongod --bind_ip_all --replSet rs1 --keyFile /data/keyfile

7. 在一台机器初始化集群

1
2
3
4
5
6
7
8
# AI02
docker exec -it mongo_9690 mongo
# 查看集群状态
> rs.status()
# 编写配置
> cfg={"_id":"rs1","members":[{"_id":0,"host":"172.24.29.118:9690"}, {"_id":1,"host":"172.24.29.121:9692"}, {"_id":2,"host":"172.24.29.120:9694"}]}
# 初始化配置
> rs.initiate(cfg)

8. 创建用户密码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 只需要在PRIMARY机器(AI02) 执行, 用户信息会同步到其他机器
docker exec -it mongo_9690 mongo
# 在admin库添加admin和nolan两个用户
> use admin
> db.createUser({user: "admin", pwd: "PASSWORD", roles: [{role: "userAdminAnyDatabase", db: "admin"}]})
> db.auth('admin', 'PASSWORD')
> db.createUser({ user: "nolan", pwd: "PASSWORD", roles: [{ role: "dbOwner", db: "db_train" }, { role: "dbOwner", db: "db_recognition" }, { role: "dbOwner", db: "db_store" }] })
# 分别在其他库创建nolan用户
> use db_store
> db.createUser({ user: "nolan", pwd: "PASSWORD", roles: [ { role: "dbOwner", db: "db_store" }] })
> use db_recognition
> db.createUser({ user: "nolan", pwd: "PASSWORD", roles: [{ role: "dbOwner", db: "db_recognition" }] })
> use db_train
> db.createUser({ user: "nolan", pwd: "PASSWORD", roles: [{ role: "dbOwner", db: "db_train" }] })

9. 测试数据同步

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# PRIMARY机器(AI02)
docker exec -it mongo_9690 mongo
> use db_store
> db.auth('nolan', 'PASSWORD')
> db.test.insert({'a': 1})
# 到其他机器查看是否数据有没有同步过去
# SECONDARY机器需要先给予读写权限, 在SECONDARY机器执行如下命令
> db.getMongo().setSlaveOk();
# 或
> db.getMongo().setSecondaryOk();

10. 导入旧数据

1
2
# 备份数据先拷到/nfs_data/mongo_9690
docker exec -it mongo_9690 mongorestore --username nolan --password 'PASSWORD' --db db_store /data/dump/db_store