MongoDB: 副本集(高可用性)

如何配置高可用性的副本集

副本集是由一组 MongoDB 节点组成,通过在多台服务器之间复制数据,实现高可用性和性能提升。使用副本集,即使某个节点发生故障,您的数据库依然可用,同时通过分担负载,可以处理更多的请求。

包含 3 个节点的副本集示意图包含 3 个节点的副本集示意图

在高可用性架构下,如果某个节点离线,您的数据依然可以通过其他节点访问。性能方面也会有所提升,因为所有写操作都会发送到主节点(primary),而读操作则可以分布到各个从节点(secondary)。

如果您是首次接触副本集,建议参考 MongoDB 官方文档 以获取更多背景信息。

要搭建副本集,您至少需要三台 MongoDB 节点:

  1. 一个节点作为 primary,负责所有写操作,并且默认也处理读操作。
  2. 其他节点为 secondary,它们会几乎实时地从 primary 节点同步数据。

如果某个 secondary 节点不可用,您的应用依然可以正常运行。当该节点重新加入集群时,会自动同步缺失的数据,与副本集的其他节点保持一致。

如果 primary 节点发生故障,副本集会自动发起选举,选出新的 primary。这个过程通常需要大约 10 秒。在此期间,副本集处于只读状态。新 primary 选举完成后,所有操作会恢复正常。

选举过程示意图选举过程示意图

要在 Stackhero 上创建副本集,您至少需要三台 MongoDB 实例。以下是详细步骤:

  1. 在 Stackhero 控制台启动三台(或更多)MongoDB 实例。
  2. 实例启动后,在控制台更新它们的配置:
    1. 为每个实例设置相同的管理员密码。
    2. 启用 激活副本集 选项。
    3. 选择一个副本集名称密钥,所有节点需保持一致。(请注意:副本集名称创建后无法更改。如果不确定,rs-1 是一个不错的默认值。)

请确保所有实例的配置完全一致(管理员密码、副本集名称和副本集密钥)。

配置保存后,您需要在 MongoDB 内部定义副本集的所有成员。操作方法如下:

  1. 使用以下命令通过 Mongo CLI 连接:
mongo --quiet mongodb://admin@<XXXXXX>.stackhero-network.com/?tls=true

如果您尚未安装 Mongo CLI,可以使用官方 Docker 镜像,命令如下:

> docker run -it mongo /bin/bash

该命令会打开一个 shell,您可以直接在其中运行 Mongo 命令。

  1. 连接后,使用以下命令初始化副本集。请将 _id 替换为您选择的副本集名称,并根据实际情况修改成员主机名:
rs.initiate({
   _id: "rs-1",
   members: [
      { _id: 0, host: "<XXXXXX>.stackhero-network.com:27017" },
      { _id: 1, host: "<XXXXXX>.stackhero-network.com:27017" },
      { _id: 2, host: "<XXXXXX>.stackhero-network.com:27017" }
   ]
})

如果命令执行成功,您会看到类似 { "ok" : 1 } 的响应。

  1. 如需查看副本集配置,可运行:
rs.conf()

只需在其中一个节点上应用该配置,其他节点会自动同步更新。

现在,您的 MongoDB 副本集应该已经成功运行。

为了方便您监控副本集状态,我们开发了一个 Node.js 脚本,每秒检查一次副本集状态。您可以在我们的 GitHub 仓库 找到该脚本。

脚本截图脚本截图

如果遇到此错误,通常是因为未启用 TLS 加密。您可以在连接 URL 中添加 tls=true 参数来解决。例如:

mongodb://admin:PASSWORD@<XXXXXX>.stackhero-network.com:27017/admin?tls=true