实验环境
主机/IP | 角色 | 系统 |
server01/192.168.1.201 | 主节点 | ubuntu 22.04 |
server02/192.168.1.202 | 从节点 | / |
server03/192.168.1.203 | 仲裁节点 | / |
server04/192.168.1.204 | 优先级为0的从节点 | / |
server05/192.168.1.205 | 隐藏的从节点 | / |
server06/192.168.1.206 | 延迟的从节点 | / |
一个副本集最多可以有 50 个节点,但只有 7 个投票节点。如果副本集已有 7 个投票节点,则其他节点必须为非投票节点。
server01
生成密钥
mkdir -p /usr/local/src/mongodb/certs
openssl rand -base64 756 > /usr/local/src/mongodb/certs/replset.key
chmod 600 /usr/local/src/mongodb/certs/replset.key
chown -R mongodb:mongodb /usr/local/src/mongodb/certs
将密钥复制到其他节点
All Nodes
安装mongodb
sudo apt-get install gnupg curl
curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg \
--dearmor
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
修改配置文件
vim /etc/mongod.conf
# 设置监听端口
net:
port: 27017
bindIp: 0.0.0.0
# 设置安全
security:
authorization: "enabled"
keyFile: "/usr/local/src/mongodb/certs/replset.key"
# 设置集群信息
replication:
replSetName: "myreplicaset"
启动软件
systemctl start mongod
server01
注册集群
mongosh
use admin
config={ _id:"myreplicaset", members:[ {_id:0,host:'192.168.1.201:27017',priority:2},{_id:1,host:'192.168.1.202:27017',priority:1},{_id:2,host:'192.168.1.203:27017',arbiterOnly:true}] };
rs.initiate(config)
副本集名称为myreplicaset;
id为0,priority为2的192.168.1.201节点将会是主节点;
id为1,priority为1的192.168.1.202节点将会是从节点;
id为2,priority为1的192.168.1.203节点,因为设置了arbiterOnly:true,所以它是仲裁节点
查询副本集状态(建立完成时间根据服务器配置)
rs.status()
{
set: 'mymongo',
date: ISODate('2024-10-06T16:36:18.040Z'),
myState: 1,
term: Long('4'),
syncSourceHost: '',
syncSourceId: -1,
heartbeatIntervalMillis: Long('2000'),
majorityVoteCount: 2,
writeMajorityCount: 2,
votingMembersCount: 3,
writableVotingMembersCount: 2,
optimes: {
lastCommittedOpTime: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
lastCommittedWallTime: ISODate('2024-10-06T16:36:13.677Z'),
readConcernMajorityOpTime: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
appliedOpTime: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
durableOpTime: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
writtenOpTime: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
lastAppliedWallTime: ISODate('2024-10-06T16:36:13.677Z'),
lastDurableWallTime: ISODate('2024-10-06T16:36:13.677Z'),
lastWrittenWallTime: ISODate('2024-10-06T16:36:13.677Z')
},
lastStableRecoveryTimestamp: Timestamp({ t: 1728232533, i: 1 }),
electionCandidateMetrics: {
lastElectionReason: 'priorityTakeover',
lastElectionDate: ISODate('2024-10-06T16:09:43.603Z'),
electionTerm: Long('4'),
lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1728230983, i: 1 }), t: Long('3') },
lastSeenWrittenOpTimeAtElection: { ts: Timestamp({ t: 1728230983, i: 1 }), t: Long('3') },
lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1728230983, i: 1 }), t: Long('3') },
numVotesNeeded: 2,
priorityAtElection: 2,
electionTimeoutMillis: Long('10000'),
priorPrimaryMemberId: 1,
numCatchUpOps: Long('0'),
newTermStartDate: ISODate('2024-10-06T16:09:43.619Z'),
wMajorityWriteAvailabilityDate: ISODate('2024-10-06T16:09:43.718Z')
},
members: [
{
_id: 0,
name: '192.168.1.201:27017',
health: 1,
state: 1,
stateStr: 'PRIMARY',
uptime: 1606,
optime: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
optimeDate: ISODate('2024-10-06T16:36:13.000Z'),
optimeWritten: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
optimeWrittenDate: ISODate('2024-10-06T16:36:13.000Z'),
lastAppliedWallTime: ISODate('2024-10-06T16:36:13.677Z'),
lastDurableWallTime: ISODate('2024-10-06T16:36:13.677Z'),
lastWrittenWallTime: ISODate('2024-10-06T16:36:13.677Z'),
syncSourceHost: '',
syncSourceId: -1,
infoMessage: '',
electionTime: Timestamp({ t: 1728230983, i: 2 }),
electionDate: ISODate('2024-10-06T16:09:43.000Z'),
configVersion: 1,
configTerm: 4,
self: true,
lastHeartbeatMessage: ''
},
{
_id: 1,
name: '192.168.1.202:27017',
health: 1,
state: 2,
stateStr: 'SECONDARY',
uptime: 1604,
optime: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
optimeDurable: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
optimeWritten: { ts: Timestamp({ t: 1728232573, i: 1 }), t: Long('4') },
optimeDate: ISODate('2024-10-06T16:36:13.000Z'),
optimeDurableDate: ISODate('2024-10-06T16:36:13.000Z'),
optimeWrittenDate: ISODate('2024-10-06T16:36:13.000Z'),
lastAppliedWallTime: ISODate('2024-10-06T16:36:13.677Z'),
lastDurableWallTime: ISODate('2024-10-06T16:36:13.677Z'),
lastWrittenWallTime: ISODate('2024-10-06T16:36:13.677Z'),
lastHeartbeat: ISODate('2024-10-06T16:36:16.350Z'),
lastHeartbeatRecv: ISODate('2024-10-06T16:36:16.882Z'),
pingMs: Long('0'),
lastHeartbeatMessage: '',
syncSourceHost: '192.168.1.201:27017',
syncSourceId: 0,
infoMessage: '',
configVersion: 1,
configTerm: 4
},
{
_id: 2,
name: '192.168.1.203:27017',
health: 1,
state: 7,
stateStr: 'ARBITER',
uptime: 1604,
lastHeartbeat: ISODate('2024-10-06T16:36:16.350Z'),
lastHeartbeatRecv: ISODate('2024-10-06T16:36:16.348Z'),
pingMs: Long('0'),
lastHeartbeatMessage: '',
syncSourceHost: '',
syncSourceId: -1,
infoMessage: '',
configVersion: 1,
configTerm: 4
}
],
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1728232573, i: 1 }),
signature: {
hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
keyId: Long('0')
}
},
operationTime: Timestamp({ t: 1728232573, i: 1 })
}
创建超级用户
use admin
db.createUser({user:'root',pwd:'root#1234',roles:[{role: 'root', db: 'admin'},{ role: "__system", db: "admin" }]})
测试
接下来可以在各个节点对数据进行写入读取,以及停止主节点服务观测故障转移的功能是否生效
mongosh --username root --password --authenticationDatabase admin
use test
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
{ item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
{ item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])
拓展
部署优先级为0的从节点,它不能成为主节点和不能参加投票,适合备份数据使用
rs.add({ _id: 3, host: '192.168.1.204:27017', priority: 0 });
部署隐藏的从节点,它们对客户端不可见,不能成为主节点,但是可以进行投票,适合备份、分析、报告等任务
# 获取当前配置
config = rs.conf();
# 添加新成员
config.members.push({ _id: 4, host: '192.168.1.205:27017', priority: 0, hidden: true });
# 重新应用配置
rs.reconfig(config);
部署延迟的从节点,它们对客户端不可见,不能成为主节点,但是可以进行投票,它的特点是延迟复制,对恢复、分析很早之前的数据十分有用
# 获取当前配置
config = rs.conf();
# 添加新成员,secondaryDelaySecs单位为秒
config.members.push({ _id: 5, host: '192.168.1.206:27017', priority: 0, hidden: true, secondaryDelaySecs: 3600 });
# 重新应用配置
rs.reconfig(config);
删除节点
rs.remove("host:port")
替换成员
cfg = rs.conf()
cfg.members[0].host = "host:port"
rs.reconfig(cfg)