mongo db集群故障选举分析

转载请注明出处:

一、MongoDB集群基础架构

1. 副本集(Replica Set)核心原理

  • 节点角色

    • Primary :唯一可写节点,处理所有写操作和默认读请求

    • Secondary :异步复制Primary数据,可配置为只读节点

    • Arbiter (可选):不存储数据,仅参与投票

  • 选举机制

    • 基于Raft协议,需多数节点存活 (N/2 +1)才能选出Primary

    • 每个节点有1票,Arbiter无数据但有投票权

  • 数据同步

    • 通过Oplog(操作日志)实现异步复制

    • 写操作需满足writeConcern级别才返回成功

2. 三节点典型部署

复制代码
Node1: Primary (投票权=1)
Node2: Secondary (投票权=1)
Node3: Secondary/Arbiter (投票权=1)
多数票数(majority)=2

二、单节点故障场景分析

1.集群状态变化:

  1. 剩余节点 :2个节点存活(1主1从或2从)。

  2. 选举能力

    • 三节点集群的多数(majority)= 2。

    • 剩余2个节点仍能形成多数,触发自动选举。

  3. 读写能力

    • 新主节点继续处理写操作 (需满足w: majority)。

    • 读操作 可正常进行(从新主或剩余从节点)。

  4. 数据安全

    • 若宕机节点是主节点:已确认的写操作(w: majority)不会丢失。

    • 若宕机节点是从节点:主节点继续服务,数据同步暂停直至节点恢复。

  5. 恢复流程

    • 自动故障转移(通常30秒内完成)。

    • 宕机节点恢复后自动同步增量数据。

  6. 选举日志:

2. 故障节点类型

故障节点 集群行为 影响范围
Primary 剩余2个Secondary触发选举,30秒内选出新Primary 写入中断<30秒,读操作可继续(若客户端配置readPreference=secondaryPreferred)
Secondary Primary继续服务,集群标记该节点为RECOVERING,恢复后自动同步增量数据 无写入中断,读能力降级(少一个读节点)

3. 数据一致性保障

  • 写关注(Write Concern)

    • 若写操作配置w: majority,即使故障节点未确认,数据也不会丢失

    • 示例安全写入命令:

      复制代码
      db.products.insert(
        { item: "card", qty: 15 },
        { writeConcern: { w: "majority", j: true } }  // j=true表示持久化到磁盘
      )

三、双节点故障场景分析

1.集群状态变化:

  1. 剩余节点 :1个节点存活。

  2. 选举能力

    • 无法满足多数(2/3),无法选举新主

    • 原主节点若存活则继续服务,否则集群无主。

  3. 读写能力

    • 写操作 :完全不可用(无主节点)。

    • 读操作

      • 若存活节点是主节点:可读(需客户端直连该节点)。

      • 若存活节点是从节点:需设置readPreference=secondary

  4. 数据风险

    • 若原主节点宕机且未持久化最新数据:可能丢失未复制到从节点的写操作。
  5. 恢复选项

    • 自动恢复 :需至少一个节点恢复形成多数。

    • 强制恢复 (高风险)

2. 剩余节点状态

存活节点 集群状态 恢复方案
仅Primary 失去majority,Primary自动降级为Secondary,集群进入只读模式 需手动干预: 1. 重启一个故障节点 2. 或强制重组副本集(rs.reconfig())
仅Secondary 无Primary,所有写入操作失败,读操作需显式指定readPreference=secondary 需至少恢复1个节点以形成majority

3. 数据风险窗口

  • 潜在丢失数据

    • 故障前写入未达到w: majority的数据可能丢失

    • 可通过oplog检查未复制的操作:

      复制代码
      // 在Primary上查看oplog时间窗口
      rs.printReplicationInfo()
      // 输出示例:oplog first event time -> last event time

四、核心机制深度解析

1. 选举触发条件

复制代码
  A[节点检测Primary无响应] --> B[发起选举请求]
    B --> C{获票数≥majority?}
    C -->|Yes| D[成为新Primary]
    C -->|No| E[等待重试]

2. 数据同步流程

  1. Primary将写操作记录到local.oplog.rs集合

  2. Secondary定期拉取(fetch) Primary的oplog

  3. 应用oplog到本地数据集(异步过程)

3. 故障恢复时序

复制代码
故障检测(10s) → 选举阶段(30s) → 数据同步(依赖网络带宽)

五、生产环境建议

1. 部署优化

  • 跨机房容灾

    复制代码
    机房A: Primary + Secondary
    机房B: Secondary
  • 优先级配置

    复制代码
    // 确保特定节点优先成为Primary
    cfg = rs.conf()
    cfg.members[0].priority = 2
    cfg.members[1].priority = 1
    rs.reconfig(cfg)

    以下是一个集群配置下的 : rs.conf() 配置:

    复制代码
    rs0:PRIMARY> rs.conf()
    {
            "_id" : "rs0",
            "version" : 222935,
            "protocolVersion" : NumberLong(1),
            "writeConcernMajorityJournalDefault" : true,
            "members" : [
                    {
                            "_id" : 0,
                            "host" : "mongo1:27017",
                            "arbiterOnly" : false,
                            "buildIndexes" : true,
                            "hidden" : false,
                            "priority" : 2,
                            "tags" : {
    
                            },
                            "slaveDelay" : NumberLong(0),
                            "votes" : 1
                    },
                    {
                            "_id" : 1,
                            "host" : "mongo2:27017",
                            "arbiterOnly" : false,
                            "buildIndexes" : true,
                            "hidden" : false,
                            "priority" : 2,
                            "tags" : {
    
                            },
                            "slaveDelay" : NumberLong(0),
                            "votes" : 1
                    },
                    {
                            "_id" : 2,
                            "host" : "mongo3:27017",
                            "arbiterOnly" : false,
                            "buildIndexes" : true,
                            "hidden" : false,
                            "priority" : 2,
                            "tags" : {
    
                            },
                            "slaveDelay" : NumberLong(0),
                            "votes" : 1
                    }
            ],
            "settings" : {
                    "chainingAllowed" : true,
                    "heartbeatIntervalMillis" : 2000,
                    "heartbeatTimeoutSecs" : 10,
                    "electionTimeoutMillis" : 10000,
                    "catchUpTimeoutMillis" : -1,
                    "catchUpTakeoverDelayMillis" : 30000,
                    "getLastErrorModes" : {
    
                    },
                    "getLastErrorDefaults" : {
                            "w" : 1,
                            "wtimeout" : 0
                    },
                    "replicaSetId" : ObjectId("67d7f53d2d42a33b47b36ff2")
            }
    }
    rs0:PRIMARY>

2. 监控关键指标

  • 选举相关

    复制代码
    mongostat -e "repl_set_name,election_date,term"  # 监控选举事件
  • 复制延迟

    复制代码
    db.adminCommand({ replSetGetStatus: 1 }).members.map(m => m.optimeDate)

3. 灾难恢复方案

  • 强制恢复单节点集群 (极端情况):

    复制代码
    // 在唯一存活的Secondary上执行
    rs.reconfig({_id:"rs0", version:2, members:[{_id:1, host:"single-node:27017"}]}, {force:true})

六、与传统数据库对比

特性 MongoDB副本集 MySQL主从复制
故障切换 自动选举(秒级) 需手动提升从库
数据一致性 最终一致性+可调强度 依赖半同步复制配置
读写分离 原生支持readPreference 需中间件实现
网络分区容忍 优先保证可用性(AP) 优先保证一致性(CP)
相关推荐
qixiang201314 小时前
mysql和mongodb
数据库·mysql·mongodb
植物系青年15 小时前
前端玩数据库 👏 MongoDB/Mongoose 入门指南(下)
前端·mongodb·mongoose
植物系青年15 小时前
前端玩数据库 👏 MongoDB/Mongoose 入门指南(上)
前端·mongodb·mongoose
kikyo哎哟喂17 小时前
MongoDB常见面试题总结(上)
数据库·mongodb
!!!5251 天前
Spring Boot 整合 MongoDB:分页查询详解 (新手友好)
spring boot·后端·mongodb
爱的叹息2 天前
Spring Boot 集成 MongoDB 时自动创建的核心 Bean 的详细说明及表格总结
spring boot·后端·mongodb
!!!5252 天前
Spring Boot MongoDB 分页工具类封装 (新手指南)
spring boot·后端·mongodb
!!!5252 天前
MongoDB 新手笔记
数据库·笔记·mongodb
Mr.Java.2 天前
Spring Boot MongoDB自定义连接池配置
java·spring boot·后端·mongodb