Skip to content

复制集

复制集(Replica Set)是MongoDB实现高可用的核心机制。本章将介绍复制集的概念、架构、配置和管理方法。

复制集概述

什么是复制集

javascript
// 复制集是一组维护相同数据集的MongoDB实例

// 复制集的特点:
// 1. 数据冗余:多份数据副本,提高数据安全性
// 2. 高可用:自动故障转移,减少停机时间
// 3. 读写分离:读操作可以分散到从节点
// 4. 灾难恢复:数据备份和恢复

// 复制集成员角色:
// - Primary(主节点):处理所有写操作
// - Secondary(从节点):复制主节点数据,可处理读请求
// - Arbiter(仲裁节点):不存储数据,只参与选举投票

复制集架构

// 典型的三节点复制集架构
//
//     Primary (主节点)
//        |
//    +---+---+
//    |       |
// Secondary  Secondary
// (从节点)   (从节点)
//
// 数据流向:Primary -> Secondary
// 选举机制:Primary故障时,Secondary自动选举新的Primary

部署复制集

创建复制集

javascript
// 步骤1:启动MongoDB实例(指定replSet参数)

// 在配置文件中添加
// mongod.conf
replication:
  replSetName: "rs0"

// 或使用命令行参数
mongod --replSet rs0 --port 27017 --dbpath /data/rs0-0
mongod --replSet rs0 --port 27018 --dbpath /data/rs0-1
mongod --replSet rs0 --port 27019 --dbpath /data/rs0-2

// 步骤2:初始化复制集
rs.initiate({
    _id: "rs0",
    members: [
        { _id: 0, host: "localhost:27017" },
        { _id: 1, host: "localhost:27018" },
        { _id: 2, host: "localhost:27019" }
    ]
})

// 步骤3:查看复制集状态
rs.status()

复制集配置

javascript
// 查看复制集配置
rs.conf()

// 修改复制集配置
var config = rs.conf()
config.members[0].priority = 2  // 设置优先级
rs.reconfig(config)

// 添加成员
rs.add("localhost:27020")

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

// 移除成员
rs.remove("localhost:27020")

// 成员配置选项
{
    _id: 0,                    // 成员ID
    host: "localhost:27017",   // 主机地址
    priority: 1,               // 选举优先级(0-1000)
    hidden: false,             // 是否隐藏节点
    slaveDelay: 0,             // 从节点延迟秒数
    buildIndexes: true,        // 是否构建索引
    arbiterOnly: false,        // 是否为仲裁节点
    votes: 1                   // 投票权
}

复制集管理

查看状态

javascript
// 查看复制集状态
rs.status()

// 输出关键字段:
// - members: 成员列表
// - state: 成员状态
//   - PRIMARY: 主节点
//   - SECONDARY: 从节点
//   - STARTUP: 启动中
//   - RECOVERING: 恢复中
//   - ARBITER: 仲裁节点
// - health: 健康状态(1=正常,0=异常)
// - optime: 最后一次操作时间
// - lastHeartbeat: 最后心跳时间

// 查看复制集配置
rs.conf()

// 查看主节点信息
rs.isMaster()

// 查看从节点同步状态
rs.printSlaveReplicationInfo()

故障转移

javascript
// 手动降级主节点
rs.stepDown(60)  // 60秒内不能成为主节点

// 冻结节点(不参与选举)
rs.freeze(120)  // 冻结120秒

// 解冻节点
rs.freeze(0)

// 强制重新配置(当大多数节点不可用时)
rs.reconfig(config, { force: true })

同步管理

javascript
// 查看同步状态
db.printReplicationInfo()  // 主节点oplog信息
db.printSlaveReplicationInfo()  // 从节点同步延迟

// 调整oplog大小
db.adminCommand({
    replSetResizeOplog: 1,
    size: 10240  // MB
})

// 初始同步(从节点重新同步)
// 1. 停止从节点
// 2. 删除数据目录
// 3. 启动从节点(自动进行初始同步)

读写分离

读偏好设置

javascript
// 读偏好(Read Preference)决定读操作路由到哪个节点

// primary(默认):只从主节点读取
db.users.find().readPref("primary")

// primaryPreferred:优先主节点,主节点不可用时读从节点
db.users.find().readPref("primaryPreferred")

// secondary:只从从节点读取
db.users.find().readPref("secondary")

// secondaryPreferred:优先从节点,从节点不可用时读主节点
db.users.find().readPref("secondaryPreferred")

// nearest:读网络延迟最低的节点
db.users.find().readPref("nearest")

// 连接字符串中设置读偏好
mongodb://localhost:27017,localhost:27018,localhost:27019/?readPreference=secondary

写关注设置

javascript
// 写关注(Write Concern)决定写操作的确认级别

// w: 1 - 确认主节点写入(默认)
db.users.insertOne({ name: "张三" }, { w: 1 })

// w: "majority" - 确认大多数节点写入
db.users.insertOne({ name: "张三" }, { w: "majority" })

// w: 2 - 确认2个节点写入
db.users.insertOne({ name: "张三" }, { w: 2 })

// wtimeout: 写入超时时间
db.users.insertOne(
    { name: "张三" }, 
    { w: "majority", wtimeout: 5000 }
)

// j: true - 等待日志刷盘
db.users.insertOne(
    { name: "张三" }, 
    { w: 1, j: true }
)

本章小结

本章介绍了MongoDB复制集的相关知识:

  1. 复制集概述:理解复制集的概念和架构
  2. 部署复制集:学会创建和配置复制集
  3. 复制集管理:掌握状态查看、故障转移、同步管理
  4. 读写分离:学会设置读偏好和写关注

下一章,我们将学习分片,了解MongoDB的水平扩展能力。