害!面试挂在了Redis集群上......

上篇《干货:送你一份新鲜出炉的面试题》里提到了redis集群的三种模式,私下里就这道题和几位熟悉的朋友也交流过,很多答得不是很全面。大多数人平时对redis的使用很熟悉,但是对于这种偏思想与设计的东西却只是略知一二。

那么,今天我们就来聊聊redis集群的三种模式。

画外音:事实上,这道题在小莱的面试经历中被问到的频率还是挺高的。

主从模式

1、架构图

 

 

2、集群介绍

1)主从模式里使用一个redis实例作为主机(master),其余多个实例作为备份机(slave);

2)master用来支持数据的写入和读取操作,而slave支持读取及master的数据同步;

3)在整个架构里,master和slave实例里的数据完全一致;

3、主从复制原理

全量同步

1) 当从节点启动时,会向主节点发送SYNC命令;

2) 主节点接收到SYNC命令后,开始在后台执行保存快照的命令生成RDB文件,并使用缓冲区记录此后执行的所有写命令;

3) 主节点快照完成后,将快照文件和所有缓存命令发送给集群内的从节点,并在发送期间继续记录被执行的写命令;

4) 主节点快照发送完毕后开始向从节点发送缓冲区中的写命令;

5) 从节点载入快照文件后,开始接收命令请求,执行接收到的主节点缓冲区的写命令。

增量同步

主从复制中因网络等原因造成数据丢失场景,当从节点再次连上主节点。如果条件允许,主节点会补发丢失数据给从节点。因为补发的数据远远小于全量数据,可以有效避免全量复制的过高开销。

三种模式主从复制原理基本一致。

4、主节点故障处理方式

主从模式中,每个客户端连接redis实例时都指定了ip和端口号。如果所连接的redis实例因为故障下线了,则无法通知客户端连接其他客户端地址,因此只能进行手动操作。

5、不支持高可用

显而易见,主从模式很好地解决了数据备份的问题,但是主节点因为故障下线后,需要手动更改客户端配置重新连接,这种模式并不能保证服务的高可用。

于是redis集群迎来了哨兵模式......

哨兵模式

1、架构图

 

2、集群介绍

和主从模式不一样的是,哨兵模式中增加了独立进程(即哨兵)来监控集群中的一举一动。客户端在连接集群时,首先连接哨兵,通过哨兵查询主节点的地址,然后再去连接主节点进行数据交互。

如下图所示,如果master异常,则会进行master-slave切换,将最优的一个slave切换为主节点。

 

同时,哨兵持续监控挂掉的主节点,待其恢复后,作为新的从节点加入集群中。

3、主节点故障处理方式/哨兵工作方式

1) 每个哨兵每秒向集群中的master、slave以及其他哨兵发送一个PING命令;

2) 如果某个实例距离最后一次有效回复ping命令的时间超过一定值,则会被标记为主观下线;

3) 如果master被标记为主观下线,那么其他正在监视master的哨兵以每秒的频率确认其确实进入主观下线状态,且数量达到一定值时,master会被标记为下线,然后通知其他的从服务器,修改配置文件,让它们切换主机;

4) 客户端在master节点发生故障时会重向哨兵要地址,此时会获得最新的master节点地址。

4、扩容问题 

哨兵模式的出现虽然解决了主从模式中master节点宕机不能自主切换(即高可用)的问题。但是,随着业务的逐渐增长,不可避免需要对当前业务进行扩容。

常见的扩容方式有垂直和水平扩容两种方式:

  • 垂直扩容:通过增加master内存来增加容量;

  • 水平扩容:通过增加节点来进行扩容,即在当前基础上再增加一个master节点。

虽然垂直扩容方式很便捷,不需要添加多余的节点,但是机器的容量是有限的,最终还是需要通过水平扩容方式来解决。而水平扩容涉及到数据的迁移,且迁移过程中又要保证服务的可用性。因此,数据能不迁移就尽量不要迁移。

显然,哨兵模式无法满足这种情形。因此,redis cluster应运而生。

Redis cluster 模式

1、架构图

 

2、集群介绍

1) redis cluster模式采用了无中心节点的方式来实现,每个主节点都会与其它主节点保持连接。节点间通过gossip协议交换彼此的信息,同时每个主节点又有一个或多个从节点;

2) 客户端连接集群时,直接与redis集群的每个主节点连接,根据hash算法取模将key存储在不同的哈希槽上;

3) 在集群中采用数据分片的方式,将redis集群分为16384个哈希槽。如下图所示,这些哈希槽分别存储于三个主节点中:

  • Master1负责0~5460号哈希槽

  • Master2负责5461~10922号哈希槽

  • Master3负责10922~16383号哈希槽

4) 每个节点会保存一份数据分布表,节点会将自己的slot信息发送给其他节点,节点间不停的传递数据分布表;

5) 客户端连接集群时,通过集群中某个节点地址进行连接。客户端尝试向这个节点执行命令时,比如获取某个key值,如果key所在的slot刚好在该节点上,则能够直接执行成功。如果slot不在该节点,则节点会返回MOVED错误,同时把该slot对应的节点告诉客户端,客户端可以去该节点执行命令。

3、主节点故障处理方式

redis cluster中主节点故障处理方式与哨兵模式较为相像,当约定时间内某节点无法与集群中的另一个节点顺利完成ping消息通信时,则将该节点标记为主观下线状态,同时将这个信息向整个集群广播。

如果一个节点收到某个节点失联的数量达到了集群的大多数时,那么将该节点标记为客观下线状态,并向集群广播下线节点的fail消息。然后立即对该故障节点进行主从切换。等到原来的主节点恢复后,会自动成为新主节点的从节点。如果主节点没有从节点,那么当它发生故障时,集群就将处于不可用状态。

4、扩容问题

在哨兵模式中我们在扩容的时候遇到了问题,那么cluster中我们如何动态上线某个节点呢。当集群中加入某个节点时,哈希槽又是如何来进行分配的?

当集群中加入新节点时,会与集群中的某个节点进行握手,该节点会把集群内的其它节点信息通过gossip协议发送给新节点,新节点与这些节点完成握手后加入到集群中。

然后集群中的节点会各取一部分哈希槽分配给新节点,如下图:

  • Master1负责1365-5460

  • Master2负责6827-10922

  • Master3负责12288-16383

  • Master4负责0-1364,5461-6826,10923-12287

当集群中要删除节点时,只需要将节点中的所有哈希槽移动到其它节点,然后再移除空白(不包含任何哈希槽)的节点就可以了。

少侠留步

看你骨骼清奇,天赋异禀!

送你一份大厂面试秘籍

关注公众号「IT界农民工」回复「面试」即可获取!

关于作者

作者:大家好,我是莱乌,BAT搬砖工一枚。从小公司进入大厂,一路走来收获良多,想将这些经验分享给有需要的人,因此创建了公众号「IT界农民工」。定时更新,希望能帮助到你。

 

推荐阅读

《面试官:谈谈分布式锁的实现》

《干货:送你一份新鲜出炉的面试题》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值