部署地理冗余副本集
在本页面
Overview
本教程概述了使用多个位置的成员部署replica set的过程。本教程介绍三成员副本集和五成员副本集。如果您有偶数个副本集成员,请添加另一个数据承载成员(如果可能)以部署奇数个投票成员。 [1]
有关分布式副本集的更多信息,请参见跨两个或多个数据中心分布的副本集。另请参见副本集部署体系结构和Replication。
[1] | 如果情况不允许其他数据承载成员,并且投票成员的数量为偶数,则可以添加仲裁器。有关使用仲裁器的注意事项,请参见复制集仲裁器。 |
Considerations
Architecture
在 Producing,将副本集的每个成员部署到其自己的计算机上,并尽可能绑定到标准 MongoDB 端口27017
。
有关更多信息,请参见副本集部署体系结构。
IP Binding
使用bind_ip
选项可确保 MongoDB 在配置的地址上侦听来自应用程序的连接。
在 3.6 版中进行了更改:从 MongoDB 3.6 开始,MongoDB 二进制文件mongod和mongos默认绑定到 localhost(127.0.0.1
)。如果为二进制文件设置了net.ipv6配置文件设置或--ipv6
命令行选项,则该二进制文件还会绑定到 IPv6 地址::1
。
以前,从 MongoDB 2.6 开始,默认情况下,只有正式 MongoDB RPM(Red Hat,CentOS,Fedora Linux 和派生版本)和 DEB(Debian,Ubuntu 和派生版本)程序包中的二进制文件绑定到 localhost。
当仅绑定到 localhost 时,这些 MongoDB 3.6 二进制文件只能接受来自同一台计算机上运行的 Client 端(包括mongo shell,部署中其他成员(副本集和分片群集)的连接)。远程 Client 端无法连接到仅绑定到 localhost 的二进制文件。
要覆盖并绑定到其他 IP 地址,可以使用net.bindIp配置文件设置或--bind_ip
命令行选项来指定 IP 地址列表。
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
例如,以下mongod实例同时绑定到 localhost 和示例 IP 地址198.51.100.1
:
mongod --bind_ip localhost,198.51.100.1
为了连接到该实例,远程 Client 端必须指定 IP 地址198.51.100.1
或与该 IP 地址关联的主机名:
mongo --host 198.51.100.1
mongo --host My-Example-Associated-Hostname
Connectivity
确保网络流量可以在集合的所有成员与网络中的所有 Client 端之间安全地传递。
考虑以下:
-
构建虚拟专用网。确保您的网络拓扑在局域网中路由单个站点内成员之间的所有流量。
-
配置访问控制以防止从未知 Client 端到副本集的连接。
-
配置网络和防火墙规则,以使传入和传出数据包仅在默认的 MongoDB 端口上并且仅在您的部署中才允许。请参阅 IP 绑定注意事项。
确保可以通过可解析的 DNS 或主机名访问副本集的每个成员。您应该适当地配置 DNS 名称或设置系统的/etc/hosts
文件以反映此配置。
每个成员都必须能够连接到其他每个成员。有关如何检查连接的说明,请参阅测试所有成员之间的连接。
Configuration
在部署 MongoDB 之前,请创建 MongoDB 用来存储数据文件的目录。
在/etc/mongod.conf
或相关位置中存储的configuration file中指定mongod配置。
有关配置选项的更多信息,请参见配置文件选项。
成员分布
如果可能,请使用奇数个数据中心,并选择成员分布,以最大程度地保证即使丢失数据中心,其余副本集成员也可以构成多数或最少提供数据副本的可能性。
Voting Members
决不能部署超过七个投票成员。
Prerequisites
对于本教程中的所有配置,请将每个副本集成员部署在单独的系统上。尽管您可能在一个系统上部署多个副本集成员,但是这样做会降低副本集的冗余性和容量。此类部署通常用于测试目的。
本教程假定您已在将成为副本集一部分的每个系统上安装了 MongoDB。如果尚未安装 MongoDB,请参阅installation tutorials。
Procedures
部署地理上冗余的三成员副本集
对于地理上冗余的三成员副本集部署,必须确定如何分发系统。这三个成员可能的分布是:
-
跨三个数据中心:每个站点一名成员。
-
跨两个数据中心:站点 A 的两个成员和站点 B 的一个成员。如果副本集的成员之一是仲裁者[#arbiter-alternative],则与一个承载数据的成员将仲裁者分发到站点 A。
Note
在两个数据中心之间分布副本集成员可提供优于单个数据中心的好处。在两个数据中心分布中,
-
如果其中一个数据中心发生故障,则与单个数据中心分发不同,该数据仍可读取。
-
如果具有少数成员的数据中心发生故障,则副本集仍然可以同时执行写操作和读操作。
-
但是,如果具有大多数成员的数据中心发生故障,则副本集将变为只读。
如果可能,请在至少三个数据中心中分配成员。对于配置服务器副本集(CSRS),最佳实践是分布在三个(或更多,取决于成员的数量)中心中。如果第三个数据中心的成本过高,则一种分配可能性是在公司 Policy 允许的情况下,在两个数据中心之间平均分配数据承载成员,并将其余成员存储在云中。
使用适当的选项启动副本集的每个成员。
对于每个成员,使用以下设置启动mongod实例:
- 将replication.replSetName选项设置为副本集名称,
如果您的应用程序连接到多个副本集,则每个副本集应具有不同的名称。某些驱动程序通过副本集名称对副本集连接进行分组。
-
将net.bindIp选项设置为 IP 或以逗号分隔的 IP 列表,然后
-
根据您的部署设置任何其他设置。
在本教程中,三个mongod实例与以下主机关联:
副本集成员 | Hostname |
---|---|
Member 0 | mongodb0.example.net |
Member 1 | mongodb1.example.net |
Member 2 | mongodb2.example.net |
以下示例通过--replSet和--bind_ip命令行选项指定副本集名称和 ip 绑定:
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
mongod --replSet "rs0" --bind_ip localhost,<ip address of the mongod host>
对于<ip address>
,请指定mongod实例的 IP 地址或主机名,远程 Client 端(包括副本集的其他成员)可以使用该 IP 地址或主机名连接到该实例。
另外,您也可以在configuration file中指定副本集名称和ip addresses:
replication:
replSetName: "rs0"
net:
bindIp: localhost,<ip address>
要以配置文件开始mongod,请使用--config选项指定配置文件的路径:
mongod --config <path-to-config>
在生产部署中,您可以配置init script来 Management 此过程。初始化脚本超出了本文档的范围。
将 mongo shell 连接到其中一个 mongod 实例。
从运行mongod的同一台计算机(在本教程中为mongodb0.example.net
)中,启动mongo Shell。要连接mongod并在27017
的默认端口上监听 localhost,只需发出:
mongo
根据您的路径,您可能需要指定mongo二进制文件的路径。
启动副本集。
在mongo shell 中,对副本集成员 0 运行rs.initiate()。
Important
在副本集的仅一个且仅一个 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" }
]
})
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" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "mongodb1.example.net:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "mongodb2.example.net:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 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。
副本集的某些成员(例如,具有网络限制或资源有限的成员)不应成为failover中的主要成员。配置不应成为主要成员的成员具有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)
Note
rs.reconfig() shell 方法可以强制当前的主数据库降级,从而引起选举。当主要服务器降级时,所有 Client 端都将断开连接。这是预期的行为。虽然选择一个新主数据库的中值时间通常不应超过 12 秒,但请始终确保在计划的维护期间进行任何副本配置更改。
这些命令返回后,您将获得一个具有地理位置冗余的三成员副本集。
确保副本集具有主副本集。
使用rs.status()标识副本集中的主副本。
部署地理上冗余的五成员副本集
对于地理上具有冗余性的五成员副本集部署,您必须决定如何分发系统。这五个成员的一些可能的分布是:
-
跨三个数据中心:站点 A 中的两个成员,站点 B 中的两个成员,站点 C 中的一个成员。
-
跨四个数据中心:一个站点中的两个成员,其他三个站点中的一个成员。
-
横跨五个数据中心:每个站点一名成员。
-
跨两个数据中心:站点 A 中的三个成员和站点 B 中的两个成员。如果可能,请避免仅在两个数据中心之间分发配置服务器副本集。
Note
在两个数据中心之间分布副本集成员可提供优于单个数据中心的好处。在两个数据中心分布中,
-
如果其中一个数据中心发生故障,则与单个数据中心分发不同,该数据仍可读取。
-
如果具有少数成员的数据中心发生故障,则副本集仍然可以同时执行写操作和读操作。
-
但是,如果具有大多数成员的数据中心发生故障,则副本集将变为只读。
如果可能,请在至少三个数据中心中分配成员。对于配置服务器副本集(CSRS),最佳实践是分布在三个(或更多,取决于成员的数量)中心中。如果第三个数据中心的成本过高,则一种分配可能性是在公司 Policy 允许的情况下,在两个数据中心之间平均分配数据承载成员,并将其余成员存储在云中。
使用适当的选项启动副本集的每个成员。
对于每个成员,使用以下设置启动mongod实例:
- 将replication.replSetName选项设置为副本集名称,
如果您的应用程序连接到多个副本集,则每个副本集应具有不同的名称。某些驱动程序通过副本集名称对副本集连接进行分组。
-
将net.bindIp选项设置为 IP 或以逗号分隔的 IP 列表,然后
-
根据您的部署设置任何其他设置。
在本教程中,五个mongod实例与以下主机关联:
副本集成员 | Hostname |
---|---|
Member 0 | mongodb0.example.net |
Member 1 | mongodb1.example.net |
Member 2 | mongodb2.example.net |
Member 3 | mongodb3.example.net |
Member 4 | mongodb4.example.net |
以下示例通过--replSet和--bind_ip命令行选项指定副本集名称和 ip 绑定:
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
mongod --replSet "rs0" --bind_ip localhost,<ip address of the mongod host>
对于<ip address>
,请指定mongod实例的 IP 地址或主机名,远程 Client 端(包括副本集的其他成员)可以使用该 IP 地址或主机名连接到该实例。
另外,您也可以在configuration file中指定副本集名称和ip addresses:
replication:
replSetName: "rs0"
net:
bindIp: localhost,<ip address>
要以配置文件开始mongod,请使用--config选项指定配置文件的路径:
mongod --config <path-to-config>
在生产部署中,您可以配置init script来 Management 此过程。初始化脚本超出了本文档的范围。
将 mongo shell 连接到其中一个 mongod 实例。
从运行mongod的同一台计算机(在本教程中为mongodb0.example.net
)中,启动mongo Shell。要连接mongod并在27017
的默认端口上监听 localhost,只需发出:
mongo
根据您的路径,您可能需要指定mongo二进制文件的路径。
启动副本集。
在mongo shell 中,对副本集成员 0 运行rs.initiate()。
Important
在副本集的仅一个且仅一个 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),
"members" : [
{
"_id" : 0,
"host" : "mongodb0.example.net:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "mongodb1.example.net:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "mongodb2.example.net:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 3,
"host" : "mongodb3.example.net:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 4,
"host" : "mongodb4.example.net:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 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。
副本集的某些成员(例如,具有网络限制或资源有限的成员)不应成为failover中的主要成员。配置不应成为主要成员的成员具有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)
Note
rs.reconfig() shell 方法可以强制当前的主数据库降级,从而引起选举。当主要服务器降级时,所有 Client 端都将断开连接。这是预期的行为。虽然选择一个新主数据库的中值时间通常不应超过 12 秒,但请始终确保在计划的维护期间进行任何副本配置更改。
这些命令返回后,您将获得一个具有地理位置冗余的五成员副本集。
确保副本集具有主副本集。
使用rs.status()标识副本集中的主副本。