4.5 复制集:高可用的基石


4.5 复制集:高可用的基石

从本节起进入 MongoDB 的分布式篇。复制集(Replica Set)解决的是 3.1 节提出的第一个分布式问题:单节点宕机服务不能停、数据不能丢。它的三个机制——oplog 同步、多数派选举、读写关注——分别对应第 3 章的复制、一致性与读写配额思想,对照着读收获最大。

架构:一主多从加仲裁

复制集由若干数据节点(典型三节点:一主两从)构成,主节点(Primary)受理全部写入,从节点(Secondary)持续同步并参与选举;可选的仲裁节点(Arbiter)只投票不存数据,用最低成本凑够选举多数——但它不增强数据安全,反而稀释了数据副本,生产环境建议用三数据节点替代"两数据 + 一仲裁"。

// 查看复制集状态:成员角色与健康度 rs.status() // 输出要点:members[] 中 PRIMARY 与 SECONDARY 标记、 // 每个成员的 optimeDate(同步位点)与 lastHeartbeat(心跳延迟) // 读写偏好:读请求发往从节点以分摊主库压力 db.orders.find({ status: "PAID" }) .readPref("secondaryPreferred")

oplog:同步的血液

主节点的每一次写操作都会记入操作日志 oplog(一个有上限的固定集合),从节点拉取 oplog 并在本地重放,实现异步复制。oplog 是一个环形空间,空间满了旧条目被覆盖——由此推出一个经典故障:从节点宕机太久,恢复时它需要的 oplog 已被覆盖,只能全量重新初始化同步。监控 oplog 窗口(最旧与最新条目的时间差)是复制集运维的日常功课。

选举与写关注:数据安全的两道闸

主节点失联时,存活的数据节点投票选出新主(要求多数派存活——三节点复制集最多容忍一节点故障)。多数派规则同时给了写关注(Write Concern)一个清晰的语义基础:w: "majority" 要求写入在多数数据节点确认后才向客户端返回成功。这是数据安全的锚点——被多数确认的写入,即使原主宕机也不会因选举回滚而丢失。

写关注配置 语义 风险/代价
w: 1(默认) 主节点确认即返回 主库宕机窗口内可能丢写入
w: "majority" 多数节点确认 延迟略升,安全级别最高
w: 1 + j: true 主节点落日志确认 折中:单机掉电不丢

读侧对称的旋钮是读偏好(Read Preference):primary(只读主,强一致)、primaryPreferred、secondary(只读从,分摊压力但可能旧数据)、secondaryPreferred、nearest(就近)。结合 3.3 的档位观:读己之写场景必须 primary,浏览类列表用 secondary 分流。

演练:一次主节点故障的完整时间线

背景:三节点复制集(PRIMARY + 两个 SECONDARY),业务写关注 w:1,某天主节点所在可用区网络抖动,主节点与其他节点心跳中断 15 秒。

操作:推演时间线。第 0 秒心跳中断;第 10 秒(超时阈值)两个从节点发起选举,秒级选出新主;新主接收写入期间,原主其实还活着——它降级为从节点并回滚自己未被新主确认的写入(回滚条目写入回滚文件,需要人工比对合并);业务侧第 12 秒起恢复写入(驱动自动发现新主,期间报连接错误重试)。

结果:服务中断约 12 秒自愈;因 w:1 配置,中断前最后 200 毫秒内的部分写入被回滚,出现少量"订单已创建但库存未扣"的悬挂数据,人工比对回滚文件后修复。

解读:两个要点。w:1 的丢失窗口真实存在——若业务要求订单写入绝不丢失,写关注必须 majority,代价是写入延迟略增;回滚文件是人工义务——复制集自动保住的是多数派确认的数据,单主确认的数据进回滚文件等人工处理。这就是 3.1 CAP 在 MongoDB 里的具体价格表。

变式:把写关注改为 majority 重演同一故障,回滚的只有未达多数确认的极少量写入,业务层再配重试幂等,即可做到"无感切换"。配置没有对错,业务定级决定配置。

易错点

第一个是把仲裁节点当数据节点用:"两数据 + 一仲裁"架构里数据只有两份,一份数据节点损坏后既无冗余也无容错余量。第二个是读偏好滥用 secondary:读从节点换吞吐却引入复制延迟读旧数据,会话敏感页面读己之写失效(3.3 的读己之写路由),使用前分清哪些读可以旧。第三个是忽视 oplog 窗口监控:大事务或批量写入会瞬间吃掉 oplog 空间,从节点一旦落后出窗即触发全量同步,雪上加霜。

选举与故障转移演练

复制集是一组维护相同数据的 mongod 进程:一个主节点接收写入,若干从节点异步复制,另有可选的仲裁节点只投票不存数据。

演练:主节点失联后发生了什么

  1. 心跳超时(默认 10 秒):其余节点发现联系不上主节点,标记为疑似不可用;
  2. 发起选举:具备选举资格的节点(数据与主节点足够新、优先级大于 0)发起选举,需要获得多数票;
  3. 选出新主:票数过半者成为新主,其余节点重新指向它开始复制。整个过程通常十秒内完成;
  4. 旧主回归:旧主恢复后以从节点身份加入,若它在失联前有过未同步的写入,这部分写入会被回滚(保存在回滚文件里,需人工处理)。
// 查看复制集状态的关键字段 rs.status().members.forEach(m => print(m.name, m.stateStr, m.health, m.optimeDate)) // PRIMARY / SECONDARY / ARBITER,health 为 1 表示可达 // 查看复制延迟(主从 optime 的差值) rs.printSecondaryReplicationInfo() // 输出示例:source: 10.0.0.12:27017 syncedTo: ... 3 secs (0.05 hrs) behind the primary

写关注与读关注:一致性的两个旋钮

复制集最容易被忽视、也最该配的两个参数是写关注(writeConcern)与读关注(readConcern),它们直接决定了这个复制集在 CAP 里站在哪一边。

配置 语义 一致性 延迟
w:1(默认) 主节点写入即返回 弱,主节点宕机可能丢 最低
w:majority 多数节点确认后返回 强,不会因切换丢失 中等
w:majority + readConcern:majority 只读取被多数确认的数据 强一致读 较高
readConcern:snapshot 事务内的快照读 最强 最高

生产建议:涉及资金、库存、配额的写入显式指定 w:majority;日志、行为埋点这类可容忍少量丢失的写入用默认配置换取吞吐。读的侧同理——对账类读用 majority,普通展示用 local。

一条经验:默认配置(w:1)在单机房小规模部署下问题不大,但一旦上了云或跨机房,网络抖动频率显著上升,此时"主节点写入即返回"意味着一次切换就可能丢掉最后几百毫秒的写入。这个风险窗口值不值得消除,取决于业务——但必须先知道它的存在。

本节要点回顾

  • 复制集标准配置:一主两从三数据节点,仲裁节点是低成本凑票方案而非数据安全方案。
  • 同步靠 oplog 环形日志重放,窗口耗尽触发全量重同步,必须监控。
  • 选举要求多数派存活;w:1 有丢失窗口,majority 是数据安全锚点。
  • 读偏好五档按业务分派:会话敏感读主,浏览列表读从。
  • 主库故障的完整代价 = 切换时间 + 回滚文件人工比对,两者都要演练。

高可用有了,规模还没解——下一节分片集群,把数据摊到更多机器上。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U