目录
1. 概述
2.节点成员介绍
3.工作原理
4.下载地址
5.部署规划
6.部署
7.注意事项
8.总结
概述
MongoDB 副本集是一个用于数据高可用性和冗余的集群配置。副本集由多个 MongoDB 实例组成,其中一个是主节点(Primary),其余是从节点(Secondary)。主节点负责所有写入操作,从节点则从主节点复制数据,提供读操作的负载均衡,(主节点-从节点-从节点)(推荐);如果情况(例如成本)禁止添加第三个数据承载节点,则可以是两个数据承载节点加一个仲裁节点(主节点-从节点-仲裁节点)
节点成员介绍
主节点以及两个从节点 (P-S-S)
具有三个存储数据的节点的副本集包含:
- 一个主节点。
- 两个从节点。两个从节点都可以在选举中成为主节点
主节点、从节点和仲裁节点(P-S-A)
具有两个存储数据的节点的三节点副本集包含:
- 一个主节点。
- 一个从节点成员。从节点可以在选举中成为主节点。
- 一个仲裁节点。仲裁节点仅在选举中投票。
工作原理
- 主从关系:写入操作总是发生在主节点,从节点会异步复制主节点的数据。
- 数据同步:从节点定期向主节点请求数据更新,以保持数据一致性。
- 故障转移:如果主节点发生故障,副本集中会选举一个新的主节点,确保服务的持续可用性。
- 读操作:可以配置从节点处理读操作,以分担主节点的负载。
下载地址
MongoDB Community Downloads | MongoDB
部署规划 (P-S-S)
配置hosts解下
10.10.10.21 mon1(Pr)
10.10.10.22 mon2(Se)
10.10.10.23 mon3(Se)
部署
创建相关目录
tar xvf mongodb-linux-x86_64-rhel70-7.0.14.tgz
mv mongodb-linux-x86_64-rhel70-7.0.14 mongodb
mkdir -p /monogodata/{config,data,log}
配置文件
vim /monogodata/config/mongo-conf
# 网络设置
net:
port: 27017 # MongoDB 默认端口
bindIp: 0.0.0.0 # 允许从所有 IP 访问,生产环境建议限制
# 数据目录
storage:
dbPath: /monogodata/data # 数据文件存放路径
wiredTiger:
engineConfig:
cacheSizeGB: 26 # 根据情况配置内存(75%)
# 日志设置
systemLog:
destination: file # 日志写入文件
path: /monogodata/log/mongod.log # 日志文件路径
logAppend: true # 追加日志
logRotate: rename # 日志轮转方式,支持 rename 或 reopen
# 副本集配置
replication:
replSetName: "rs0" # 副本集名称
# 进程设置
processManagement:
fork: true # 以后台进程方式运行
pidFilePath: /monogodata/data/mongod.pid # PID 文件路径
# 慢日志设置
operationProfiling:
slowOpThresholdMs: 100 # 记录慢操作的阈值,单位为毫秒
mode: slowOp # 记录慢操作
# 认证
#security:
# authorization: enabled # 启用认证
# keyFile: /monogodata/config/mongo-keyfile # 密钥文件路径
创建秘钥文件
openssl rand -base64 753 >/monogodata/config/mongo-keyfile
#将主节点生成的mongo-keyfile文件拷贝到从节点,注意权限
chmod 600 /monogodata/config/mongo-keyfile
启动
/opt/mongodb/bin/mongod -f /monogodata/config/mongo-confbr
初始化
[root@easyliao012 ~]# mongosh mon1:27017
admin> rs.initiate()
##本文章部署的是p-s-s架构
rs0 [direct: primary] admin>rs.add("mon2:27017")
rs0 [direct: primary] admin>rs.add("mon3:27017")
rep:PRIMARY> rs.conf() #查看副本集主节点配置
rep:PRIMARY> rs.status() #查看副本集状态
##部署仲裁架构(P-S-A),本次部署不需要执行
rs0 [direct: primary] admin>rs.add("mon2:27017")
rs0 [direct: primary] admin>rs.addArb("mon3:27017")
创建超管账户
rs0 [direct: primary] admin> use admin
rs0 [direct: primary] admin> db.createUser({
user: "root",
pwd: "hjasfWERFWE2ewd",
roles: [{ role: "root", db: "admin" }]
});
开启认证的key文件重启各个节点
--去掉注释
# 认证
security:
authorization: enabled # 启用认证
keyFile: /monogodata/config/mongo-keyfile # 密钥文件路径
从节点先停止,最后停止主节点
/opt/mongodb/bin/mongod -f /monogodata/config/mongo-conf --shutdown
先启动主节点,再启动从节点
/opt/mongodb/bin/mongod -f /monogodata/config/mongo-conf
查看节点状态
mongosh mongodb://mon1:27017 -u "root" --authenticationDatabase "admin" -p hjasfWERFWE2ewd
rs0 [direct: primary] admin> rs.status()
{
set: 'rs0',
date: ISODate("2024-09-21T11:53:28.190Z"),
myState: 1,
term: Long("3"),
syncSourceHost: '',
syncSourceId: -1,
heartbeatIntervalMillis: Long("2000"),
majorityVoteCount: 2,
writeMajorityCount: 2,
votingMembersCount: 3,
writableVotingMembersCount: 3,
optimes: {
lastCommittedOpTime: { ts: Timestamp({ t: 1726919601, i: 1 }), t: Long("3") },
lastCommittedWallTime: ISODate("2024-09-21T11:53:21.060Z")},
members: [
{
_id: 0,
name: 'mon1:27017',
health: 1,
state: 1,
stateStr: 'PRIMARY',
uptime: 90994,
optime: { ts: Timestamp({ t: 1726919601, i: 1 }), t: Long("3") },
optimeDate: ISODate("2024-09-21T11:53:21.000Z"),
lastAppliedWallTime: ISODate("2024-09-21T11:53:21.060Z"),
lastDurableWallTime: ISODate("2024-09-21T11:53:21.060Z"),
syncSourceHost: '',
syncSourceId: -1,
infoMessage: '',
electionTime: Timestamp({ t: 1726828657, i: 1 }),
electionDate: ISODate("2024-09-20T10:37:37.000Z"),
configVersion: 5,
configTerm: 3,
self: true,
lastHeartbeatMessage: ''
},
{
_id: 1,
name: 'mon2:27017',
health: 1,
state: 2,
stateStr: 'SECONDARY',
uptime: 90951,
optime: { ts: Timestamp({ t: 1726919601, i: 1 }), t: Long("3") },
optimeDurable: { ts: Timestamp({ t: 1726919601, i: 1 }), t: Long("3") },
optimeDate: ISODate("2024-09-21T11:53:21.000Z"),
optimeDurableDate: ISODate("2024-09-21T11:53:21.000Z"),
lastAppliedWallTime: ISODate("2024-09-21T11:53:21.060Z"),
lastDurableWallTime: ISODate("2024-09-21T11:53:21.060Z"),
lastHeartbeat: ISODate("2024-09-21T11:53:27.099Z"),
lastHeartbeatRecv: ISODate("2024-09-21T11:53:27.531Z"),
pingMs: Long("0"),
lastHeartbeatMessage: '',
syncSourceHost: 'mon1:27017',
syncSourceId: 0,
infoMessage: '',
configVersion: 5,
configTerm: 3
},
{
_id: 2,
name: 'mon3:27017',
health: 1,
state: 2,
stateStr: 'SECONDARY',
uptime: 90927,
optime: { ts: Timestamp({ t: 1726919601, i: 1 }), t: Long("3") },
optimeDurable: { ts: Timestamp({ t: 1726919601, i: 1 }), t: Long("3") },
optimeDate: ISODate("2024-09-21T11:53:21.000Z"),
optimeDurableDate: ISODate("2024-09-21T11:53:21.000Z"),
lastAppliedWallTime: ISODate("2024-09-21T11:53:21.060Z"),
lastDurableWallTime: ISODate("2024-09-21T11:53:21.060Z"),
lastHeartbeat: ISODate("2024-09-21T11:53:27.098Z"),
lastHeartbeatRecv: ISODate("2024-09-21T11:53:27.097Z"),
pingMs: Long("0"),
lastHeartbeatMessage: '',
syncSourceHost: 'mon2:27017',
syncSourceId: 1,
infoMessage: '',
configVersion: 5,
configTerm: 3
}
],
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1726919601, i: 1 }),
signature: {
hash: Binary(Buffer.from("c1d2f85d83c0a69b8de904ce00211013c21e4098", "hex"), 0),
keyId: Long("7416670258263490567")
}
},
operationTime: Timestamp({ t: 1726919601, i: 1 })
}
创建库
rs0 [direct: primary] admin> use mon
rs0 [direct: primary] mon> db.tt.insert({"articleid":"100004","content":"今天天气真好,阳光明媚","userid":"1001","nickname":"rose"}) ;
DeprecationWarning: Collection.insert() is deprecated. Use insertOne, insertMany, or bulkWrite.
{
acknowledged: true,
insertedIds: { '0': ObjectId("66eeb354f5149446a62bcc11") }
}
rs0 [direct: primary] mon> db.tt.find();
[
{
_id: ObjectId("66eeb354f5149446a62bcc11"),
articleid: '100004',
content: '今天天气真好,阳光明媚',
userid: '1001',
nickname: 'rose'
}
]
查看从节点数据同步
root@easyliao012 ~]# mongosh mongodb://mon1:27017 -u "root" --authenticationDatabase "admin" -p hjasfWERFWE2ewd
rs0 [direct: secondary] test> show dbs;
admin 225 kB
config 340 kB
local 823 kB
mon 41 kB
rs0 [direct: secondary] test> use mon
switched to db mon
rs0 [direct: secondary] mon> show tables;
tt
rs0 [direct: secondary] mon> db.tt.find()
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
MongoServerError: not primary and secondaryOk=false - consider using db.getMongo().setReadPref() or readPreference in the connection string
rs0 [direct: secondary] mon>
开启从节点可读
rs0 [direct: secondary] mon>rs.secondaryOk();
[direct: secondary] mon> db.tt.find()
[
{
_id: ObjectId("66eeb354f5149446a62bcc11"),
articleid: '100004',
content: '今天天气真好,阳光明媚',
userid: '1001',
nickname: 'rose'
注意事项
- 认证与权限:启用副本集时,务必配置安全性(如 keyFile 和用户权限)。
- 网络延迟:确保节点之间的网络连接良好,以减少数据同步延迟。
- 节点数量:推荐使用奇数数量的节点(至少三个),以保证选举过程中的稳定性。
- 数据一致性:在某些情况下,读取从节点可能导致读取过期数据,需根据需求配置读偏好。
总结
MongoDB 7 的副本集是实现数据高可用性和冗余的重要工具。通过配置合理的节点和适当的安全措施,可以有效提高系统的可靠性和性能。对于关键业务系统,实施副本集是确保数据持久性和可用性的最佳实践。