部署地理冗余自托管复制集
概述
本教程概述了部署具有多个位置成员的副本集的过程。本教程涵盖了三成员副本集和五成员副本集。如果您有偶数个副本集成员,如果可能的话,添加另一个数据承载成员,以部署奇数个投票成员。[1]
有关分布式副本集的更多信息,请参阅跨越两个或更多数据中心部署的副本集。另请参阅副本集部署架构和自管理复制参考。
[1] | (1, 2) 如果情况不允许添加另一个数据承载成员,并且您有偶数个投票成员,则可以添加仲裁员。有关使用仲裁员的考虑因素,请参阅副本集仲裁员。 |
考虑事项
架构
在生产环境中,将副本集的每个成员部署到自己的机器上。如果可能的话,请确保MongoDB监听默认端口27017
.
注意
在滚动升级之外,一个副本集的所有 mongod
成员应使用相同的 MongoDB 主版本。
有关更多信息,请参阅 副本集部署架构。
主机名
重要
为了避免因 IP 地址更改而进行的配置更新,请使用 DNS 主机名而不是 IP 地址。当配置副本集成员或分片集群成员时,使用 DNS 主机名而不是 IP 地址尤为重要。
在跨越分割网络视域配置集群时,请使用主机名而不是 IP 地址。从 MongoDB 5.0 开始,仅配置了 IP 地址的节点将失败启动验证且不会启动。
IP 绑定
使用 --bind_ip
选项确保 MongoDB 能够监听配置地址上的应用程序的连接。
警告
在将实例绑定到公开可访问的 IP 地址之前,您必须保护集群免受未经授权的访问。有关安全建议的完整列表,请参阅 自托管部署的安全清单。至少,请考虑 启用身份验证 和 强化网络基础设施。
MongoDB的二进制文件,包括mongod
和mongos
,默认绑定到本地主机。如果二进制文件的配置文件设置或命令行选项--ipv6
设置了net.ipv6
,则二进制文件还将绑定到本地主机的IPv6地址。
默认情况下,绑定到本地主机的mongod
和mongos
只接受运行在同一台计算机上的客户端的连接。这种绑定行为包括mongosh
和您副本集或分片集群的其他成员。远程客户端无法连接到仅绑定到本地主机的二进制文件。
要覆盖默认绑定并绑定到其他IP地址,请使用配置文件设置net.bindIp
或命令行选项--bind_ip
来指定主机名或IP地址列表。
警告
从MongoDB 5.0开始,仅配置了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 地址的节点将失败启动验证且不会启动。
对于地理冗余的三成员副本集部署,您必须决定如何分配您的系统。三个成员的一些可能的分配方式包括
跨三个数据中心:每个站点一个成员。
跨两个数据中心:Site A 有两个成员,Site B 有一个成员。如果副本集的成员之一是仲裁者 [1],将仲裁者分配到 Site 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)>
,指定远程客户端(包括副本集的其他成员)可以用来连接到该实例的主机名和/或 ip 地址。
或者,您也可以在 配置文件 中指定 副本集名称
和 ip 地址
:
replication: replSetName: "rs0" net: bindIp: localhost,<hostname(s)|ip address(es)>
要使用配置文件启动 mongod
,请使用 --config
选项指定配置文件的路径
mongod --config <path-to-config>
在生产部署中,您可以配置一个 init 脚本 来管理此过程。init 脚本超出了本文档的范围。
启动副本集。
从 mongosh
,在副本集成员 0 上运行 rs.initiate()
。
重要
在副本集的 一个 实例上运行 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()
显示副本集配置对象:
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()
命令行方法可以强制当前主节点下线,引发选举。当主节点下线时,所有客户端都将断开连接。这是预期的行为。虽然选举新主节点的中值时间通常不会超过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)>
,指定远程客户端(包括副本集的其他成员)可以用来连接到该实例的主机名和/或 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>
在生产部署中,您可以配置一个 init 脚本 来管理此过程。init 脚本超出了本文档的范围。
启动副本集。
从 mongosh
,在副本集成员 0 上运行 rs.initiate()
。
重要
在副本集的 一个 实例上运行 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()
显示副本集配置对象:
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()
命令行方法可以强制当前主节点下线,引发选举。当主节点下线时,所有客户端都将断开连接。这是预期的行为。虽然选举新主节点的中值时间通常不会超过12秒,但始终确保任何副本集配置更改都发生在计划维护期间。
执行完这些命令后,您将拥有一个具有地理冗余的五成员副本集。
确保副本集有一个主节点。
使用 rs.status()
来识别副本集中的主节点。