一、复制介绍
复制是在多台服务器之间同步数据的过程。
复制在为数据提供了冗余同时,也提高了数据的可用性。由于在不同的数据库服务器上拥有多个数据镜像,复制可以有效的防止由于单台服务器故障而导致的数据丢失。复制还能够帮助我们从硬件故障或是服务中断中恢复数据。我们也可以通过增加复制节点来将其用于灾难恢复、报表或是备份。
在某些情况中,我们可以通过复制的方式来提高读的性能。客户端可以将读与写请求分别发送到不同的服务器上。我们还能够通过在其他数据中心建立分布式复制节点的方式来做异地冗灾,以进一步提高可用性。
MongoDB中的复制
复制集是由一组拥有相同数据集的 mongod 实例组成的。其中的一个节点为主节点(Primary),所有的写请求都是在它上面完成的。而其他的节点都是从节点(secondary),从节点接收从主节点上传来的操作并应用,并以此来保证其与主节点的数据集一致。
主节点 接收所有来自客户端的写操作。一个复制集只能有一个主节点。由于在一个复制集中只有一个成员能够接收写操作,复制集为所有来自主节点的读提供了 严格的一致性校验 。主节点通过将所有数据集的变动记录到 oplog 中以支持复制的实现。
从节点 将主节点上的oplog复制过来并应用这些操作来修改其自己的数据集以确保从节点的数据集与主节点的数据集一致。一旦主节点不可用了,复制集就会将一个从节点选举成为新的主节点。客户端默认是从主节点进行读操作,但是客户端也可以通过指定 复制集读选项 来将读操作发送给从节点。需要注意的是,在从节点上进行读操作时,所获得的数据可能不是此时主节点上的值
我们也可以为复制集新增一个额外的 mongod 实例作为 投票节点 。投票节点中并不包含数据集,投票节点的作用仅仅是在选举过程中参与投票。当复制集的成员个数为偶数时,添加一个投票节点可以防止平局的出现,通过多数选票来选举出新的主节点。由于投票节点仅提供投票功能,故无需一个专用的物理机。
投票节点 将只做投票使用。当 主节点 降职变为 从节点 的时候,其他的一个 从节点 将在选举中被推选为主节点。
异步复制
从节点从主节点上应用操作的过程是异步的。由于从节点是在主节点之后应用操作的,所以复制集在缺少某些成员的时候仍能继续运行。然而在这种情况下,从节点返回给客户端的数据可能并不是最新的数据。
自动化故障切换
当主节点无法与复制集中其他成员进行沟通超过10秒时,复制集将尝试推举另一位成员成为新的主节点。这时,第一个获得多数投票的从节点将升职为主节点。
其他特征
复制集提供了一些选项来支持实际应用时的需求。例如,将一个复制集分布在多个数据中心 ,又或是通过设置 priority 来控制选举的结果。复制集同时也支持将成员用于报表、灾难恢复或是备份。
二、复制概念介绍
复制集成员
MongoDB的 复制集 是由一组 mongod 实例所组成的,并提供了数据冗余与高可用性。复制集中的成员有以下几种:
Primary.
主节点 接收所有的写操作请求。
Secondaries.
从节点通过应用主节点传来的数据变动操作来保持其数据集与主节点的一致。从节点也可以通过增加额外的参数配置来对应特殊的需求。例如,从节点可以是 non-voting 或是 priority 0 。
我们也可以为复制集设置一个 投票节点 。投票节点其本身并不包含数据集。但是,一旦当前的主节点不可用时,投票节点就会参与到新的主节点选举的投票中。
一个复制集最多可以拥有12个成员。 [1] 但是同时最多只有其中的7个可以进行投票。
一个复制集至少需要这几个成员:一个 主节点 ,一个 从节点 ,和一个 投票节点 。但是在大多数情况下,我们会保持3个拥有数据集的节点:一个 主节点 和两个 从节点 。
复制集主节点
在复制集中,主节点是唯一能够接收写请求的节点。MongoDB在 主节点 上进行写操作,并会将这些操作记录到主节点的 oplog 中。 从节点 会将oplog复制到其本机并将这些操作应用到其自己的数据集上。
在拥有下述三个成员的复制集中,主节点将接收所有的写请求,而从节点会将oplog复制到本机并在其自己的数据集上应用这些操作。
复制集中任何成员都可以接收读请求。但是默认情况下,应用程序会直接连接到在主节点上进行读操作。
复制集最多只能拥有一个主节点。一旦当前的主节点不可用了,复制集就会选举出新的主节点。
在拥有下述三个成员的复制集中,一旦当前主节点不可用了,就会触发选举机制,并将在剩下的从节点中选举出一个新的主节点。
复制集从节点
从节点的数据集与 主节点 中的一致。从节点将主节点上的 oplog 复制到本机,并异步的将这些操作记录应用在其自己的数据集上。每个复制集可以拥有多个从节点。
下述由三个成员组成的复制集拥有两个从节点。这些从节点将主节点上的oplog复制过来并应用在其自己的数据集上。
客户端虽然无法在从节点上进行写操作,但却可以进行读操作。
从节点是可以升职为主节点的。一旦现有的主节点不可用了,那么复制集将会发起 election 来选择将哪个从节点提升为新的主节点。
在拥有下述三个成员的复制集中,一旦当前主节点不可用了,就会触发选举机制,并将在剩下的从节点中选举出一个新的主节点。
我们可以通过修改参数的方式来将从节点用于特殊的需求。例如:
我们可以通过禁止从节点升职为主节点的方式来将该节点永驻为从节点或是用于冷备。
我们可以通过禁止应用在该从节点上进行读操作的方式,来让一些需要进行流量隔离的应用在其上进行读。
我们可以通过设置 “延时备份节点” 的方式来防止诸如误删除等的误操作或是错误。
优先级为0的复制集成员
一旦将优先级设置为0,那么该从节点将 不能 升职为 主节点 。 优先级为0 的成员不会 触发 选举 。除此之外该节点与其他从节点没有区别,优先级为0 的从节点拥有与主节点一致的数据集,能接受读请求,同时也能参与投票。通过将从节点的 优先级设置为0 来防止其升职为主节点可以在分布式数据中心的结构中起到很好的作用。
在下述这样的拥有三个成员的复制集中,一个主节点和一个从节点坐落在某一个数据中心中,另一个不能升职为主节点的 优先级为0 的从节点则在另一个数据中心。
将优先级为0的成员作为备用节点
在很多情况下,我们可能不需要准备一个 优先级为0 的备用节点。然而在一些硬件环境或是架构的 地理分布 较为多变的情境中,一个 优先级为0 的备用节点可以很好的保证符合条件的成员升职为主节点。
一个拥有特殊硬件配置或是系统优化配置的 优先级为0 的备用节点也可以有效的为特殊需求提供服务。比如可以将 优先级设置为0 来让其不能升职为主节点。
如果我们的复制集中已经有了七个参与投票的节点,那么请将其他节点设置为 不参与投票 。
优先级为0的节点与故障切换
当配置一个 优先级为0 的节点时,我们需要考虑到可能出现的故障切换情况,比如网络故障等。需要注意的时,我们要确保在主数据中心中拥有足够多可以参与投票和选举的节点,并确保其拥有可以顺利成为主节点的成员。
隐藏节点
隐藏节点拥有与 主节点 一致的数据集,但是它对于应用程序来说是 不可见 的。隐藏节点可以很好的与 复制集 中的其他节点隔离,并应对特殊的需求。隐藏节点也应该是一个 不能升职为主节点 的 优先级为0的节点 。函数 db.isMaster() 将不会列出隐藏节点。隐藏节点在 选举 中是 可以进行投票 的。
在下述这样拥有五个节点的复制集中,四个从节点都拥有与主节点一致的数据集,但其中的一个从节点是隐藏节点。
读操
客户端将不会把读请求分发到隐藏节点上,即使我们设定了 复制集读选项 。这些隐藏节点将不会收到来自应用程序的请求。我们可以将隐藏节点专用于报表节点或是备份节点。 延时节点 也应该是一个隐藏节点。
在分片集群中, mongos 将不与隐藏节点进行交流。
投票
在复制集的选举中,隐藏节点是会 参加 投票的。当关闭一个隐藏节点的时候,请确认复制集中的可用节点个数足够进行选举,以防 主节点 降职导致复制集对外不可用。
将隐藏节点用于备份,可以防止我们在备份过程中使用 db.fsyncLock() 和 db.fsyncUnlock() 操作来对 mongod 实例加或解除写锁的过程中应用程序的不可用。
延时节点
延时节点也将从 复制集 中主节点复制数据,然而延时节点中的数据集将会比复制集中主节点的数据延后。举个例子,现在是09:52,如果延时节点延后了1小时,那么延时节点的数据集中将不会有08:52之后的操作。
由于延时节点的数据集是延时的,因此它可以帮助我们在人为误操作或是其他意外情况下恢复数据。举个例子,当应用升级失败,或是误操作删除了表和数据库时,我们可以通过延时节点进行数据恢复。
行为
延时节点通过延时应用 oplog 中的操作来实现其延时的效果。当我们选择延时时常的时候,需要考虑到以下内容:
必须大于或者等于你的维护视窗。
必须 小于 oplog的存储能力
分片
在分片集群中,当 平衡器 平衡器打开的时候延时节点效果有限。因为延时节点延时的复制数据段,而若在延时的时间段内进行过数据段迁移的话,复制集中的延时节点就无法为还原分片集群提供有效的帮助
例子
在下述这样拥有五个成员的复制集中,主节点与所有从节点都拥有数据集的副本。其中一个从节点延时3600秒(1小时)应用oplog中的操作。这个延时节点同时也是 隐藏节点 和 优先级为0 的节点。
配置方式
延时节点需要将 priority 设置为0,还需要将 hidden 设置为 true ,同时还需要将 slaveDelay 设置为想要延迟的时间(单位为秒):
{
"_id" : <num>,
"host" : <hostname:port>,
"priority" : 0,
"slaveDelay" : <seconds>,
"hidden" : true}
投票节点
投票节点 并不含有 复制集中的数据集副本,且也 无法 升职为主节点。复制集中可能会有多个投票节点来为 选举出新的主节点 进行投票。投票节点的存在使得复制集可以以偶数个节点存在,而无需为复制集再新增节点。
注意
不要将投票节点运行在复制集的主节点或者从节点机器上。
仅仅在复制集成员为偶数个的时候加入投票节点。如果在拥有奇数个复制集成员的复制集中新增了一个投票节点,复制集可能会遇到 选举 僵局。