本文以 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` 的组合,可以在实际环境中验证一致性与延迟的权衡,为生产场景选择更稳健的参数与读写策略。



点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部