Skip to content

MongoDB 副本集角色

主节点(Primary)

主节点功能

写操作处理

  • 接收并处理所有客户端写请求
  • 将写操作记录到 oplog(操作日志)
  • 确保写操作的原子性和持久性
  • 向客户端返回写操作结果

数据同步管理

  • 维护与所有从节点的连接
  • 向从节点发送 oplog 记录
  • 监控从节点的同步状态
  • 处理从节点的同步请求

选举参与

  • 在初始选举中参与竞选
  • 当自身不可用时触发重新选举
  • 支持强制重新配置

主节点选举

选举触发条件

  • 副本集初始化
  • 主节点故障或网络中断
  • 主节点主动降级
  • 副本集配置变更

选举过程

  1. 从节点检测到主节点不可用
  2. 从节点发起选举请求
  3. 所有投票节点进行投票
  4. 获得多数票的节点成为新主节点
  5. 新主节点通知所有节点

选举条件

  • 节点必须是健康的
  • 节点必须具有最新的 oplog
  • 节点必须能够与大多数节点通信
  • 节点必须具有选举权

从节点(Secondary)

从节点功能

数据复制

  • 从主节点复制 oplog
  • 应用 oplog 到本地数据库
  • 维护与主节点的数据一致性
  • 支持不同的复制延迟设置

读操作支持

  • 默认情况下不处理读请求
  • 可以配置为接收读请求
  • 支持多种读偏好设置
  • 提供数据冗余和高可用性

选举参与

  • 参与选举投票
  • 可以被选举为新主节点
  • 监控主节点状态

从节点配置

读偏好设置

javascript
// 连接字符串配置
mongodb://localhost:27017,localhost:27018,localhost:27019/?readPreference=secondary

// 客户端代码配置
db = db.getSiblingDB('test');
db.collection('users').find().readPref('secondary');

复制延迟配置

javascript
// 设置延迟节点
cfg = rs.conf();
cfg.members[2].secondaryDelaySecs = 3600; // 延迟1小时
cfg.members[2].hidden = true;
rs.reconfig(cfg);

隐藏节点配置

javascript
// 设置隐藏节点
cfg = rs.conf();
cfg.members[2].hidden = true;
rs.reconfig(cfg);

仲裁节点(Arbiter)

仲裁节点功能

选举投票

  • 参与选举投票,但不参与竞选
  • 帮助副本集在偶数节点情况下达成多数票
  • 不存储任何数据,仅维护副本集配置

状态监控

  • 监控主节点状态
  • 向其他节点发送心跳
  • 参与副本集状态维护

仲裁节点部署

部署场景

  • 副本集节点数为偶数时
  • 需要降低硬件成本时
  • 跨数据中心部署时

部署方式

bash
# 启动仲裁节点
docker run -d \
  --name mongodb-arbiter \
  -p 27020:27017 \
  mongo:6.0 --replSet rs0 --smallfiles

# 添加仲裁节点到副本集
rs.addArb("localhost:27020")

注意事项

  • 仲裁节点不应与主节点部署在同一台服务器上
  • 仲裁节点不应与其他仲裁节点部署在同一台服务器上
  • 仲裁节点不需要大量的资源

特殊角色配置

延迟节点(Delayed)

延迟节点用途

  • 用于恢复误删除或误修改的数据
  • 提供时间窗口进行数据恢复
  • 用于测试和验证

配置方法

javascript
cfg = rs.conf();
cfg.members[2].secondaryDelaySecs = 7200; // 延迟2小时
cfg.members[2].hidden = true;
cfg.members[2].priority = 0; // 不参与竞选
rs.reconfig(cfg);

使用场景

  • 恢复误删除的集合或数据库
  • 恢复误修改的数据
  • 测试灾难恢复流程

隐藏节点(Hidden)

隐藏节点用途

  • 用于备份和ETL操作
  • 用于监控和分析
  • 用于延迟节点

配置方法

javascript
cfg = rs.conf();
cfg.members[2].hidden = true;
cfg.members[2].priority = 0;
rs.reconfig(cfg);

特点

  • 对客户端不可见
  • 不参与选举
  • 仍参与数据复制

非投票节点

非投票节点用途

  • 增加副本集节点数超过7个时
  • 用于只读副本
  • 用于备份节点

配置方法

javascript
cfg = rs.conf();
cfg.members[7].votes = 0; // 设置为非投票节点
rs.reconfig(cfg);

注意事项

  • 副本集最多支持50个节点
  • 最多支持7个投票节点
  • 非投票节点不参与选举

角色管理命令

查看角色状态

查看副本集状态

javascript
rs.status()

查看节点配置

javascript
rs.conf()

查看节点角色

javascript
// 连接到节点
use admin
// 查看当前节点角色
db.runCommand({ isMaster: 1 })

修改角色配置

修改节点优先级

javascript
cfg = rs.conf();
cfg.members[0].priority = 2; // 提高主节点优先级
cfg.members[1].priority = 1; // 设置从节点优先级
rs.reconfig(cfg);

添加节点

javascript
// 添加从节点
rs.add("localhost:27018")

// 添加带配置的节点
rs.add({
  host: "localhost:27018",
  priority: 1,
  votes: 1
})

// 添加仲裁节点
rs.addArb("localhost:27020")

移除节点

javascript
// 移除节点
rs.remove("localhost:27018")

// 移除仲裁节点
rs.remove("localhost:27020")

角色最佳实践

生产环境配置

节点数量

  • 建议使用奇数个节点(3、5或7个)
  • 避免使用偶数个节点,除非添加仲裁节点
  • 考虑业务的可用性要求

角色分配

  • 至少配置1个主节点和2个从节点
  • 仅在必要时使用仲裁节点
  • 配置适当的优先级,避免频繁选举
  • 考虑跨数据中心部署

资源配置

  • 主节点需要更多的CPU和内存资源
  • 从节点需要足够的磁盘空间
  • 仲裁节点资源需求较低

性能优化

读操作分布

  • 使用读偏好将读操作分发到从节点
  • 避免所有读操作集中在主节点
  • 根据应用需求选择合适的读偏好

复制优化

  • 确保网络带宽足够支持复制
  • 配置适当的复制延迟
  • 监控复制延迟,及时处理延迟问题

选举优化

  • 配置适当的心跳间隔
  • 设置合理的选举超时时间
  • 避免频繁的配置变更

常见问题(FAQ)

Q1: 副本集最少需要多少个节点?

A1: 副本集最少需要1个节点,但生产环境建议至少3个节点(1个主节点,2个从节点)。单节点副本集不提供高可用性,仅用于测试。

Q2: 什么时候需要使用仲裁节点?

A2: 当副本集节点数为偶数时,需要添加仲裁节点以确保能够形成多数票。例如,2个节点的副本集需要1个仲裁节点,4个节点的副本集需要1个仲裁节点。

Q3: 主节点故障后,副本集会自动选举新主节点吗?

A3: 是的,当主节点故障或不可用时,副本集会自动触发选举,从可用的从节点中选举新主节点。选举过程通常在几秒钟内完成。

Q4: 如何防止某个节点被选举为主节点?

A4: 可以通过设置节点的优先级为0来防止其被选举为主节点:

javascript
cfg = rs.conf();
cfg.members[2].priority = 0;
rs.reconfig(cfg);

Q5: 隐藏节点有什么用?

A5: 隐藏节点对客户端不可见,主要用于:

  • 备份和ETL操作
  • 监控和分析
  • 延迟节点
  • 测试环境

Q6: 如何查看当前主节点是谁?

A6: 可以通过以下命令查看当前主节点:

javascript
rs.status().members.find(m => m.stateStr === "PRIMARY").name

Q7: 副本集最多支持多少个节点?

A7: 副本集最多支持50个节点,但最多只有7个节点可以参与选举投票。超过7个节点的副本集需要将额外的节点配置为非投票节点。

Q8: 延迟节点的延迟时间应该设置为多少?

A8: 延迟时间取决于业务需求,建议设置为:

  • 至少1小时,以便有足够的时间发现和恢复误操作
  • 不超过24小时,避免延迟节点与主节点差距过大
  • 根据数据变更频率和业务SLA调整