部署地理位置冗余的自管理副本集
Overview
本教程概述了在多个地点部署具有 节点的 副本集 的过程。本教程涉及三节点副本集和五节点副本集。如果副本集节点数为偶数,尽可能添加另一个数据承载节点,以部署奇数个投票节点。[ 1 ]
有关分布式副本集的更多信息,请参阅分布在两个或多个数据中心的副本集。另请参阅副本集部署架构和自管理复制参考。
[1] | ( 1 , 2 )如果情况不允许增加另一个数据承载节点,且投票节点数量为偶数,则可以改为添加仲裁节点。有关使用仲裁节点时的注意事项,请参阅副本集仲裁节点。 |
Considerations
架构
在生产中,将副本集的每个成员部署到其自己的计算机上。如果可能,请确保 MongoDB 监听默认端口 27017
。
有关详细信息,请参阅《副本集部署架构》。
主机名
重要
要避免因 IP 地址变更而更新配置,请使用 DNS 主机名而非 IP 地址。在配置副本集成员或分片集群成员时,使用 DNS 主机名而非 IP 地址尤为重要。
在水平分割网络配置下,请使用主机名而非 IP 地址来配置集群。从 MongoDB 5.0 开始,仅配置了 IP 地址的节点将无法通过启动验证,因而不会启动。
IP 绑定
使用 --bind_ip
选项确保 MongoDB 在配置地址监听来自应用程序的连接。
警告
将实例绑定到可公开访问的 IP 地址之前,必须保护集群免遭未经授权的访问。有关安全建议的完整列表,请参阅自管理部署的安全清单。至少应考虑启用身份验证和强化网络基础设施。
MongoDB 二进制文件 mongod
和 mongos
默认绑定到本地主机。如果为此二进制文件设置了 net.ipv6
配置文件设置或 --ipv6
命令行选项,则该二进制文件还会绑定到本地主机 IPv6 地址。
默认情况下,绑定到本地主机的 mongod
和 mongos
只接受来自同一计算机上运行的客户端的连接。这种绑定行为包括 mongosh
以及副本集或分片集群的其他成员。远程客户端无法连接到仅绑定到本地主机的二进制文件。
要覆盖默认绑定并绑定到其他 IP 地址,请使用 net.bindIp
配置文件设置或 --bind_ip
命令行选项来指定主机名或 IP 地址的列表。
警告
从 MongDB5.0 开始, 水平分割 DNS 仅配置了 IP 地址的节点无法启动验证并报告错误。请参阅disableSplitHorizonIPCheck
。
例如,以下 mongod
实例会绑定到本地主机和主机名 My-Example-Associated-Hostname
,而该主机名与 IP 地址 198.51.100.1
相关联:
mongod --bind_ip localhost,My-Example-Associated-Hostname
为了连接到此实例,远程客户端必须指定主机名或其关联的 IP 地址 198.51.100.1
:
mongosh --host My-Example-Associated-Hostname mongosh --host 198.51.100.1
连接
确保网络流量能在集中的所有节点和网络中的所有客户端之间安全传递。
请考虑以下内容:
建立虚拟专用网络。确保网络拓扑通过局域网路由单个站点内节点之间的所有流量。
配置访问控制,防止未知客户端连接到副本集。
配置网络连接和防火墙规则,以便仅允许在默认 MongoDB 端口上且仅来自部署内部的传入和传出数据包。请参阅《IP 绑定考虑因素》。
确保副本集中的每个成员都可以通过可解析的 DNS 或主机名进行访问。您应适当配置 DNS 名称或设置系统的 /etc/hosts
文件,以反映此配置。
每个成员均须能连接到所有其他成员。关于如何检查连接,请参阅《测试所有成员之间的连接》。
配置
在部署 MongoDB 之前创建 MongoDB 存储数据文件的目录。
在存储在 /etc/mongod.conf
或相关位置的配置文件中指定 mongod
配置。
有关配置选项的更多信息,请参阅自管理配置文件选项。
节点分布
如果可能,使用奇数个数据中心,并选择一种节点分布方式,以最大限度地保证即使丢失一个数据中心,剩余的副本集节点也能形成多数,或至少提供一份数据副本。
投票权节点
从不部署超过七名投票成员。
先决条件
对于本教程中的所有配置,请在单独的系统上部署每个副本集节点。虽然可以在单个系统上部署多个副本集节点,但这样做会降低副本集的冗余和容量。这种部署通常用于测试目的。
本教程假设您已在将成为副本集一部分的每个系统上安装了 MongoDB。如果您尚未安装 MongoDB,请参阅安装教程。
步骤
部署地理上冗余的三节点副本集
重要
要避免因 IP 地址变更而更新配置,请使用 DNS 主机名而非 IP 地址。在配置副本集成员或分片集群成员时,使用 DNS 主机名而非 IP 地址尤为重要。
在水平分割网络配置下,请使用主机名而非 IP 地址来配置集群。从 MongoDB 5.0 开始,仅配置了 IP 地址的节点将无法通过启动验证,因而不会启动。
对于地理上冗余的三节点副本集部署,必须决定如何分配系统。三个节点可能的分配情况如下:
跨三个数据中心:每个地点一个节点。
跨两个数据中心:两个节点到地点 A,一个节点到地点 B。如果副本集的其中一个节点是仲裁节点 [1],则将仲裁节点与数据承载节点一起分配到地点 A。
注意
将副本集成员分布在两个数据中心比分布在一个数据中心更有优势。分布在两个数据中心时,
如果其中一个数据中心发生故障,数据仍可供读取,分布在单个数据中心则无法实现此功能。
如果具有少数成员的数据中心出现故障,副本集仍然可以支持写入操作和读取操作。
但是,如果具有大多数成员的数据中心出现故障,副本集将变为只读。
如有可能,请将成员分布在至少三个数据中心。对于配置服务器副本集 (CSRS),最佳实践是分布在三个数据中心(也可根据成员数量来增加数据中心数量)。如果使用第三个数据中心成本过高,一种可行的分布方法是在两个数据中心均匀分配数据承载成员,并将剩余成员存储在云中(如果公司政策允许)。
使用适当的选项启动副本集的每个成员。
为每个成员启动一个 mongod
实例,设置如下:
将
replication.replSetName
选项设置为副本集名称。如果您的应用程序连接到多个副本集,则每个副本集的名称必须不同。将
net.bindIp
选项设置为主机名/IP,或使用逗号隔开的主机名/IP 列表。设置适合您的部署的任何其他设置。
在本教程中,三个 mongod
实例与以下主机相关联:
副本集成员 | 主机名 |
---|---|
成员 0 | mongodb0.example.net |
成员 1 | mongodb1.example.net |
成员 2 | mongodb2.example.net |
以下示例通过 --replSet
和 --bind_ip
命令行选项指定副本集名称和 IP 绑定:
警告
将实例绑定到可公开访问的 IP 地址之前,必须保护集群免遭未经授权的访问。有关安全建议的完整列表,请参阅自管理部署的安全清单。至少应考虑启用身份验证和强化网络基础设施。
mongod --replSet "rs0" --bind_ip localhost,<hostname(s)|ip address(es)>
对于 <hostname(s)|ip address(es)>
,指定您的 mongod
实例的主机名和/或 IP 地址,远程客户端(包括副本集的其他成员)可以使用它们连接到该实例。
或者,您也可以在配置文件中指定 replica set name
和 ip addresses
:
replication: replSetName: "rs0" net: bindIp: localhost,<hostname(s)|ip address(es)>
要使用配置文件启动 mongod
,请使用 --config
选项指定配置文件的路径:
mongod --config <path-to-config>
在生产部署中,您可以配置一个初始化脚本来管理此进程。初始化脚本超出了本文档的范围。
启动新副本集。
通过 mongosh
,在副本集成员 0 上运行 rs.initiate()
。
重要
在副本集的一个且仅一个 mongod
实例上运行 rs.initiate()
。
重要
要避免因 IP 地址变更而更新配置,请使用 DNS 主机名而非 IP 地址。在配置副本集成员或分片集群成员时,使用 DNS 主机名而非 IP 地址尤为重要。
在水平分割网络配置下,请使用主机名而非 IP 地址来配置集群。从 MongoDB 5.0 开始,仅配置了 IP 地址的节点将无法通过启动验证,因而不会启动。
rs.initiate( { _id : "rs0", members: [ { _id: 0, host: "mongodb0.example.net:27017" }, { _id: 1, host: "mongodb1.example.net:27017" }, { _id: 2, host: "mongodb2.example.net:27017" } ] })
MongoDB 使用默认副本集配置启动副本集。
查看副本集配置。
rs.conf()
副本集配置对象与以下内容类似:
{ "_id" : "rs0", "version" : 1, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "mongodb0.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "mongodb1.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "mongodb2.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("585ab9df685f726db2c6a840") } }
可选。配置节点成为主节点的资格。
某些情况下,您可能希望一个数据中心内的节点先于其他数据中心内的节点被选为主节点。您可以修改节点的 priority
,使一个数据中心中的节点的 priority
高于其他数据中心的节点。
该副本集的某些成员(例如存在网络限制或资源有限的成员)不应在故障转移时成为主节点。将不应成为主节点的成员配置为具有优先级 0。
例如,要降低位于其中一个地点(本示例中为 mongodb2.example.net
)的节点的相对资格,可将该节点的优先级设置为 0.5
。
查看副本集配置,确定节点的
members
数组位置。请记住,数组位置与_id
并不相同:rs.conf() 将副本集配置对象复制到变量中(在以下示例中复制到
cfg
)。然后在变量中为节点设置正确的优先级。然后将变量传递给rs.reconfig()
,更新副本集配置。例如,要设置数组中第三个节点(即位置 2 的节点)的优先级,请发出以下命令序列:
cfg = rs.conf() cfg.members[2].priority = 0.5 rs.reconfig(cfg) 注意
rs.reconfig()
Shell 方法可以强制当前的主节点降级,从而引发选举。当主节点降级时,所有客户端都将断开连接。这是预期的行为。虽然选择新主节点的平均时间通常不应超过 12 秒,但请始终确保在计划维护期间发生任何副本配置更改。
这些命令返回后,您就设置好了地理上冗余的三节点副本集。
确保副本集有一个主节点。
使用 rs.status()
标识副本集中的主节点。
部署地理位置冗余的五节点副本集
重要
要避免因 IP 地址变更而更新配置,请使用 DNS 主机名而非 IP 地址。在配置副本集成员或分片集群成员时,使用 DNS 主机名而非 IP 地址尤为重要。
在水平分割网络配置下,请使用主机名而非 IP 地址来配置集群。从 MongoDB 5.0 开始,仅配置了 IP 地址的节点将无法通过启动验证,因而不会启动。
对于地理位置冗余的五节点副本集部署,您必须决定如何分配系统。五个节点可能的分配情况如下:
跨三个数据中心:两个节点在地点 A,两个节点在地点 B,一个节点在地点 C。
跨四个数据中心:两个节点在一个地点,一个节点在其他三个地点。
跨五个数据中心:每个地点一个节点。
跨两个数据中心:站点 A 中的三个节点和站点 B 中的两个节点。如果可能,请避免仅跨两个数据中心分配配置服务器副本集。
注意
将副本集成员分布在两个数据中心比分布在一个数据中心更有优势。分布在两个数据中心时,
如果其中一个数据中心发生故障,数据仍可供读取,分布在单个数据中心则无法实现此功能。
如果具有少数成员的数据中心出现故障,副本集仍然可以支持写入操作和读取操作。
但是,如果具有大多数成员的数据中心出现故障,副本集将变为只读。
如有可能,请将成员分布在至少三个数据中心。对于配置服务器副本集 (CSRS),最佳实践是分布在三个数据中心(也可根据成员数量来增加数据中心数量)。如果使用第三个数据中心成本过高,一种可行的分布方法是在两个数据中心均匀分配数据承载成员,并将剩余成员存储在云中(如果公司政策允许)。
使用适当的选项启动副本集的每个成员。
为每个成员启动一个 mongod
实例,设置如下:
将
replication.replSetName
选项设置为副本集名称,如果您的应用程序连接到多个副本集,则每个副本集的名称必须不同。有些驱动程序会按副本集名称对副本集连接进行分组。
将
net.bindIp
选项设置为主机名/IP 地址或以逗号分隔的主机名/IP 地址列表,并设置适合您的部署的任何其他设置。
在本教程中,五个 mongod
实例与以下主机相关联:
副本集成员 | 主机名 |
---|---|
成员 0 | mongodb0.example.net |
成员 1 | mongodb1.example.net |
成员 2 | mongodb2.example.net |
节点 3 | mongodb3.example.net |
节点 4 | mongodb4.example.net |
以下示例通过 --replSet
和 --bind_ip
命令行选项指定副本集名称和 IP 绑定:
警告
将实例绑定到可公开访问的 IP 地址之前,必须保护集群免遭未经授权的访问。有关安全建议的完整列表,请参阅自管理部署的安全清单。至少应考虑启用身份验证和强化网络基础设施。
mongod --replSet "rs0" --bind_ip localhost,<hostname(s)|ip address(es)>
对于 <hostname(s)|ip address(es)>
,指定您的 mongod
实例的主机名和/或 IP 地址,远程客户端(包括副本集的其他成员)可以使用它们连接到该实例。
或者,您也可以在配置文件中指定 replica set name
和 hostnames/ip
addresses
:
replication: replSetName: "rs0" net: bindIp: localhost,<hostname(s)|ip address(es)>
要使用配置文件启动 mongod
,请使用 --config
选项指定配置文件的路径:
mongod --config <path-to-config>
在生产部署中,您可以配置一个初始化脚本来管理此进程。初始化脚本超出了本文档的范围。
启动新副本集。
通过 mongosh
,在副本集成员 0 上运行 rs.initiate()
。
重要
在副本集的一个且仅一个 mongod
实例上运行 rs.initiate()
。
rs.initiate( { _id : "rs0", members: [ { _id: 0, host: "mongodb0.example.net:27017" }, { _id: 1, host: "mongodb1.example.net:27017" }, { _id: 2, host: "mongodb2.example.net:27017" }, { _id: 3, host: "mongodb3.example.net:27017" }, { _id: 4, host: "mongodb4.example.net:27017" } ] })
查看副本集配置。
rs.conf()
副本集配置对象与以下内容类似:
{ "_id" : "rs0", "version" : 1, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "mongodb0.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "mongodb1.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "mongodb2.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 3, "host" : "mongodb3.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 4, "host" : "mongodb4.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("5df2c9ccc21c478b838b98d6") } }
可选。配置节点成为主节点的资格。
某些情况下,您可能希望一个数据中心内的节点先于其他数据中心内的节点被选为主节点。您可以修改节点的 priority
,使一个数据中心中的节点的 priority
高于其他数据中心的节点。
该副本集的某些成员(例如存在网络限制或资源有限的成员)不应在故障转移时成为主节点。将不应成为主节点的成员配置为具有优先级 0。
例如,要降低位于其中一个地点(本示例中为 mongodb2.example.net
)的节点的相对资格,可将该节点的优先级设置为 0.5
。
查看副本集配置,确定节点的
members
数组位置。请记住,数组位置与_id
并不相同:rs.conf() 将副本集配置对象复制到变量中(在以下示例中复制到
cfg
)。然后在变量中为节点设置正确的优先级。然后将变量传递给rs.reconfig()
,更新副本集配置。例如,要设置数组中第三个节点(即位置 2 的节点)的优先级,请发出以下命令序列:
cfg = rs.conf() cfg.members[2].priority = 0.5 rs.reconfig(cfg) 注意
rs.reconfig()
Shell 方法可以强制当前的主节点降级,从而引发选举。当主节点降级时,所有客户端都将断开连接。这是预期的行为。虽然选择新主节点的平均时间通常不应超过 12 秒,但请始终确保在计划维护期间发生任何副本配置更改。
这些命令返回后,您就设置好了地理上冗余的五节点副本集。
确保副本集有一个主节点。
使用 rs.status()
标识副本集中的主节点。