MongoDB Replica Set 中文教程

1. 核心概念

MongoDB Replica Set 是 MongoDB 官方提供的高可用性解决方案,由一组维护相同数据集的 MongoDB 实例组成。它通过主从复制和自动故障转移机制,确保 MongoDB 服务的持续可用性。

1.1 主要功能

  • 数据冗余:将数据复制到多个节点,提供数据冗余和高可用性
  • 自动故障转移:当主节点发生故障时,自动将一个从节点提升为新的主节点
  • 读写分离:可以将读操作分发到从节点,提高系统性能
  • 地理分布式部署:支持跨数据中心部署,提供灾备能力
  • 选举机制:基于 Raft 协议的选举机制,确保集群一致性

1.2 架构组成

  • 主节点(Primary):负责处理所有写操作和读操作(默认情况下)
  • 从节点(Secondary):复制主节点的数据,可用于处理读操作
  • 仲裁节点(Arbiter):不存储数据,仅参与选举过程,用于打破平局

1.3 选举机制

MongoDB Replica Set 使用基于 Raft 协议的选举机制:

  1. 当主节点不可用时,从节点会触发选举
  2. 每个节点会投票给一个候选节点
  3. 获得大多数投票的节点成为新的主节点
  4. 选举过程通常在 10 秒内完成

1.4 数据复制

主节点将操作记录写入 oplog(操作日志),从节点通过复制 oplog 来同步数据:

  1. 主节点执行写操作并记录到 oplog
  2. 从节点定期从主节点获取 oplog
  3. 从节点重放 oplog 中的操作,保持数据与主节点一致
  4. 从节点维护一个 oplog 时间戳,跟踪同步进度

2. 安装与配置

2.1 安装 MongoDB

2.1.1 在 Ubuntu/Debian 系统上安装

# 导入 MongoDB GPG 密钥
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -

# 添加 MongoDB 仓库
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

# 更新包列表
sudo apt update

# 安装 MongoDB
sudo apt install -y mongodb-org

# 启动 MongoDB 服务
sudo systemctl start mongod

# 设置 MongoDB 服务开机自启
sudo systemctl enable mongod

2.1.2 在 CentOS/RHEL 系统上安装

# 创建 MongoDB 仓库文件
sudo tee /etc/yum.repos.d/mongodb-org-7.0.repo << 'EOF'
[mongodb-org-7.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-7.0.asc
EOF

# 安装 MongoDB
sudo yum install -y mongodb-org

# 启动 MongoDB 服务
sudo systemctl start mongod

# 设置 MongoDB 服务开机自启
sudo systemctl enable mongod

2.1.3 从源码编译安装

# 克隆 MongoDB 源码
git clone https://github.com/mongodb/mongo.git
cd mongo

# 切换到稳定版本
git checkout r7.0.0

# 安装依赖
sudo apt install -y build-essential libssl-dev libcurl4-openssl-dev liblzma-dev

# 编译 MongoDB
scons \
    --prefix=/usr/local/mongodb \
    --disable-warnings-as-errors \
    --ssl

# 安装 MongoDB
sudo scons install --prefix=/usr/local/mongodb

# 添加 MongoDB 到 PATH
echo 'export PATH=/usr/local/mongodb/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

2.2 配置 MongoDB Replica Set

2.2.1 准备配置文件

创建 3 个 MongoDB 实例的配置文件(1 主 2 从):

mongod-27017.conf

# 系统日志配置
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod-27017.log

# 存储配置
storage:
  dbPath: /var/lib/mongodb/27017
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1

# 进程控制
processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod-27017.pid

# 网络配置
net:
  port: 27017
  bindIp: 0.0.0.0

# 复制集配置
replication:
  replSetName: rs0

# 安全配置
security:
  authorization: enabled
  keyFile: /etc/mongodb/keyfile

mongod-27018.conf

# 系统日志配置
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod-27018.log

# 存储配置
storage:
  dbPath: /var/lib/mongodb/27018
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1

# 进程控制
processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod-27018.pid

# 网络配置
net:
  port: 27018
  bindIp: 0.0.0.0

# 复制集配置
replication:
  replSetName: rs0

# 安全配置
security:
  authorization: enabled
  keyFile: /etc/mongodb/keyfile

mongod-27019.conf

# 系统日志配置
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod-27019.log

# 存储配置
storage:
  dbPath: /var/lib/mongodb/27019
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1

# 进程控制
processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod-27019.pid

# 网络配置
net:
  port: 27019
  bindIp: 0.0.0.0

# 复制集配置
replication:
  replSetName: rs0

# 安全配置
security:
  authorization: enabled
  keyFile: /etc/mongodb/keyfile

2.2.2 创建数据目录和日志目录

# 创建数据目录
sudo mkdir -p /var/lib/mongodb/27017 /var/lib/mongodb/27018 /var/lib/mongodb/27019

# 创建日志目录
sudo mkdir -p /var/log/mongodb

# 创建运行目录
sudo mkdir -p /var/run/mongodb

# 设置权限
sudo chown -R mongodb:mongodb /var/lib/mongodb /var/log/mongodb /var/run/mongodb

2.2.3 创建 keyFile

keyFile 用于在复制集成员之间进行身份验证:

# 创建 keyFile 目录
sudo mkdir -p /etc/mongodb

# 生成 keyFile
sudo openssl rand -base64 756 > /etc/mongodb/keyfile

# 设置权限
sudo chmod 400 /etc/mongodb/keyfile

# 设置所有者
sudo chown mongodb:mongodb /etc/mongodb/keyfile

2.2.4 启动 MongoDB 实例

# 启动第一个实例
sudo -u mongodb mongod --config /etc/mongod-27017.conf

# 启动第二个实例
sudo -u mongodb mongod --config /etc/mongod-27018.conf

# 启动第三个实例
sudo -u mongodb mongod --config /etc/mongod-27019.conf

2.2.5 初始化复制集

# 连接到第一个实例
mongo --port 27017

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

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

2.2.6 创建管理员用户

# 连接到主节点
mongo --port 27017

# 切换到 admin 数据库
use admin

# 创建管理员用户
db.createUser({
  user: "admin",
  pwd: "your_strong_password",
  roles: [
    { role: "root", db: "admin" }
  ]
})

# 验证用户创建成功
db.auth("admin", "your_strong_password")

3. 基本使用

3.1 连接到复制集

3.1.1 使用 mongo 命令行工具

# 连接到复制集(会自动连接到主节点)
mongo "mongodb://admin:your_strong_password@localhost:27017,localhost:27018,localhost:27019/admin?replicaSet=rs0"

# 连接到特定节点
mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin

3.1.2 使用 Node.js 客户端

const { MongoClient } = require('mongodb');

// 复制集连接字符串
const uri = 'mongodb://admin:your_strong_password@localhost:27017,localhost:27018,localhost:27019/admin?replicaSet=rs0';

// 创建客户端
const client = new MongoClient(uri, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

// 连接到 MongoDB
async function connect() {
  try {
    await client.connect();
    console.log('Connected to MongoDB Replica Set');
    
    // 获取数据库
    const db = client.db('test');
    
    // 执行操作
    // ...
    
  } catch (err) {
    console.error('Error connecting to MongoDB:', err);
  } finally {
    // 关闭连接
    await client.close();
  }
}

connect();

3.2 查看复制集状态

# 连接到主节点
mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin

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

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

# 查看从节点复制状态
rs.printSlaveReplicationInfo()

# 查看主节点状态
rs.printReplicationInfo()

3.3 数据操作

3.3.1 写操作

写操作会自动路由到主节点:

# 连接到复制集
mongo "mongodb://admin:your_strong_password@localhost:27017,localhost:27018,localhost:27019/admin?replicaSet=rs0"

# 切换到 test 数据库
use test

# 插入文档
db.users.insertOne({ name: "张三", age: 25, email: "zhangsan@example.com" })

# 更新文档
db.users.updateOne({ name: "张三" }, { $set: { age: 26 } })

# 删除文档
db.users.deleteOne({ name: "张三" })

3.3.2 读操作

默认情况下,读操作也会路由到主节点。可以通过设置 readPreference 来将读操作路由到从节点:

# 连接到复制集
mongo "mongodb://admin:your_strong_password@localhost:27017,localhost:27018,localhost:27019/admin?replicaSet=rs0"

# 切换到 test 数据库
use test

# 设置读偏好为从节点
db.getMongo().setReadPref("secondary")

# 执行读操作
db.users.find()

# 或者在连接字符串中指定读偏好
# mongo "mongodb://admin:your_strong_password@localhost:27017,localhost:27018,localhost:27019/admin?replicaSet=rs0&readPreference=secondary"

3.4 添加和移除节点

3.4.1 添加节点

# 连接到主节点
mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin

# 添加新节点
rs.add("localhost:27020")

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

3.4.2 移除节点

# 连接到主节点
mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin

# 移除节点
rs.remove("localhost:27020")

3.5 手动故障转移

# 连接到主节点
mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin

# 执行手动故障转移
rs.stepDown()

4. 高级功能

4.1 读写分离

通过设置 readPreference,可以实现读写分离,将读操作分发到从节点:

4.1.1 在连接字符串中设置

const uri = 'mongodb://admin:your_strong_password@localhost:27017,localhost:27018,localhost:27019/admin?replicaSet=rs0&readPreference=secondary';

4.1.2 在代码中设置

const client = new MongoClient(uri);
await client.connect();

// 获取数据库
const db = client.db('test');

// 设置读偏好
db.collection('users').find().readPreference('secondary').toArray();

4.2 延迟复制

延迟复制可以用于灾难恢复,当主节点发生错误时,可以从延迟的从节点恢复数据:

# 连接到主节点
mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin

# 配置延迟复制(延迟 1 小时)
cfg = rs.conf()
cfg.members[2].priority = 0  # 降低优先级,避免成为主节点
cfg.members[2].slaveDelay = 3600  # 延迟 3600 秒
rs.reconfig(cfg)

4.3 隐藏节点

隐藏节点不会接收客户端请求,可用于备份或报表:

# 连接到主节点
mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin

# 配置隐藏节点
cfg = rs.conf()
cfg.members[2].priority = 0  # 降低优先级
cfg.members[2].hidden = true  # 设置为隐藏节点
rs.reconfig(cfg)

4.4 标签感知路由

通过设置标签,可以将读操作路由到特定的节点:

# 连接到主节点
mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin

# 配置节点标签
cfg = rs.conf()
cfg.members[0].tags = { "dc": "us-east", "rack": "A" }
cfg.members[1].tags = { "dc": "us-east", "rack": "B" }
cfg.members[2].tags = { "dc": "us-west", "rack": "A" }
rs.reconfig(cfg)

# 设置读偏好标签
const client = new MongoClient(uri, {
  readPreference: 'secondary',
  readPreferenceTags: [{ "dc": "us-east" }]
});

4.5 复制集监控

4.5.1 使用 MongoDB Atlas

MongoDB Atlas 提供了全面的复制集监控功能,包括:

  • 节点状态监控
  • 复制延迟监控
  • 操作日志监控
  • 性能指标监控

4.5.2 使用命令行工具

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

# 查看复制延迟
rs.printSlaveReplicationInfo()

# 查看操作日志状态
db.adminCommand({ replSetGetStatus: 1 })

# 查看连接状态
db.serverStatus().connections

4.6 备份与恢复

4.6.1 使用 mongodump 和 mongorestore

# 从主节点备份
timestamp=$(date +%Y%m%d_%H%M%S)
mongodump --host "rs0/localhost:27017" --username admin --password your_strong_password --out "backup_$timestamp"

# 恢复数据
mongorestore --host "rs0/localhost:27017" --username admin --password your_strong_password "backup_$timestamp"

4.6.2 使用文件系统快照

如果使用支持快照的文件系统(如 LVM、ZFS),可以使用文件系统快照进行备份:

  1. 锁定数据库

    mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin
    use admin
    db.fsyncLock()
  2. 创建文件系统快照

    sudo lvcreate --snapshot --name mongodb_snap /dev/vg0/mongodb
  3. 解锁数据库

    mongo --port 27017 -u admin -p your_strong_password --authenticationDatabase admin
    use admin
    db.fsyncUnlock()
  4. 挂载快照并复制数据

    sudo mkdir -p /mnt/mongodb_snap
    sudo mount /dev/vg0/mongodb_snap /mnt/mongodb_snap
    sudo cp -r /mnt/mongodb_snap/* /backup/mongodb/
    sudo umount /mnt/mongodb_snap
    sudo lvremove --force /dev/vg0/mongodb_snap

5. 最佳实践

5.1 部署建议

  • 节点数量:建议至少部署 3 个节点(1 主 2 从),或 2 个节点加 1 个仲裁节点
  • 硬件配置:根据数据量和访问量选择合适的硬件配置,主节点和从节点配置应相同
  • 网络配置:确保节点之间网络畅通,网络延迟应尽可能低
  • 防火墙:确保开放必要的端口(默认 27017)
  • 部署位置:将节点部署在不同的物理机器或虚拟机上,避免单点故障
  • 地理分布:对于关键应用,考虑跨数据中心部署,提高灾备能力

5.2 性能优化

  • 内存配置:为 MongoDB 分配足够的内存,建议将 wiredTiger.cacheSizeGB 设置为系统内存的 50%
  • 存储配置:使用 SSD 存储提高性能,特别是对于写密集型应用
  • 索引优化:为常用查询创建合适的索引,避免全表扫描
  • 批量操作:使用批量操作减少网络往返时间
  • 连接池:使用连接池管理客户端连接,避免频繁创建和销毁连接
  • 读写分离:将读操作分发到从节点,提高系统整体性能

5.3 安全配置

  • 启用认证:启用 MongoDB 的认证机制,设置强密码
  • 使用 keyFile:在复制集成员之间使用 keyFile 进行身份验证
  • 限制访问:通过 bindIp 参数限制只接受特定 IP 的连接
  • 使用 TLS:在生产环境中启用 TLS 加密
  • 定期更新:及时更新 MongoDB 版本,修复安全漏洞
  • 权限管理:根据最小权限原则,为不同用户分配适当的角色

5.4 监控与维护

  • 监控指标:监控节点状态、复制延迟、内存使用、CPU 使用率、网络流量等指标
  • 日志分析:定期分析 MongoDB 日志,及时发现问题
  • 定期备份:制定合理的备份策略,确保数据安全
  • 容量规划:根据数据增长趋势,提前规划存储容量
  • 健康检查:定期执行 db.serverStatus() 和 db.stats() 检查数据库健康状态
  • 索引维护:定期重建索引,提高查询性能

6. 故障排查

6.1 常见问题

  • 主节点不可用:检查主节点状态,查看日志文件,确认是否有硬件或网络问题
  • 复制延迟过高:检查网络连接,确认从节点硬件配置是否足够,查看是否有大量写操作
  • 选举失败:检查节点数量是否足够,确认网络连接是否正常,查看日志文件中的选举相关信息
  • 数据不一致:检查复制状态,确认 oplog 是否正常,可能需要重新同步从节点
  • 连接问题:检查网络连接,确认 MongoDB 服务是否运行,检查防火墙设置
  • 性能问题:检查索引使用情况,确认硬件配置是否足够,查看是否有慢查询

6.2 排查工具

  • mongo 命令行工具:用于执行管理命令和查看状态
  • MongoDB Compass:图形化管理工具,提供可视化监控
  • MongoDB Atlas:云服务,提供全面的监控和管理功能
  • mongostat:实时监控 MongoDB 实例的性能指标
  • mongotop:监控集合级别的读写操作
  • 日志文件:包含详细的操作和错误信息

6.3 示例排查过程

问题:复制集出现复制延迟

排查步骤

  1. 查看复制状态

    rs.printSlaveReplicationInfo()
  2. 查看从节点日志

    tail -f /var/log/mongodb/mongod-27018.log
  3. 检查网络连接

    ping localhost
    telnet localhost 27017
  4. 检查主节点写操作

    mongotop --host localhost:27017 --username admin --password your_strong_password
  5. 检查从节点资源使用

    top -p $(pgrep -f mongod-27018)
    iostat -x
  6. 解决方法

    • 增加从节点硬件资源
    • 优化主节点写操作
    • 检查网络连接,减少网络延迟
    • 考虑使用分片集群分散写操作

7. 实用案例

7.1 构建高可用 MongoDB 集群

场景:构建一个高可用的 MongoDB 集群,用于存储用户数据和应用状态。

解决方案

  1. 部署架构

    • 3 个 MongoDB 节点(1 主 2 从)
    • 节点分布在 3 台不同的物理机器上
    • 每台机器配置相同的硬件资源
  2. 配置步骤

    • 在每台机器上安装 MongoDB
    • 配置 MongoDB 实例
    • 初始化复制集
    • 创建管理员用户
    • 配置客户端连接
  3. 客户端配置

    const { MongoClient } = require('mongodb');
    
    // 复制集连接字符串
    const uri = 'mongodb://admin:your_strong_password@server1:27017,server2:27017,server3:27017/admin?replicaSet=rs0';
    
    // 创建客户端
    const client = new MongoClient(uri, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      maxPoolSize: 100
    });
    
    // 连接到 MongoDB
    async function connect() {
      try {
        await client.connect();
        console.log('Connected to MongoDB Replica Set');
      } catch (err) {
        console.error('Error connecting to MongoDB:', err);
      }
    }
    
    // 存储用户数据
    async function saveUser(user) {
      try {
        const db = client.db('app');
        const result = await db.collection('users').insertOne(user);
        return result.insertedId;
      } catch (err) {
        console.error('Error saving user:', err);
        throw err;
      }
    }
    
    // 获取用户数据
    async function getUser(userId) {
      try {
        const db = client.db('app');
        return await db.collection('users').findOne({ _id: userId });
      } catch (err) {
        console.error('Error getting user:', err);
        throw err;
      }
    }
    
    // 更新用户数据
    async function updateUser(userId, updates) {
      try {
        const db = client.db('app');
        await db.collection('users').updateOne({ _id: userId }, { $set: updates });
      } catch (err) {
        console.error('Error updating user:', err);
        throw err;
      }
    }
    
    // 导出函数
    module.exports = {
      connect,
      saveUser,
      getUser,
      updateUser
    };
  4. 使用示例

    const mongoService = require('./mongo-service');
    
    // 启动时连接 MongoDB
    mongoService.connect();
    
    // 存储用户数据
    const userId = await mongoService.saveUser({
      name: '张三',
      age: 25,
      email: 'zhangsan@example.com',
      createdAt: new Date()
    });
    console.log('User created with ID:', userId);
    
    // 获取用户数据
    const user = await mongoService.getUser(userId);
    console.log('User data:', user);
    
    // 更新用户数据
    await mongoService.updateUser(userId, {
      age: 26,
      lastUpdated: new Date()
    });
    console.log('User updated successfully');

7.2 使用 MongoDB Replica Set 作为会话存储

场景:使用 MongoDB Replica Set 作为 Node.js 应用的会话存储,提高系统可用性。

解决方案

  1. 部署架构

    • 3 个 MongoDB 节点(1 主 2 从)
    • 节点分布在不同的可用区
  2. 安装依赖

    npm install express express-session connect-mongodb-session mongodb
  3. 实现代码

    const express = require('express');
    const session = require('express-session');
    const MongoDBStore = require('connect-mongodb-session')(session);
    const { MongoClient } = require('mongodb');
    
    const app = express();
    
    // 复制集连接字符串
    const uri = 'mongodb://admin:your_strong_password@server1:27017,server2:27017,server3:27017/admin?replicaSet=rs0';
    
    // 创建 MongoDB 客户端
    const client = new MongoClient(uri, {
      useNewUrlParser: true,
      useUnifiedTopology: true
    });
    
    // 连接到 MongoDB
    client.connect().then(() => {
      console.log('Connected to MongoDB Replica Set');
      
      // 创建会话存储
      const store = new MongoDBStore({
        uri: uri,
        collection: 'sessions'
      });
      
      // 处理存储错误
      store.on('error', function(error) {
        console.error('Session store error:', error);
      });
      
      // 配置会话中间件
      app.use(session({
        secret: 'your_secret_key',
        resave: false,
        saveUninitialized: false,
        store: store,
        cookie: {
          maxAge: 1000 * 60 * 60 * 24 // 24 小时
        }
      }));
      
      // 测试路由
      app.get('/', (req, res) => {
        if (req.session.views) {
          req.session.views++;
          res.send(`Views: ${req.session.views}`);
        } else {
          req.session.views = 1;
          res.send('First view!');
        }
      });
      
      // 启动服务器
      app.listen(3000, () => {
        console.log('Server listening on port 3000');
      });
    }).catch(err => {
      console.error('Error connecting to MongoDB:', err);
    });
  4. 使用示例

    • 启动应用:node app.js
    • 访问 http://localhost:3000/,会看到 "First view!"
    • 刷新页面,会看到 "Views: 2"
    • 重启应用,再次访问页面,会看到 "Views: 3"(会话数据已持久化)

7.3 实现 MongoDB 读写分离

场景:实现 MongoDB 的读写分离,提高系统整体性能。

解决方案

  1. 部署架构

    • 3 个 MongoDB 节点(1 主 2 从)
  2. 实现代码

    const { MongoClient } = require('mongodb');
    
    // 复制集连接字符串
    const uri = 'mongodb://admin:your_strong_password@localhost:27017,localhost:27018,localhost:27019/admin?replicaSet=rs0';
    
    // 创建客户端(用于写操作)
    const writeClient = new MongoClient(uri, {
      useNewUrlParser: true,
      useUnifiedTopology: true
    });
    
    // 创建客户端(用于读操作)
    const readClient = new MongoClient(uri, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      readPreference: 'secondary' // 优先从从节点读取
    });
    
    // 连接到 MongoDB
    async function connect() {
      try {
        await writeClient.connect();
        await readClient.connect();
        console.log('Connected to MongoDB Replica Set');
      } catch (err) {
        console.error('Error connecting to MongoDB:', err);
      }
    }
    
    // 写操作
    async function writeOperation() {
      try {
        const db = writeClient.db('app');
        const result = await db.collection('users').insertOne({
          name: '李四',
          age: 30,
          email: 'lisi@example.com'
        });
        console.log('Write operation successful:', result.insertedId);
        return result.insertedId;
      } catch (err) {
        console.error('Error in write operation:', err);
        throw err;
      }
    }
    
    // 读操作
    async function readOperation(userId) {
      try {
        const db = readClient.db('app');
        const user = await db.collection('users').findOne({ _id: userId });
        console.log('Read operation successful:', user);
        return user;
      } catch (err) {
        console.error('Error in read operation:', err);
        throw err;
      }
    }
    
    // 使用示例
    async function main() {
      await connect();
      
      // 执行写操作
      const userId = await writeOperation();
      
      // 执行读操作
      const user = await readOperation(userId);
      
      // 关闭连接
      await writeClient.close();
      await readClient.close();
    }
    
    main();
  3. 测试验证

    • 启动应用:node app.js
    • 查看日志输出,确认写操作和读操作都成功执行
    • 查看 MongoDB 从节点的日志,确认读操作被路由到从节点

8. 总结

MongoDB Replica Set 是构建高可用 MongoDB 集群的理想解决方案,通过主从复制和自动故障转移机制,提供了比单机 MongoDB 更高的可用性和可靠性。本教程详细介绍了 MongoDB Replica Set 的核心概念、部署配置、使用方法和最佳实践,帮助开发者快速掌握 MongoDB Replica Set 的使用技巧,构建稳定可靠的 MongoDB 高可用集群。

在实际应用中,应根据具体需求和场景,合理配置 MongoDB Replica Set 参数,确保系统的稳定性和性能。同时,定期进行集群维护和监控,及时发现和解决问题,确保 MongoDB Replica Set 持续稳定运行。

« 上一篇 Redis Cluster 中文教程 下一篇 » PostgreSQL 复制教程