MongoDB双机热备份

上次把服务器的MongoDB端口开放然后忘记关了,而且数据库还没有密码,然后就被黑了,所以感觉还是有必要做一下备份的,手动备份有麻烦,所以这里用到了MongoDB的replSet,也就是副本集来做热备份。

备份服务器上的数据(可选)

配置双热机备份时最好把之前已有的数据备份起来,本文会删除现有数据

使用MongoDB自带的mogodump备份,具体可以去看官方文档

1
2
3
mongodump -h 127.0.0.1:27017 -d ihci -u root -p password -o backup
mongodump -h 127.0.0.1:27017 -d calendar -u root -p password -o backup
zip -r backup.zip backup

相关参数配置

  • -h 地址和端口
  • -d 数据库名称
  • -u 用户名(如果有的话)
  • -p 密码(如果有的话)
  • -o 输出路径 (backup文件夹先建好)

配置frp

安装frp

安装frp的原因是本地服务器没有公网ip地址,需要将本地服务器端口穿透到云服务器上去
注意本地和云的frp版本要一致,当前使用版本:0.44.0

1
2
wget https://github.com/fatedier/frp/releases/download/v0.44.0/frp_0.44.0_linux_amd64.tar.gz
tar -zxvf frp_0.44.0_linux_amd64.tar.gz

配置frp

进入frp文件夹,可以看到4个文件(其他忽略):

  • frpc
  • frpc.ini
  • frps
  • frps.ini

云服务器配置frp

编辑云服务器的frps.ini,修改后如下:

1
2
3
4
5
6
7
8
9
10
[common]
# 注释很重要 注释很重要 注释很重要
# frps运行端口
bind_port = 7002
# frp面板运行端口,可以看frp连接和流量,不想开把下面三个注释掉
dashboard_port = 7500
dashboard_port = admin
dashboard_pwd = myPwd
# 记住这个token
token = myToken

云服务器运行frps

1
nohup ./frps -c frps.ini &

注意要开启云服务器的防火墙端口:7002,7500,27001,27002,27017

本地服务器配置frp

编辑本地服务器的frpc.ini,修改后如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[common]
# 注释很重要 注释很重要 注释很重要
# 云服务器的ip地址
server_addr = 123.123.123.123
# 云服务器frps运行端口
server_port = 7002
# 这里必须开tls,不然校园网会封frp端口
# 这里必须开tls,不然校园网会封frp端口
# 这里必须开tls,不然校园网会封frp端口
tls_enable = true
# token要和frps保持一致
token = password

# ssh 映射后可以用外网连接本地服务器,不做也行
[IHCI_ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 7003

# MongoDB 备用机
[mongodb_secondary]
type = tcp
local_ip = 127.0.0.1
# 记住这个端口
local_port = 27001
remote_port= = 27001

# MongoDB 仲裁机
[mongodb_arbiter]
type = tcp
local_ip = 127.0.0.1
# 记住这个端口
local_port = 27002
remote_port = 27002

本地服务器运行frpc

1
nohup ./frpc -c frpc.ini &

运行成功后可以打开frp面板(云服务器的7500端口)查看连接,可以看到有三个tcp连接

配置MongoDB

如果已经安装MongoDB且配置好用户密码建议重新安装或者清空data
注意本地和云的MongoDB版本要一致,当前使用版本:3.2.7
配置参考:简书

MongoDB副本集

MongoDB副本集官网的定义:
A replica set in MongoDB is a group of mongod processes that maintain the same data set.
简单来说就是运行多个mongod,存储一样的数据,官网的最少节点是3个,有两种部署方式(有仲裁节点和无仲裁节点),这里为了节省空间我们使用了有仲裁节点的部署方式(仲裁节点不存储数据)。

replica-set-primary-with-secondary-and-arbiter.bakedsvg

MongoDB在主节点挂掉之后会投票投出下一个主节点,在这种情况下只有Secondary可以成为主节点,所以Secondary成为主节点,当挂掉的节点重新上线后会自动成为副节点。

副本集部署后主节点存储的数据副节点也会存储,我们的目标只是要做简单的双机热备份不考虑节点挂掉的情况,所以把主节点部署在云服务器上,副节点和仲裁节点部署在本地服务器上,然后通过frp将本地服务器的节点穿透到云服务器上。

安装MongoDB

注意本地和云的frp版本要一致,当前使用版本:0.44.0

本地服务器和云服务器都安装:

1
2
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.7.tgz
tar -zxvf mongodb-linux-x86_64-3.2.7.tgz

进入MongoDB文件夹可以看到bin文件夹(其他忽略),bin文件夹里就是MongoDB的可执行文件

云服务器配置MongoDB

创建目录

创建MongoDB目录,将MongoDB的bin文件夹复制到目录里,创建数据目录和日志目录

1
2
3
4
mkdir /root/mongodb
cp -r /root/mongodb-linux-x86_64-3.2.7/bin /root/mongodb
cd /root/mongodb
mkdir data logs

创建配置文件

在mongodb目录下创建配置文件mongodb.conf,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#数据库存储位置:改为实际路径
dbpath = /root/mongodb/data

#日志文件位置:改为实际路径,注意填上文件名
logpath = /root/mongodb/logs/mongodb.log

#端口
port = 27017

#是否以守护进程的方式运行
fork = true

#副本集指向备机
replSet=datamip/123.123.123.123:27001

# 暂时注释掉,教程后面会用到

# 是否开启认证
# auth=true

# keyFile鉴权文件
# keyFile=/root/mongodb/keyFile

本地服务器配置MongoDB

创建目录

本地服务器需要开启两个MongoDB,分别是secondary(副机)和arbiter(仲裁机)

创建mongodb目录,将MongoDB的bin文件夹复制到目录里,创建数据目录和日志目录

1
2
3
4
mkdir /root/mongodb
cp -r /root/mongodb-linux-x86_64-3.2.7/bin /root/mongodb
cd /root/mongodb
mkdir data logs

将mongodb目录复制两份,一份命名为secondary(副机),一份命名为arbiter(仲裁机)

1
2
cp -r /root/mongodb /root/secondary
cp -r /root/mongodb /root/arbiter

创建配置文件

在secondary和arbiter目录下分别创建配置文件mongodb.conf,配置如下:

secondary(副机):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#数据库存储位置:改为实际路径
dbpath = /root/secondary/data

#日志文件位置:改为实际路径,注意填上文件名
logpath = /root/secondary/logs/mongodb.log

#端口
port = 27001

#是否以守护进程的方式运行
fork = true

#副本集指向主机
replSet=datamip/123.123.123.123:27017

# 暂时注释掉,教程后面会用到

# 是否开启认证
# auth=true

# keyFile鉴权文件
# keyFile=/root/secondary/keyFile

arbiter(仲裁机):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#数据库存储位置:改为实际路径
dbpath = /root/arbiter/data

#日志文件位置:改为实际路径,注意填上文件名
logpath = /root/arbiter/logs/mongodb.log

#端口
port = 27002

#是否以守护进程的方式运行
fork = true

#副本集指向主机
replSet=datamip/123.123.123.123:27017

# 暂时注释掉,教程后面会用到

# 是否开启认证
# auth=true

# keyFile鉴权文件
# keyFile=/root/arbiter/keyFile

启动MongoDB

在三个节点MongoDB的bin目录下分别启动MongoDB

1
./mongod -f ../mongodb.conf

显示如下启动成功:

1
2
3
about to fork child process, waiting until server is ready for connections.
forked process: 1234
child process started successfully, parent exiting

组建副本集

在主机也就是云服务器上连接MongoDB,配置副本集
(注意要使用mongo命令首先要配置好环境变量,这里默认配置完成,也可以在bin目录下使用./mongo代替)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
mongo --port 27017
# 切换到admin数据库
> use admin
# 设置replSet
> db.runCommand({
..."replSetInitiate":{
... "_id":"datamip", //此 replSet 的名字
... "members":[ //此 replSet 的主备成员,不包含仲裁机
... {
... "_id":1,"host":"123.123.123.123:27017"
... },
... {
... "_id":2,"host":"123.123.123.123:27001"
... }
... ]}})
# { "ok" : 1 }
# 添加仲裁机
> rs.addArb("123.123.123.123:27002")
# 主机命令行头变为PRIMARY
# 查看副本集状态
datamip:PRIMARY> rs.status()
{
"set" : "datamip",
"date" : ISODate("2022-08-24T02:23:54.884Z"),
"myState" : 2,
"term" : NumberLong(5),
"syncingTo" : "123.123.123.123:27017",
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 1,
"name" : "123.123.123.123:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 241108,
"optime" : {
"ts" : Timestamp(1661220933, 2),
"t" : NumberLong(5)
},
"optimeDate" : ISODate("2022-08-23T02:15:33Z"),
"lastHeartbeat" : ISODate("2022-08-24T02:23:54.464Z"),
"lastHeartbeatRecv" : ISODate("2022-08-24T02:23:54.771Z"),
"pingMs" : NumberLong(56),
"electionTime" : Timestamp(1661066732, 1),
"electionDate" : ISODate("2022-08-21T07:25:32Z"),
"configVersion" : 2
},
{
"_id" : 2,
"name" : "123.123.123.123:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 241110,
"optime" : {
"ts" : Timestamp(1661220933, 2),
"t" : NumberLong(5)
},
"optimeDate" : ISODate("2022-08-23T02:15:33Z"),
"syncingTo" : "123.123.123.123:27017",
"configVersion" : 2,
"self" : true
},
{
"_id" : 3,
"name" : "123.123.123.123:27002",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 240562,
"lastHeartbeat" : ISODate("2022-08-24T02:23:53.609Z"),
"lastHeartbeatRecv" : ISODate("2022-08-24T02:23:53.242Z"),
"pingMs" : NumberLong(119),
"configVersion" : 2
}
],
"ok" : 1
}

配置认证和keyFile

将MongoDB端口暴露在外网有较高的风险,所以我们还需要增加认证,而副本集之间的认证是通过keyFile完成的

创建用户

连接主机节点创建用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 创建admin用户
datamip:PRIMARY> db.createUser({
... user:"admin",
... pwd:"password",
... roles:[
... {role: "userAdminAnyDatabase", db:"admin"},
... {role: "root", db:"admin"}
...]})

# 创建数据库用户
datamip:PRIMARY> use ihci
datamip:PRIMARY> db.createUser({
... user:"root",
... pwd:"password",
... roles:[
... {role:"dbOwner", db:"ihci"}
... ]})
datamip:PRIMARY> use calendar
datamip:PRIMARY> db.createUser({
... user:"root",
... pwd:"password",
... roles:[
... {role:"dbOwner", db:"calendar"}
... ]})

连接验证

1
2
mongo 127.0.0.1:27017/ihci -u root -p password
mongo 127.0.0.1:27017/calendar -u root -p password

创建副本集认证文件keyFile

注意三个节点要用同一份keyFile且要修改成600的文件属性

首先先关闭每个节点

1
2
3
# 主机为例
mongo 127.0.0.1:27017/admin
datamip:PRIMARY> db.shutdownServer()

在云服务器上创建

1
2
3
openssl rand -base64 90 -out ./keyFile
cp keyFile /root/mongodb
chmod 600 /root/mongodb/keyFile

同时将keyFile拷贝到本地服务器的两个节点的MongoDB目录下(记得修改成600的文件属性

最终每个节点的MongoDB文件目录如下:
mongodb
├── bin #可执行文件
├── data #存放数据库文件
├── keyFile #KeyFile鉴权文件
├── logs #存放系统日志
├── mongodb.conf #配置文件

开启认证

修改三个节点的mongodb.conf,将auth和keyFile解注释,重新启动MongoDB

恢复MongoDB数据(可选)

将之前备份的文件backup解压,使用MongoDB自带的mongorestore恢复数据(在主机上恢复,副机也会恢复),具体可以去看官方文档

1
2
3
unzip backup.zip
mongorestore -h 127.0.0.1:27017 -u root -p password -p 27017 -d ihci backup/ihci
mongorestore -h 127.0.0.1:27017 -u root -p password -p 27017 -d calendar backup/calendar

相关参数配置

  • -h 地址和端口
  • -d 数据库名称
  • -u 用户名(如果有的话)
  • -p 密码(如果有的话)

MongoDB双机热备份
http://example.com/2022/09/05/MongoDB双机热备份/
作者
Sonce
发布于
2022年9月5日
许可协议