MongoDB复制集成员及架构介绍(一)

时间:2021-07-16 05:13:01

MongoDB复制集介绍

MongoDB支持在多个机器中通过异步复制达到提供了冗余,增加了数据的可用性。MongoDB有两种类型的复制,第一种是同于MySQL的主从复制模式(MongoDB已不再推荐此方案);第二种是复制集,提供了自动故障转移的主从复制集群,其中复制集没有固定的主节点,当一个主机的故障后从节点会重新“选举”出一个新的主节点,从而提高的系统的可用性。

复制集(Replica Sets)成员

MongoDB的复制集是由一组mongod实例所组成的,并提供了数据冗余与高可用性。复制集中的成员有以下几种:

1)主节点(PRIMARY)

在复制集中,主节点是唯一能够接收写请求的节点。MongoDB在 主节点上进行写操作,并会将这些操作记录到主节点的oplog 中。从节点会将oplog复制到其本机并将这些操作应用到其自己的数据集上。

2)从节点(SECONDARY)

从节点通过应用主节点传来的数据变动操作(oplog日志文件)来保持其数据集与主节点的一致,这一点跟大多数数据库的复制模式差不多,但Mongodb的从节点是无法进行写操作的。此外从节点也可以通过增加额外的参数配置来对应特殊的需求。例如,从节点可以是non-voting 或是priority 0。

3)投票节点(arbiter)

我们也可以为复制集设置一个投票节点,投票节点其本身并不包含数据集副本。且也无法升职为主节点。这里我们称arbiter为投票节点,也可以称为仲裁(arbiter中文就是仲裁),一般在高可用集群中有两种常见的方式选举,一个是投票另一个就是仲裁。一个复制集中可能会有多个投票节点来为选举出新的主节点进行投票,投票节点的存在使得复制集可以以偶数个节点存在,而无需为复制集再新增节点(不要将投票节点运行在复制集的主节点或者从节点机器上)。一旦当前的主节点不可用时,投票节点就会参与到新的主节点选举的投票中。

注意:

1)一个复制集中所有的成员都有一票投票权利,ARBITER节点从MongoDB2.6开始也只有投一票的权利。但是跟其他成员不同的是,其他成员的投票权是可以通过votes参数给取消掉的,但是ARBITER的投票权是无法取消的。目前副本集节点最多可以有12个(从节点可以分摊读压力),其中最多只有7个可以投票,也就是说当你的投票节点大于7个时,就要把其余节点的投票权取消。

2)如果仅仅在复制集成员为偶数个的时候加入投票节点,如果在拥有奇数个复制集成员的复制集中新增了一个投票节点,复制集可能会遇到选举僵局。在下面这样的复制集中,一个投票节点可被加入到复制集中来实现选举过程中所需的偶数张票。

MongoDB复制集成员及架构介绍(一)

另外要说的就是安全性,投票节点与其他复制集节点的交流仅有:选举过程中的投票,心跳检测和配置数据,这些交互都是不加密的。当然如果有需求也可以通过开启authorization来进行安全性保证。

什么时候应该使用投票节点?

当复制集中有偶数个节点时,应该再加一个投票节点,用于打破投票僵局。比如:我线上共有3台服务器,其中1台是作为Web 服务器;其余2台作为 DB 服务器,各部署了1个MongoDB节点,构成了2个节点的复制集。这个时候,我并没有多余的机器了。在这个情况下,如果任意一台 DB 服务器上的 MongoDB 挂了,那么另外一台的 MongoDB 必然变为 SECONDARY 节点(这个地方可能有些不太理解,任意一台挂掉了另外一台不是应该做主节点吗?),那么就意味着 MongoDB 是不可用的了。为了避免这种情况,提高服务的可用性,可以在 Web 服务器上部署一个投票节点。投票节点并不存储数据,因此不能升职为 PRIMARY 节点,它对于硬件资源要求很低,并不会对 Web 服务器上的其他程序产生太大影响。这种情况下,如果任意一台 DB 服务器挂了,另外一台服务器上的 MongoDB 将成为 PRIMARY 节点,此时 MongoDB 还是依旧对外提供服务的。乘此时机,赶紧排查出故障的那台服务器的原因,尽快恢复服务。

为了让投票节点可以占用更少的资源,可以在配置文件中添加以下几个配置项:

1
2
3
journal = false
smallfiles = true
noprealloc = true

所以一个复制集至少需要这几个成员:一个主节点 ,一个从节点和一个投票节点。但是在大多数情况下,我们会保持3个拥有数据集的节点:一个主节点和两个从节点。

MongoDB复制集成员及架构介绍(一)

复制集中任何成员都可以接收读请求。但是默认情况下,应用程序会直接连接到在主节点上进行读操作。阅读复制集读选项可以获得更多关于更改默认读请求目标的信息。复制集最多只能拥有一个主节点,一旦当前的主节点不可用了,复制集就会选举出新的主节点。

对于复制集从节点来说,还可以有以下几种多样性。分别为优先级为0的复制集成员、隐藏节点、延时节点。

优先级为0的复制集成员

一旦将优先级设置为0,那么该从节点将不能升职为主节点。优先级为0的成员不会触发选举。除此之外该节点与其他从节点没有区别,优先级0的从节点拥有与主节点一致的数据集,能接受读请求,同时也能参与投票。通过将从节点的优先级设置为0来防止其升职为主节点可以在分布式数据中心的结构中起到很好的作用。

在下述这样的拥有三个成员的复制集中,一个主节点和一个从节点坐落在某一个数据中心中,另一个不能升职为主节点的优先级为0的从节点则在另一个数据中心。

MongoDB复制集成员及架构介绍(一)

隐藏节点

读操作

当在一个复制集中设置了隐藏节点,那么客户端将不会把读请求分发到隐藏节点上,即使我们设定了复制集读选项。这些隐藏节点将不会收到来自应用程序的请求。我们可以将隐藏节点专用于报表节点或是备份节点。延时节点也应该是一个隐藏节点。在分片集群中, mongos 将不与隐藏节点进行交流。

投票

在复制集的选举中,隐藏节点是会参加投票的。当关闭一个隐藏节点的时候,请确认复制集中的可用节点个数足够进行选举,以防主节点降职导致复制集对外不可用。

延时节点

延时节点也将从复制集中主节点复制数据,然而延时节点中的数据集将会比复制集中主节点的数据延后。举个例子,现在是09:52,如果延时节点延后了1小时,那么延时节点的数据集中将不会有08:52之后的操作。由于延时节点的数据集是延时的,因此它可以帮助我们在人为误操作或是其他意外情况下恢复数据。举个例子,当应用升级失败,或是误操作删除了表和数据库时,我们可以通过延时节点进行数据恢复。

行为

延时节点通过延时应用 oplog 中的操作来实现其延时的效果。当我们选择延时时常的时候,需要考虑到以下内容:

1)必须大于或者等于你的维护视窗。

2)必须小于oplog的存储能力,参见Oplog大小来获得更多oplog的信息。

分片

在分片集群中,当平衡器打开的时候延时节点效果有限。因为延时节点延时的复制数据段,而若在延时的时间段内进行过数据段迁移的话,复制集中的延时节点就无法为还原分片集群提供有效的帮助了。

使用复制集的好处?

1)备份数据

通过自带的 mongo_dump/mongo_restore 工具也可以实现备份,但是毕竟没有复制集的自动同步备份方便。

2)故障自动转移

部署了复制集,当主节点挂了后,集群会自动投票再从节点中选举出一个新的主节点,继续提供服务。而且这一切都是自动完成的,对运维人员和开发人员是透明的。当然,发生故障了还是得人工及时处理,不要过度依赖复制集,万一都挂了,那就连喘息的时间都没有了。

3)提高读性能

默认情况下,读和写都只能在主节点上进行。但是主压力过大时就可以把读操作分离到从节点上从而提高读性能。下面是MongoDB的驱动支持5种复制集读选项:

primary:默认模式,所有的读操作都在复制集的主节点进行的。

primaryPreferred:在大多数情况时,读操作在主节点上进行,但是如果主节点不可用了,读操作就会转移到从节点上执行。

secondary:所有的读操作都在复制集的从节点上执行。

secondaryPreferred:在大多数情况下,读操作都是在从节点上进行的,但是当从节点不可用了,读操作会转移到主节点上进行。

nearest:读操作会在复制集中网络延时最小的节点上进行,与节点类型无关。

但是除了primary 模式以外的复制集读选项都有可能返回非最新的数据,因为复制过程是异步的,从节点上应用操作可能会比主节点有所延后。如果我们不使用primary模式,请确保业务允许数据存在可能的不一致。

复制集架构

最基础的复制集架构是由三个成员组成的,这样的架构为复制集提供了冗余与故障切换的余地。根据应用的需求来设计复制集的架构,尽量避免不必要的复杂化。大体遵循的策略如下:

1)决定复制集的成员个数

复制集应含有奇数个成员:奇数个成员的存在确保了复制集可以正常的选举出主节点,如果复制集现有偶数个成员,那么请增加一个投票节点以保证其成员个数为奇数。投票节点由于不包含复制集的数据集副本故所需资源也很少。所以我们可以将投票节点设置在其他应用的机器或是某个共享功能的机器上。

故障容错的考量:对于复制集来说,其故障容错就是要保证在主节点不可用的时候,剩余的节点能够顺利的选举出新的主节点。换句话说,就是为了保证可以正常的选举出新的主节点,需要保证复制集中多数成员的存活。复制集在没有主节点时将无法接受写请求,复制集的故障容错受到其含有的成员个数的影响,但是该影响也不是直接体现的。请参考下表:

MongoDB复制集成员及架构介绍(一)

2)为特殊需求使用隐藏节点或延时节点

新增“隐藏节点”来为特殊需求提供服务,比如备份或是报表。新增“延时节点”用来保证数据的安全性,比如在主库误操作后,但是操作命令在延时节点还没有执行,这时就可以通过延时节点来恢复数据。

3)以读为主的架构的负载均衡

若业务带来的大量的读请求,我们可以通过做读写分离来提升复制集的读能力。随着业务的扩展,我们可以通过在其他数据中心新增从节点的方式来提高冗余能力与可用性。但为了能够选举出主节点,请保证复制集中多数节点的可用性。

4)通过journaling功能来在意外掉电中保护数据

我们可以通过开启journaling功能个来在服务意外关闭或是掉电时保护数据。如果没有开启journaling功能,MongoDB将无法在服务意外关闭或是掉电后恢复数据,默认通过journaling是可以恢复60内的数据,因为mongodb默认60秒刷一次盘。

几种常见架构模式

1)一个主节点与两个从节点

包含三个带有数据集的节点组成的复制集拥有:

l  一个主节点。

l  两个从节点,这两个从节点都可以在选举中升职为主节点。

MongoDB复制集成员及架构介绍(一)

这样的架构中除了主节点外还一直拥有两个包含完整数据集的从节点,这样架构的复制集提供了高可用性 与故障容灾的功能。一旦主节点不可用了,复制集会将一个从节点选举为新的主节点来继续对外服务。之前的主节点将在其可用后再次加入复制集中。

MongoDB复制集成员及架构介绍(一)

2)一个主节点一个从节点和一个投票节点

含三个节点其中两个带有数据集的复制集拥有:

l  一个主节点。

l  一个从节点,这个从节点可以在选举中升职为主节点。

l  一个投票节点,投票节点仅在选举中进行投票。

MongoDB复制集成员及架构介绍(一)

由于投票节点不包含数据集,所以这样的复制集架构仅有一份数据集的备份,投票节点需要的资源很少。但是,在拥有一个主节点,一个从节点和一个投票节点的复制集架构中,如果主节点或者从节点不可用了,复制集还是可以正常提供服务的。如果主节点不可用了,那么复制集会将从节点升职为主节点。

MongoDB复制集成员及架构介绍(一)

3)拥有4个或更多节点的复制集

虽然复制集默认配置是三个节点,但是我们也可以使用拥有更高扩展性的架构,设置更多节点。新增复制集节点来提高复制集的容灾能力或是提高分布式读的读性能。复制集需要有奇数个参与投票的节点,如果复制集中参与投票的节点是偶数个,新增一个投票节点来使复制集中参与投票的节点变为奇数。一个复制集最多能有12个节点,但是其中仅有7个参与投票的节点。

在下述这样拥有9个节点的复制集中,有7个参与投票的节点和2个不参与投票的几点。

MongoDB复制集成员及架构介绍(一)

4)异地分布式架构的复制集

在多个数据中心建立复制集节点可以提高数据冗余小也可以在主数据中心不可用时提供很好的故障容忍性。在其他数据中心中得复制集节点应该将优先级设置为0来避免其升职为主节点。

异地分布式架构的复制集应该拥有:

l  一个主节点在主数据中心。

l  一个从节点在主数据中心,这个节点需随时准备成为新的主节点。

l  一个优先级为0的节点在另一个数据中心,这个节点将不能升职为主节点。

在下面这样的复制集中,主节点和一个从节点在数据中心1 中, 数据中心2 中有一个不能升职为主节点的优先级为0的从节点。

MongoDB复制集成员及架构介绍(一)

当主节点不可用时,复制集将会选举出一个在数据中心1的新的主节点。如果2个数据中心之间无法沟通,数据中心2中的节点将不能升职为主节点。

如果数据中心1变得不可用,您可以手动恢复从数据中心2的数据集,以最少的停机时间。

为了实现选举,主数据中心上应该有多数节点。同时也别忘了让复制集保持奇数个节点。当我们在其他数据中心新增节点而导致复制集拥有偶数个节点的时候,应该新建一个投票节点。