Redis主从、哨兵、集群架构原理

1、主从复制

主从全量复制

当为一个master配置一个slave时,不管这个slave是否第一次连接这个master,它都会发送一个PSYNC命令给master请求复制数据。
master收到PSYNC请求后,会在后台进行数据持久化通过bgsave生成最新的rdb快照文件,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。
当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。
在这里插入图片描述

主从部分复制

当master和slave断开重连之后,一般会对整份数据进行复制,从redis2.8版本之后,redis支持断点续传,即支持部分数据的复制。
master会在其北部创建一个复制数据用的缓存队列,缓存了最近一段时间的数据。master和slave都维护了复制的数据的下表offset和进程id,因此当网络断开重连时,slave会发起请求,继续从上次复制的下标开始复制。如果master的进程id发生变化,或者offset太旧已经不在master的缓存队列里,那么会进行一次全量复制。
在这里插入图片描述

2、哨兵模式

架构图:
在这里插入图片描述
sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。
哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)。当redis主节点挂掉之后,会重新选举master节点,这期间redis是不可用的,且只有一个master节点无法支持高并发,一般不推荐。

3、集群模式

槽位定位算法

Redis Cluster 将所有数据划分为 16384 个 slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。
当 Redis Cluster 的客户端来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样当客户端要查找某个 key 时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。
Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。
HASH_SLOT = CRC16(key) mod 16384

Redis集群节点间的通信机制

redis cluster节点间采取gossip协议进行通信
维护集群的元数据(集群节点信息,主从角色,节点数量,各节点共享的数据等)有两种方式:集中式和gossip
集中式:
优点在于元数据的更新和读取,时效性非常好,一旦元数据出现变更立即就会更新到集中式的存储中,其他节点读取的时候立即就可以立即感知到;不足在于所有的元数据的更新压力全部集中在一个地方,可能导致元数据的存储压力。 很多中间件都会借助zookeeper集中式存储元数据。
gossip:
在这里插入图片描述
gossip协议包含多种消息,包括ping,pong,meet,fail等等。
ping: 每个节点都会频繁的给其他节点发送ping消息,告诉其他节点自己的状态,维护的元数据,互相通过ping交换元数据。
meet: 某节点给新加入的节点发送meet命令,让新节点加入到集群中,然后新节点就可以与其他节点通讯。
pong: 对ping和meet消息的返回,包含自己的状态和其他信息,也可以用于信息广播和更新;
fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了。
网络抖动
当发生网络抖动时,突然之间部分连接变得不可访问,然后很快又恢复正常。为解决这种问题,Redis Cluster 提供了一种选项cluster-node-timeout,表示当某个节点持续 timeout 的时间失联时,才可以认定该节点出现故障,需要进行主从切换。如果没有这个选项,网络抖动会导致主从频繁切换 (数据的重新复制)。
Redis集群选举原理分析
当salve发现自己的master变为FAIL状态时,边尝试进行Failover,以期望成为新的master。由于可能有多个从节点,便存在多个从节点竞争的过程,其流程如下:
1、slave发现自己的master变为FAIL状态
2、将自己记录的集群currentEpoch加一,表示竞争成为master的次数加一,并广播FAILOVER_AUTH_REQUEST信息
3、其他所有节点收到信息,master节点会去判断请求者的合法性,并发送FAILOVER_AUTH_ACK,每一个选举周期只会ack一次
4、尝试failover的从节点收集master响应的ACK
5、slave收到超过半数的master的ack后会变成新的master
6、slave广播pong消息
如果一次生命周期内各个从节点收到的ack数量是一样的,没有超过半数,则会从第二步开始,再进行下一轮的选举周期。
注意
从节点不是再主节点一进入FAIL状态就进行选举,而是有一定时间的延迟,计算公式如下:
DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
SLAVE_RANK 表示改从节点已经从master复制的数据总量的rank,rank越小表示数据越新,所以理论上数据越新的从节点越有肯能成为主节点。
集群脑裂数据丢失问题
Redis集群中的某个主从集群,当出现网络分区时,认为主节点FAIL,从节点选举出新的master,网络分区恢复时,会将其中一个主节点变为从节点,这时会有大量的数据丢失。
规避方法可以在redis配置里加上参数:

min-replicas-to-write 1  //写数据成功最少同步的slave数量

注意:这个配置在一定程度上会影响集群的可用性,比如slave要是少于1个,这个集群就算leader正常也不能提供服务了,需要具体场景权衡选择。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值