MongoDB: 副本集(高可用性)
如何配置高可用性的副本集
副本集是由一组 MongoDB 节点组成的集群,通过在多台服务器之间复制数据,实现高可用性和性能提升。使用副本集,即使某个节点发生故障,您的数据库依然可以访问,同时通过分担负载,能够处理更多的请求。
包含 3 个节点的副本集示意图
在高可用性架构下,如果某个节点离线,您的数据仍可通过其他节点访问。性能方面也会提升,因为所有写操作都会发送到主节点(primary),而读操作可以分散到各个从节点(secondary)。
如果您是首次接触副本集,建议查阅 MongoDB 官方文档 以获取更多背景信息。
副本集的工作原理
要搭建副本集,您至少需要三台 MongoDB 节点:
- 其中一个节点作为 primary,负责所有写操作,默认也处理读操作。
- 其他节点为 secondary,它们会几乎实时地从 primary 复制数据。
如果某个 secondary 节点不可用,您的应用依然可以正常运行。当该 secondary 节点重新加入集群时,会自动同步缺失的数据,与副本集的其他节点保持一致。
如果 primary 节点发生故障,副本集会自动发起选举,选出新的 primary。整个过程通常需要大约 10 秒。在此期间,副本集处于只读状态。新 primary 选举完成后,所有操作会恢复正常。
选举过程示意图
MongoDB 副本集快速入门
要在 Stackhero 上创建副本集,您至少需要三台 MongoDB 实例。操作步骤如下:
- 在 Stackhero 控制台启动三台(或更多)MongoDB 实例。
- 实例启动后,在控制台更新它们的配置:
- 为每个实例设置相同的管理员密码。
- 启用 激活副本集 选项。
- 选择一个副本集名称和密钥,所有节点需保持一致。(注意:副本集名称创建后无法更改。如果不确定,建议使用
rs-1作为默认值。)
请确保您的所有实例配置完全一致(管理员密码、副本集名称、副本集密钥)。
配置保存后,您需要在 MongoDB 内部定义副本集的所有成员。具体操作如下:
- 使用以下命令通过 Mongo CLI 连接:
mongo --quiet mongodb://admin@<XXXXXX>.stackhero-network.com/?tls=true
如果您尚未安装 Mongo CLI,可以使用官方 Docker 镜像,命令如下:
> docker run -it mongo /bin/bash
此命令会打开一个 shell,您可以直接在其中运行 Mongo 命令。
- 连接后,使用以下命令初始化副本集。请将
_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 } 的响应。
- 如需查看副本集配置,可执行:
rs.conf()
只需在一个节点上应用此配置,其他节点会自动同步。
现在,您的 MongoDB 副本集已经搭建完成并可正常运行。
检查 MongoDB 副本集状态
为了帮助您监控副本集状态,我们开发了一个 Node.js 脚本,每秒检查一次副本集状态。您可以在我们的 GitHub 仓库 找到该脚本。
脚本截图
故障排查
处理错误:“network error while attempting to run command 'isMaster' on host”
如果遇到此错误,通常是因为未启用 TLS 加密。您可以通过在连接 URL 中添加 tls=true 参数来解决。例如:
mongodb://admin:PASSWORD@<XXXXXX>.stackhero-network.com:27017/admin?tls=true