本文以 MongoDB 5.0+/6.0 环境为例,搭建三节点副本集并在不同 writeConcern 与 readConcern 下进行插入与读取实验,配合 `rs.stepDown()` 模拟主从切换,确保每一步都可复现与验证。
## 环境与前提
- 版本:MongoDB 5.0 或 6.0(社区版或企业版均可)。
- 拓扑:3 节点(1 Primary + 2 Secondary),局域网时钟同步(NTP)。
- 客户端:mongosh。
## 副本集初始化(可复现)
// 三个实例分别监听 27017/27018/27019
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "host1:27017", priority: 1 },
{ _id: 1, host: "host2:27018", priority: 1 },
{ _id: 2, host: "host3:27019", priority: 0 }
]
})
rs.status()
验证:`rs.status()` 显示 `PRIMARY` 与 `SECONDARY` 正常;`optimeDate` 与 `lastHeartbeat` 正常更新。
## 写关注与超时(writeConcern)
常见取值:
- `w: 1`:仅 Primary 确认,最低延迟,故障时可能丢失未复制到多数节点的写入。
- `w: "majority"`:多数节点确认,建议与 `wtimeoutMS` 配合控制超时。
示例(mongosh):
db.getMongo().setWriteConcern({ w: "majority", wtimeoutMS: 5000 })
db.getMongo().setReadConcern("majority")
db.test.insertOne({ k: 1, v: "a" })
验证:在 Secondary 人为注入网络延迟(如 `tc qdisc`)时,`wtimeoutMS` 触发可观察到超时错误;恢复后再次写入成功。
## 读偏好与一致性(readPreference / readConcern)
- `readPreference: primary`:强一致读取;避免旧数据。
- `readPreference: secondary`:低延迟但可能读取到稍旧数据。
- `readConcern: local|majority`:`majority` 提供更强读取一致性,延迟略增。
示例:
// 强一致读取
db.getMongo().setReadPref("primary")
db.getMongo().setReadConcern("majority")
db.test.find({ k: 1 })
// 延迟敏感读取(容忍旧数据)
db.getMongo().setReadPref("secondary")
db.getMongo().setReadConcern("local")
db.test.find({ k: 1 })
## 故障切换可验证实验
// 在 Primary 执行强制降级(维护窗口)
rs.stepDown(60) // 60 秒内拒绝重新成为主
rs.status() // 观察新 PRIMARY 选举
验证点:
- 在 `w: "majority"` 下提交的事务,在新 PRIMARY 上可见。
- 使用 `readPreference: primary` 的读取在选举期间短暂失败(连接重试),`secondary` 读取可继续但一致性较弱。
## 生产参数建议(均可直接验证)
- 写:`writeConcern = { w: "majority", wtimeoutMS: 3000–8000 }`。
- 读:强一致业务用 `readPreference: primary` + `readConcern: majority`;报表/缓存可用 `secondary` + `local`。
- 监控:
db.getSiblingDB("local").system.replset.findOne() // 查看副本集配置
rs.printReplicationInfo() // 主节点复制窗口
rs.printSecondaryReplicationInfo() // 从节点复制延迟
## 注意事项
- `rs.stepDown` 会影响业务连接,请在维护窗口演练;生产依赖驱动的自动重试与拓扑发现。
- 写入路径必须容忍网络与磁盘抖动,设置合理 `wtimeoutMS` 并做好告警。
- 不同版本对选举与心跳参数默认值略有差异,上线前以目标版本文档为准核对。
## 结语
通过副本集的标准部署与降级演练,结合 `writeConcern/readConcern/readPreference` 的组合,可以在实际环境中验证一致性与延迟的权衡,为生产场景选择更稳健的参数与读写策略。

发表评论 取消回复