redis中的高可用是如何实现的?

用过redis小伙伴们,大概都知道redis常见的部署方式分为单机模式,主从模式和集群模式。单机模式主要在学习,测试的场景下使用,企业中使用的场景比较少。主从模式是redis实现高可用,高性能的一种架构模式,通过读写分离,主从切换,来实现高可用与高性能的目的。而集群模式又被称为分片集群,主要用来提升redis的可扩展性,使redis可以存储更多数据。限于篇幅限制,本文重点讨论学习主从redis主从模式中的一些知识。

什么是主从结构

主从结构是一种常见的系统架构方案,主要为了实现系统的高可用和高性能。主从结构主要有两个角色构成:主节点和从节点。主节点的实例个数通常只有一个,从节点的个数通常有多个。主节点主要用来接受客户端的读写请求,从节点从主节点同步数据最新数据,保持和主节点的数据一致性,然后接受客户端的读请求。可以通过扩展从节点来提升整个集群的读性能。主从结构的主要架构图如下:

在这里插入图片描述

为什么需要主从结构

主从结构中存在多个从节点,这些从节点可以分担大量的读请求,增大整个集群的吞吐量。通过横向增加从节点实例,来线性增加读请求的处理能力。对于读多写少的业务系统比较友好。

但是事情都是有两面性的,所以在主从结构也存在着一些问题:

1.为了保证写入数据的一致性,在主从结构中,只有主节点可以处理写请求,然后其他从节点持续从主节点同步最新数据,来保证主从节点数据的一致性,这个数据同步的过程被称为"主从复制",虽然主从复制的目的是为了实现主从节点节点间的数据一致,但是实际情况中,并不一定能够实现真正的一致性,具体原因我们后面讨论。而且,正是为了保证数据的一致性,集群中每个节点上都保存全量的数据,使整个集群中数据冗余严重,集群可以容纳的数据量并不会随着集群规模的扩大而扩大。

2.主从结构中还有另外一个问题,集群中可以处理的写请求量的主节点只有一个,对于写请求量比较大的业务,会导致主节点负载压力过大,单点故障问题比较严重。

数据一致性如何保证-主从复制

在redis中主从复制的实现主要有以下三个阶段:

全量复制

全量复制时主从库之间进行的第一次数据复制,全量复制主要分为三个步骤:
1.主从库建立连接,从库给主库发送psync命令,表示要进行数据同步,主库收到这个命令后,根据命令的参数来启动复制,psync的参数主要包含了,主库的runid(可以通过info server命令查看)和复制进度offset(从主库的哪个位置开始复制)如果offset参数值为-1表示全量复制,此时主库会回复fullresync响应,表示主库会把当前所有数据都复制给从库。

2.主库将所有数据同步给从库,具体操作就是:主库启动bgsave命令,生成rdb文件,然后将生成的rdb文件发送给从库,从库收到rdb文件后,会先清空当前实例的数据库,然后把收到的rdb加载到内存中。因为全量复制的过程中,对于主库来说,是在子进程中完成,对主线程没有影响,主线程仍然可以对客户端的读写请求进行处理,为了保证数据的一致性,这个过程中主库接收到的写请求,不会记录到rdb文件中,而是保存在一个输出缓冲区(replication buffer)中,需要注意的是,主库会给每一个从库维护一个复制缓冲区。

3.主库将replication buffer中的数据,发送给从库。
该阶段的主要流程如下图:
在这里插入图片描述

长连接广播

当全量复制完毕后,主从库之间会维护一个长连接,这个长连接会实时将主库最新的命令发送给从库,保证两者之间的数据一致性,长连接命令传播是主从复制过程中的常态。

增量复制

是对长连接命令传播方式的一种容错处理。长连接命令传播的过程对网络是强依赖,而网络是不稳定的,最常见的问题就是网络延迟和连接断开,当出现网络问题后,紧接着就会就会出现主从延迟的问题,此时从库中就会存在脏数据。

那么当出现网络问题时,redis是如何进行容错的呢?在redis2.8之前,当主从库之间出现网络闪断后,主从库之间就会进行一次全量的复制,开销很大,在redis2.8之后,redis进行了一定优化:在主库端维护一个环形缓冲区,叫做复制积压缓冲区(repl_backlog_buffer)。在长链接命令传播过程中,主库再将最新数据发送给从库后,还会将这个数据写入一份到复制积压缓冲区中,同时记录写入的最新命令在环形缓冲区中的偏移量(master_repl_offset),主库接收的写请求越多,这个偏移量就会越大。同时从库从主库接收到写请求后,也会在自己本地记录,自己在环形缓冲区中消费数据的偏移量(slave_repl_offset),随着从库消费的数据量不多增多,slave_repl_offset的数值也会不断增大,正常情况下,master_repl_offset和slave_repl_offset在数值上是相同的。但是当主从库之间出现网络异常时,从库不能正常从主库同步数据,那么slave_repl_offset就会停止更新。

当网络恢复后,从库会给主库发送psync命令,同时把自己的slave_repl_offset发送给主库,主库收到从库的slave_repl_offset后,会比较和自己的master_repl_offset之间的差值,如果差值小于 环形缓冲区的容量的话,那么主库就会将差值部分的数据发送给从库,完成增量复制。

如果差值大于缓冲区大小,那么说明网络故障的这段时间内,写请求过多,导致环形缓冲区被覆盖,存在数据丢失,此时该从库据需要和主库进全量复制,才能保证数据的一致性,所以为了避免因为网络故障,导致主从之间进行全量复制,可以根据业务请求量对repl_backlog_buffer的大小进行适当调大。

高可用如何实现-主从切换

主从切换,又称为故障转移。主从切换核心作用是保证集群高可用,当检测到主节点挂掉后,就会从剩余的从节点中选择一个作为从主节点,其余的从节点选择新的主节点作为自己同步数据的对象。

为了实现整个切换过程的自动化,在redis中存在一个特殊的节点,他的工作就是定时的监测集群中主从节点的状态信息,发现情况不对,就立即触发主从切换流程,这个节点有一个很形象的名称叫做"哨兵"。

哨兵节点不处理读写请求,它的核心工作就是实现主从切换。在主从切换的整个过程中,哨兵主要做三件事:监控,选主和通知。

监控

监控:就是哨兵进程周期性对主库,从库发送ping命令,进行健康检查,如果从库没有在规定时间内响应健康检查请求的话,哨兵就会标记从库为下线状态,同样如果主库在规定时间内没有响应哨兵的健康检查请求的话,主库也会被标记为线下状态,由于主从切换是一件比较耗时,且开销比较大的操作,所以对主库下线的判定相对从库更严格。防止误判(主库并没有宕机,但是却判定其下线的情况)带来额外的影响。对于主库下线的判定分为:主观下线和客观下线两种。

主观下线是每个哨兵实例对主库下线状态的标记,也就是每个哨兵实例根据自己对主库健康检查的结果,所得出的结论。可能由于某一时刻,哨兵和主库之间存在网络问题,导致健康检查失败,因此就断定主库宕机下线,就有一定的主观性。

因为一个哨兵对于主库下线的判断具有主观性,所以可以让多个哨兵组成哨兵集群,同时对这个主库进行健康检查,这样可以减少由于网络故障造成的误判。在一个集群中只有大于一半的哨兵节点,同时判断一个主库主观下线,那么这个主库才会标记为客观下线,当一个主库被标记为客观下线后,就会触发主从切换。

选主

当主节点被判定为客观下线后,接下来就开始进行进入第二个阶段了-选主,选主顾名思义就是从剩下的从节点中,选择一个节点作为主节点,那么选择哪一个呢?
选择的过程分为一下4步:

1.过滤掉网络状况不好的从库。参数down-after-millseconds:为判定主从库之间断联的阈值,如果主从之间在这个阈值内,没有进行过通信,那么可以判定主从库之间断联了,如果断联次数超过10次,基本可以断定这个从库网络状态不会要,不适合做为新主库。

2.选择优先级高的从库作为主库,优先级是每个从库的一个参数 slave-priority,我们可以进行配置,比如某个从库配置比较高,我们可以将其优先级设置的更高一些。通过优先级的过滤后,如果存在多个优先级相同的从库的话,那么就会进行下一轮的过滤。

3.和愿主库同步最接近的那个从库作为主库。同步最接近的判定标准就是主从复制过程中,mater_repl_offset和slave_repl_offset之间的差值。差值越小,表示同步最接近。如果仍然存在差值一样的多个从库的话,那么就要进行第三轮的过滤了。

4.第三轮的判断相对简单,选择候选从库中id最小的一个作为新主库,以为每个从库的id都是不一样的,肯定可以选择一个唯一的结果。至此新主库就产生了。

通知

新主库产生后,接下来事情就是讲新主库的信息,更新给其他节点,让其他节点接下来都从自己这里同步最新的数据。同时还要告诉所有的客户端,新主库的信息。那么哨兵如何将新主库的信息告诉其他从库以及客户端的呢。

获取从库的信息:哨兵向主库发送info命令,主库收到这个命令后,将命令的执行结果发送给哨兵,此时哨兵就知道当前集群中从库列表了,从库也就可以和所有从库建立连接,这也是,哨兵监控从库的基础。

对于客户端如何感知新主库信息,是通过让客户端订阅哨兵的发布的信息,来得到最新主库的信息,例如客户端可以订阅哨兵的 +switch-master频道,来监听新主库的信息。

上文详细的描述了redis中主从复制和中从切换的的流程,上文中,我们还讨论到,在主从同步的过程中,中从节点中的数据有可能会出现不一致的情况。具体在那些场景中会产生不一致情况,我们在下一篇文章中讨论。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值