一.介绍
在任务关键型应用程序中部署 MongoDB 数据库时,可以配置副本集以实现高可用性。副本集提供冗余和高可用性,由于没有单点故障,因此可减少灾难期间的停机时间。MongoDB 副本集的最低建议配置是一个主节点和两个辅助节点,但副本集最多可以有 50 个成员。应用程序仅写入主节点,辅助节点复制数据。如果主节点发生故障,副本集将举行选举以选择新的主节点。应用程序可以从辅助数据库读取数据,但不能写入它们。
本指南介绍如何创建 MongoDB 副本集。它在 Ubuntu 20.04 上进行了测试,但其他 Linux 发行版的步骤类似。
二.准备工作
您需要将三台服务器连接到同一个 Vultr VPC。每个服务器都应具有:
- 配置了 sudo 权限的非 root 用户
- MongoDB安装并使用密码保护
- 为清楚起见,本指南对服务器使用以下主机名和专用 IP 地址。您应该用您的值替换这些值。
- 主:服务器-1 – 10.0.0.1
- 辅助:服务器-2 – 10.0.0.2
- 辅助:服务器-3 – 10.0.0.3
三 配置主机文件
MongoDB建议使用DNS主机名而不是副本成员的IP地址。由于 Vultr VPC 是没有 DNS 的私有网络,因此请将私有 IP 地址和主机名添加到主机文件中。在每台服务器上重复这些步骤。
- 以非 root 用户身份通过 SSH 连接到服务器。
- 编辑主机文件。
$ sudo nano /etc/hosts
- 找到下面的行。
127.0.0.1 localhost
- 输入 IP 地址和主机名,如该行下所示。
127.0.0.1 localhost 10.0.0.1 server-1 10.0.0.2 server-2 10.0.0.3 server-3
- 保存并关闭文件。
四. 设置复制密钥
副本集中的所有服务器共享一个 base64 密钥。请按照以下步骤安装密钥。
使用该命令在其中一台服务器上生成新密钥。openssl
$ openssl rand -base64 756
你应该得到这样的块。复制此 base64 密钥。您将在以下步骤中使用它。
Yga80PbkHKptRRoONFCPaPzOCFpySgpwNHMA3JS179wyGCOIOYg/FUnDyiIhGe5D
YVQF3o+SliscBiKftsPZ5WBojRREcefAUHOqK7pVBOjT+oYuH6ltMGiDtH26XjVB
... truncated ...
yxJm+UjpN0n8V1pH1LrMJT4FC4Bw3L7vqSnxVbLRnQIiO2Y0ECfyPgepCCNIyuaP
mMSUJ8mmlq4jdfoAKvCspeliSQ/cqaxKfqaTWjzhsLk8eHbU
在每台服务器上重复这些步骤。
- 创建新的auth_key文件。
$ sudo nano /var/lib/mongodb/auth_key
- 粘贴您的 base64 密钥。
- 保存并关闭文件。
- 将权限设置为 400,使文件对文件所有者只读,对所有其他文件都被拒绝访问。
$ sudo chmod 400 /var/lib/mongodb/auth_key
- 将所有者和组更改为 mongodb。
$ sudo chown mongodb:mongodb /var/lib/mongodb/auth_key
五. 配置 MongoDB
在本部分中,你将配置共享密钥、网络接口和副本集名称。在每台服务器上重复这些小节。
5.1. 配置共享密钥
- 在编辑器中打开 mongod.conf 以执行以下步骤。
$ sudo nano /etc/mongod.conf
- 找到安全部分。
security: authorization: enabled #operationProfiling:
- 在授权:行下,添加键文件值,如下所示。
security: authorization: enabled keyFile: /var/lib/mongodb/auth_key #operationProfiling:
5.2. 配置网络接口
- 找到网络接口部分。
# network interfaces net: port: 27017 bindIp: 127.0.0.1
- 将环路接口 (127.0.0.1) 之后的相应服务器名称添加到每个服务器。例如:
在服务器 1 上:
# network interfaces net: port: 27017 bindIp: 127.0.0.1, server-1
在服务器 2 上:
# network interfaces net: port: 27017 bindIp: 127.0.0.1, server-2
在服务器 3 上:
# network interfaces net: port: 27017 bindIp: 127.0.0.1, server-3
5.3. 配置副本集名称
- 找到复制部分。
#replication:
- 从复制行中删除注释。在此下方,按所示添加。#
replSetName: "rs0"
replication: replSetName: "rs0"
- 在主节点上重新启动 MongoDB。
$ sudo systemctl restart mongod
- 在辅助节点上重新启动 MongoDB。
$ sudo systemctl restart mongod
六. 引导副本集
在本部分中,你将节点添加到副本集并引导复制过程。
- 在主节点上,登录到MongoDB。
$ mongosh -u your_admin_name -p --authenticationDatabase admin
- 输入您的管理员帐户的密码,然后按继续。ENTER
- 运行以下命令以添加副本集成员。
test> rs.initiate( { _id: "rs0", members: [ { _id: 0, host: "server-1" }, { _id: 1, host: "server-2" }, { _id: 2, host: "server-3" } ] })
- 当副本集启动时,应收到以下响应。请注意,提示符更改为 。
rs0 [direct: secondary] test>
{ ok: 1 } rs0 [direct: secondary] test>
- 创建示例company_db数据库。
rs0 [direct: secondary] test> use company_db
- 您应该会收到以下响应,提示更改为 。此成员现在是主节点。
rs0 [direct: primary] company_db>
switched to db company_db rs0 [direct: primary] company_db>
- 在company_db数据库的新员工集合中插入示例记录。
rs0 [direct: primary] company_db> db.employees.insertOne({ "staff_id" : 1, "staff_name" : "JOHN DOE", "phone" : "11111111" })
- 您应该得到下面的输出。
{ acknowledged: true, insertedId: ObjectId("621dcf1abdb5b0c5e59294d9") }
- 在每个辅助节点上,登录到MongoDB。
$ mongosh -u your_admin_name -p --authenticationDatabase admin
- 输入您的管理员帐户的密码,然后按继续。ENTER
- 您应该会看到下面的提示,显示成员是辅助节点。
rs0 [direct: secondary] test>
- 在每个辅助节点上,切换到company_db。
rs0 [direct: secondary] test> use company_db
- 应得到以下输出。
switched to db company_db
- 在每个辅助节点上运行以下命令,以允许它们接受读取命令。
rs0 [direct: secondary] company_db> db.getMongo().setReadPref('primaryPreferred')
- 列出员工集合中的文档。
rs0 [direct: secondary] company_db> db.employees.find()
- 您应该在每个辅助节点上获得以下输出,该输出显示副本集将数据复制到每个节点。
[ { _id: ObjectId("621dcf1abdb5b0c5e59294d9"), staff_id: 1, staff_name: 'JOHN DOE', phone: '11111111' } ]
- 尝试在任何辅助节点上添加新的员工记录。
rs0 [direct: secondary] company_db> db.employees.insertOne({ "staff_id" : 2, "staff_name" : "MARY ROE", "phone" : "22222222" })
- 该命令应失败。辅助节点是只读的。
MongoServerError: not primary
- 如果停止主服务器或主服务器脱机,副本集将选择其中一个辅助节点作为新的主节点。
$ sudo systemctl stop mongod