MongoDB入门学习教程,从入门到精通,MongoDB创建副本集知识点梳理(10)

创建副本集知识点梳理

1. 复制简介

1.1 副本集的概念

副本集(Replica Set)是MongoDB的核心高可用机制,由一组维护相同数据集的mongod实例组成,提供:

  • 数据冗余:多个节点保存相同数据,防止单点故障
  • 高可用性:主节点故障时自动选举新主节点
  • 读写分离:读请求可分发到从节点,分担主节点压力
  • 灾难恢复:从节点可切换为主节点,或用于数据恢复

1.2 副本集架构

一个标准的副本集由以下角色组成:

角色 数量 功能描述
主节点(Primary) 1个 接收所有写操作,记录操作日志(oplog),是副本集的核心
从节点(Secondary) 1个或多个 异步复制主节点的oplog并应用,可参与选举和提供读服务
仲裁节点(Arbiter) 可选 不存储数据,仅参与选举投票,用于满足奇数票数要求

节点数量建议

  • 生产环境至少部署3个数据节点,或2个数据节点+1个仲裁节点
  • 副本集节点总数应为奇数,确保选举时能获得多数票(majority

1.3 数据复制机制

  • 异步复制:从节点通过异步方式从主节点拉取oplog并重放,默认存在秒级延迟
  • 同步复制 :可通过 writeConcern: majority 实现同步确认
  • Oplog:主节点的操作日志,记录所有写操作,用于从节点同步和故障恢复

1.4 选举机制

当主节点不可达时,副本集触发选举:

  • 选举触发条件:主节点心跳超时(默认10秒)、节点启动、手动触发
  • 选举算法:基于Raft协议(MongoDB 3.2+)
  • 选举因素:优先级(priority)、optime(最新操作)、网络连接

2. 建立副本集(一)

2.1 环境准备

基础配置要求

  • 至少3个节点(或2节点+仲裁者)
  • 所有节点时间同步(使用NTP服务)
  • 主机名可解析(使用DNS或hosts文件)
  • 网络互通,防火墙开放指定端口

2.2 启动单节点实例

每个副本集成员以独立的mongod进程启动,关键配置参数:

yaml 复制代码
# mongod.conf - 节点1配置
systemLog:
  destination: file
  path: /var/log/mongodb/mongod1.log
  logAppend: true
storage:
  dbPath: /data/mongodb/node1
  journal:
    enabled: true
net:
  bindIp: 0.0.0.0
  port: 27017
replication:
  replSetName: "rs0"        # 副本集名称,所有节点必须一致
processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod1.pid

启动命令

bash 复制代码
mongod --config /etc/mongod.conf

2.3 初始化副本集

连接到任意一个节点,执行副本集初始化:

javascript 复制代码
// 连接到主节点(或任意节点)
mongo --host 192.168.1.10 --port 27017

// 定义副本集配置
rsconf = {
  _id: "rs0",                // 副本集名称,必须与配置一致
  members: [
    { _id: 0, host: "host1:27017" },
    { _id: 1, host: "host2:27017" },
    { _id: 2, host: "host3:27017" }
  ]
}

// 初始化副本集
rs.initiate(rsconf)

// 查看副本集状态
rs.status()

2.4 初始化后的状态变化

  • STARTUPSTARTUP2:节点启动,加载配置
  • RECOVERING:恢复状态,正在应用oplog或进行数据同步
  • SECONDARY:从节点,正常提供服务
  • PRIMARY:主节点,选举产生

3. 网络注意事项

3.1 网络连接要求

项目 要求 说明
端口配置 所有节点端口互通 默认27017,可自定义
网络延迟 < 50ms(推荐) 高延迟影响同步效率和选举速度
带宽 足够传输oplog oplog增长速率取决于写入负载
防火墙 开放所需端口 包括内部通信和客户端连接
DNS解析 所有节点可互相解析 使用静态IP或内部DNS

3.2 网络故障处理

  • 心跳机制:节点间每2秒发送一次心跳,10秒未响应则标记为不可达
  • 网络分区(Split Brain):通过多数选举机制防止出现多个主节点
  • 自动恢复:网络恢复后,节点自动重新加入副本集并追赶oplog

3.3 网络配置最佳实践

  1. 使用专用网络VPC隔离副本集通信
  2. 配置hosts文件确保主机名解析正确
  3. 使用多个网络接口分离客户端流量和副本集内部流量
  4. 配置TCP keepalive参数,防止防火墙断开长连接

4. 安全注意事项

4.1 认证与授权

启用认证

yaml 复制代码
security:
  authorization: enabled
  keyFile: /opt/mongodb/keyfile  # 副本集内部认证

创建管理员用户

javascript 复制代码
use admin
db.createUser({
  user: "admin",
  pwd: "securePassword",
  roles: [{ role: "root", db: "admin" }]
})

4.2 内部认证

  • KeyFile机制:副本集成员使用相同的KeyFile进行内部认证
  • 生成KeyFileopenssl rand -base64 756 > /opt/mongodb/keyfile
  • 权限设置chmod 400 /opt/mongodb/keyfile

4.3 网络隔离

  • 绑定IPbindIp 配置为内网IP,避免暴露到公网
  • 防火墙规则:仅允许信任IP访问MongoDB端口
  • VPN/专线:跨数据中心部署时使用安全隧道

4.4 TLS/SSL加密

yaml 复制代码
net:
  tls:
    mode: requireTLS
    certificateKeyFile: /etc/ssl/mongodb.pem
    CAFile: /etc/ssl/ca.pem
    allowConnectionsWithoutCertificates: false

4.5 安全最佳实践

类别 最佳实践
最小权限 使用角色授权,遵循最小权限原则
审计日志 启用审计功能,记录关键操作
定期更新 保持MongoDB版本最新,及时修复安全漏洞
备份加密 备份文件加密存储
传输加密 启用TLS加密所有数据传输

5. 建立副本集(二)

5.1 向现有副本集添加节点

添加新数据节点

javascript 复制代码
// 添加普通从节点
rs.add("host4:27017")

// 添加仲裁节点
rs.addArb("host4:27017")

// 指定优先级添加
rs.add({ host: "host4:27017", priority: 1, votes: 1 })

5.2 初始化数据同步

新节点加入后的数据同步方式:

同步方式 适用场景 特点
初始同步 新节点首次加入 从其他节点全量拷贝数据,自动完成
增量同步 节点重启后 从oplog拉取缺失操作,快速追赶上
手动同步 数据量极大时 使用mongodump/mongorestore或文件快照方式

初始同步过程

  1. 节点进入STARTUP2状态
  2. 选择同步源(默认从主节点或最近节点)
  3. 克隆所有数据库文件
  4. 应用同步期间的oplog
  5. 转换为SECONDARY状态

5.3 配置优先级和选举权重

javascript 复制代码
// 调整节点配置
var cfg = rs.conf()
cfg.members[0].priority = 2    // 优先级越高,越可能成为主节点
cfg.members[1].priority = 1
cfg.members[2].priority = 0    // 优先级0节点永远不能成为主节点
rs.reconfig(cfg)

5.4 添加延迟节点

javascript 复制代码
// 添加延迟1小时的从节点(用于误操作恢复)
rs.add({
  host: "host4:27017",
  priority: 0,
  hidden: true,      // 隐藏节点,不接收读请求
  slaveDelay: 3600   // 延迟秒数
})

6. 观察副本集

6.1 常用管理命令

命令 功能 示例
rs.status() 查看副本集详细状态 成员健康度、角色、optime
rs.conf() 查看副本集配置 成员列表、优先级、心跳配置
rs.isMaster() 查看主节点信息 当前主节点、是否为主节点
db.isMaster() 同 rs.isMaster() 快速判断节点角色
db.printReplicationInfo() 查看oplog信息 大小、时间范围
db.printSlaveReplicationInfo() 查看从节点同步延迟 各从节点的同步状态

6.2 关键指标解读

从 rs.status() 输出的关键字段

  • stateStr:节点状态(PRIMARY/SECONDARY/RECOVERING等)
  • health:健康状态(1健康,0异常)
  • optime:当前节点的最新操作时间戳
  • optimeDate:optime对应的可读时间
  • syncingTo:从节点正在从哪个节点同步
  • lastHeartbeat:上次心跳时间
  • lastHeartbeatRecv:上次收到心跳时间

6.3 监控与告警

需要监控的核心指标:

  • 节点可用性:各节点健康状态
  • 复制延迟:从节点滞后主节点的时间
  • Oplog窗口:oplog可保留的时间范围,低于24小时需告警
  • 选举次数:异常选举可能表示网络问题或节点不稳定
  • 主节点切换频率:频繁切换影响业务

7. 更改副本集配置

7.1 重新配置副本集

javascript 复制代码
// 1. 获取当前配置
var cfg = rs.conf()

// 2. 修改配置(例如:修改心跳超时时间)
cfg.settings = {
  heartbeatTimeoutSecs: 15,      // 心跳超时,默认10秒
  electionTimeoutMillis: 15000    // 选举超时,默认10秒
}

// 3. 应用配置(force参数用于处理无法达到多数的情况)
rs.reconfig(cfg)
// 或强制重新配置(慎用)
rs.reconfig(cfg, { force: true })

7.2 常见配置修改场景

修改场景 操作示例 注意事项
删除节点 rs.remove("host1:27017") 确保删除后剩余节点满足多数选举
修改优先级 cfg.members[0].priority = 3 优先级0节点不能成为主节点
调整为隐藏节点 cfg.members[1].hidden = true 隐藏节点不接受读请求
设置延迟节点 cfg.members[2].slaveDelay = 7200 延迟节点需设置priority=0
调整投票数 cfg.members[0].votes = 1 投票数可为0或1
修改oplog大小 需重新配置或使用 replSetResizeOplog 修改后需要重新同步

7.3 动态调整oplog大小

javascript 复制代码
// MongoDB 3.6+ 支持动态调整
db.adminCommand({
  replSetResizeOplog: 1,
  size: 10240  // 单位:MB,这里设置为10GB
})

7.4 维护模式

javascript 复制代码
// 将节点设置为维护模式(接收不到读请求)
db.adminCommand({ replSetMaintenance: true })

// 退出维护模式
db.adminCommand({ replSetMaintenance: false })

8. 如何设计副本集

8.1 副本集设计原则

设计原则 说明
奇数节点 保证选举时能获得多数票,避免平局
跨故障域部署 节点分布在不同机架、可用区或数据中心
至少3个数据节点 2个数据节点+仲裁者也能工作,但推荐3个数据节点
考虑网络分区 避免将多数节点集中在同一网络段
合理的优先级 将性能更好的节点设置更高优先级

8.2 常见部署架构

单数据中心部署

复制代码
[Primary] --- [Secondary1]
   |              |
   +----[Secondary2]
  • 优势:低延迟,管理简单
  • 风险:数据中心故障导致服务不可用

双数据中心部署

复制代码
数据中心A             数据中心B
[Primary]          [Secondary2]
[Secondary1]       [Arbiter]    (可选)
  • 优势:提高可用性
  • 风险:网络分区可能导致选举问题

三数据中心部署(推荐)

复制代码
数据中心A          数据中心B          数据中心C
[Primary]         [Secondary1]      [Secondary2]
  • 优势:任意一个数据中心故障,仍保留多数节点
  • 最佳实践:至少3个数据节点分布在3个数据中心

8.3 跨地域部署考虑

  • 写关注 :使用 { w: "majority" } 确保数据跨地域持久化
  • 读偏好 :设置 readPreference: nearest 读取最近节点,降低延迟
  • 网络延迟:跨地域部署会增加写入延迟,需权衡一致性要求
  • 标签集:使用标签控制读写路由策略

8.4 容量规划

资源 规划建议
磁盘 数据量 × 3(数据+oplog+索引)+ 预留空间
内存 热数据集大小 + 索引大小 + 操作系统开销
CPU 根据并发量和写入负载评估,建议4核以上
网络 千兆以上网络,考虑复制流量

9. 成员配置选项

9.1 成员配置参数详解

参数 类型 默认值 说明
_id 整数 成员唯一标识,从0开始递增
host 字符串 主机名和端口
priority 浮点数 1 选举优先级,0-1000,0不能成为主节点
votes 整数 1 投票权,0或1,最多7个有投票权的节点
hidden 布尔值 false 隐藏节点,不响应读请求
slaveDelay 整数 0 延迟同步秒数,需配合priority=0
arbiterOnly 布尔值 false 是否为仲裁节点
buildIndexes 布尔值 true 是否创建索引,设置为false需配合priority=0
tags 对象 {} 标签,用于读写策略控制

9.2 节点类型及配置

节点类型 配置示例 用途
标准节点 { priority: 1, votes: 1 } 默认配置,可成为主节点并参与投票
高优先级节点 { priority: 2, votes: 1 } 更倾向于成为主节点,适合性能更好的机器
被动节点 { priority: 0, votes: 1 } 不成为主节点,但参与投票,适合备份节点
隐藏节点 { priority: 0, hidden: true } 不接收读请求,适合数据分析或备份
延迟节点 { priority: 0, slaveDelay: 3600, hidden: true } 保留历史数据,用于误操作恢复
仲裁节点 { arbiterOnly: true } 仅投票,不存储数据,节省资源
无索引节点 { buildIndexes: false, priority: 0 } 不创建索引,适用于只做备份的节点

9.3 标签集配置

配置标签

javascript 复制代码
var cfg = rs.conf()
cfg.members[0].tags = { "dc": "beijing", "rack": "A", "use": "prod" }
cfg.members[1].tags = { "dc": "beijing", "rack": "B", "use": "prod" }
cfg.members[2].tags = { "dc": "shanghai", "rack": "C", "use": "backup" }
rs.reconfig(cfg)

使用标签设置读偏好

javascript 复制代码
// 只读取北京机房的节点
db.collection.find().readPref("primaryPreferred", [
  { "dc": "beijing" }
])

使用标签设置写关注

javascript 复制代码
// 写入至少两个不同机房的节点
db.collection.insert(
  { data: "value" },
  { writeConcern: { w: "majority", wtimeout: 5000 } }
)

9.4 成员配置最佳实践

  1. 仲裁节点:部署在独立服务器,避免与数据节点共用
  2. 隐藏节点:用于备份和分析任务,减少对主节点压力
  3. 延迟节点:设置延迟时间为业务误操作可恢复的时间窗口(如8-24小时)
  4. 优先级设置:将性能更好、网络更稳定的节点设置更高优先级
  5. 标签策略:为节点打标签,实现精细化的读写路由控制

通过以上知识点的系统梳理,可以全面掌握MongoDB副本集的创建、配置、管理和优化方法,为构建高可用、高可靠的MongoDB生产环境奠定坚实基础。

相关推荐
老衲提灯找美女2 小时前
数据库事务
java·大数据·数据库
星幻元宇VR2 小时前
VR动感科普单车:让交通安全教育更真实、更有效
科技·学习·安全·生活·vr
会飞的大可2 小时前
Redis 竞品与替代方案选型可行性分析报告
数据库·redis·缓存
周杰伦的稻香2 小时前
PostgreSQL基础命令
数据库·postgresql
先做个垃圾出来………3 小时前
JSON序列化问题
数据库·json
我科绝伦(Huanhuan Zhou)3 小时前
InnoDB Undo Log 深度解析:从原理到实现(基于 MySQL 8.0)
数据库·mysql
jackiehome3 小时前
SQL数据库无法操作,日志文件损坏修复
数据库·sql·oracle
荒川之神3 小时前
ORACLE导入导出实验
数据库·oracle
执笔为剑3 小时前
利用逻辑备份修复误操作的库
数据库·kingbase