redis有几种高可用方案,每个方案的优缺点?
一、Redis多副本(主从模式)
1、高可靠性,一方面,采用双机主备架构,能够在主库出现故障时自动进行主备切换,从库提升为主库提供服务,保证服务平稳运行。另一方面,开启数据持久化(RDB和AOF)功能和配置合理的备份策略,能有效的解决数据误操作和数据异常丢失的问题。
2、读写分离策略,从节点可以扩展主库节点的读能力,有效应对大并发量的读操作。
缺点:
- 没有自动选主机制,需要人工指定某个节点为主节点,然后再恢复成主从结构,本质上无法实现做到高可用。
二、Redis Sentinel(哨兵模式)
1、RedisSentinel集群部署简单 2、能够解决Redis主从模式下的高可用切换问题
3、很方便实现Redis数据节点的线形扩展,轻松突破Redis自身单线程瓶颈,可极大满足对Redis大容量或高性能的业务需求。
4、可以实现一套Sentinel监控一组Redis数据节点或多组数据节点
缺点:
- 由于只有主节点负责写数据,如果有大量的写请求的时候,主节点负载太高,有挂掉的风险
- 集群脑裂 (具体可见下文)
三、Redis Cluster(集群模式)
1、无中心架构
2、数据按照slot存储分布在多个节点,节点间数据共享,可动态调整数据分布。
3、可扩展性,可线性扩展到1000多个节点,节点可动态添加或删除。
4、高可用性,部分节点不可用时,集群仍可用。通过增加Slave做standby数据副本,能够实现故障自动failover,节点之间通过gossip协议交换状态信息,用投票机制完成Slave到Master的角色提升。
5、降低运维成本,提高系统的扩展性和可用性。
Redis Sentinel 工作原理
1、多实例Sentinel 部署架构图
2、先了解一下哨兵集群中节点的三个定时任务
-
第一个定时任务: 每个sentinel节点每隔1s向所有的master、slaver、别的sentinel节点发送一个PING命令
作用:心跳检测
-
第二个定时任务: 每个sentinel每隔2s都会向master的sentinel:hello这个channel中发送自己掌握的集群信息和自己的一些信息(比如host,ip,run id),这个是利用redis的pub/sub功能,每个sentinel节点都会订阅这个channel,也就是说,每个sentinel节点都可以知道别的sentinel节点掌握的集群信息
作用:信息交换,了解其他sentinel节点的信息和他们对于主节点的判断
-
第三个定时任务: 每个sentinel节点每隔10s都会向master和slaver发送INFO命令
作用:发现最新的集群拓扑结构
3、工作过程:(简单讲)
-
监控
不断的检查master和slave是否正常运行。master存活检测、master与slave运行情况检测 -
通知(提醒)
当被监控的服务器出现问题时,向其他(哨兵间,客户端)发送通知。 -
自动故障转移
断开master与slave连接,选取一个slave作为master,将其他slave连接到第新的master,并告知客户端新的服务器地址
注意:哨兵也是一台redis服务器,只是不提供数据服务通常哨兵配置数量为单数
4、具体细节
(1)主观下线
如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)
接着正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态。
(2)客观下线
两个重要参数:
-
quorum:如果要认为master客观下线,最少需要主观下线的sentinel节点个数,一般为(N/2-1);
-
majority :如果确定了master客观下线了,就要把其中一个slaver切换成master,做这个事情的并不是整个sentinel集群,而是sentinel集群会选出来一个sentinel节点来做 ,且需要大多数节点都同意这个sentinel来做故障转移才可以,这个大多数节点就是这个参数
过程:
- 每个主观下线的sentinel节点都会向其他sentinel节点发送主观请求下线的muster的具体信息(主要是ip和端口以及自己的runid ),来询问其它sentinel是否同意服务下线。
- 每个sentinel收到命令之后,会根据发送过来的ip和端口检查自己判断的结果,如果自己也认为下线了,就会回复相应信息(包括msater状态确认信息,以及leader_runid )
- sentinel收到回复之后,根据quorum的值,判断达到这个值,如果大于或等于,就认为这个master客观下线
几个注意的点
- 如果sentinel节点个数5,quorum=2,majority=3,那就是3个节点同意就可以,如果quorum=5,majority=3,这时候majority=3就不管用了,需要5个节点都同意才可以。
- 选择领头sentinel的过程符合先到先得的原则
- 如果没有一个sentinel达到了majority的数量,等一段时间,重新选举
- 当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
- 若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。或者 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。
4、故障转移
选择哪一个slaver节点来作为master?
在进行选择之前需要先剔除掉一些不满足条件的slaver,这些slaver不会作为变成master的备选
-
剔除列表中已经下线的从服务(经常在线的)
-
剔除有5s没有回复sentinel的info命令的slaver(响应快的)
-
剔除与已经下线的主服务连接断开时间超过 down-after-milliseconds*10+master宕机时长的slaver(离上次和主节点交互最近的节点)
master选举优先级:
- 选择优先级最高的节点,通过sentinel配置文件中的replica-priority配置项,这个参数越小,表示优先级越高
- 如果第一步中的优先级相同,选择offset最大的,offset表示主节点向从节点同步数据的偏移量,越大表示同步的数据越多
- 如果第二步offset也相同,选择run id较小的
后续处理:
- 领头sentinel向别的slaver发送slaveof命令,告诉他们新的master
- 如果之前的master重新上线时,领头sentinel同样会给起发送slaveof命令,将其变成从节点
附:集群脑裂
集群脑裂,就是一个集群中出现了两个master,何以产生?当集群中的master的网络出现了问题,和集群中的slaver和sentinel通信出现问题,但是本身并没有挂,见下图
由于sentinel连接不上master,就会重新选择一个新的slaver变成master,这时候如果client还么有来得及切换,就会把数据写入到原来的那个master中,一旦网络恢复,原来的master就会被变成slaver,从新的master上复制数据,那client向原来的master上写的数据就丢失了。
解决:设置至少有一个slaver和master数据同步延迟不超过10s ,如果所有的slaver都超过10s,那master就会拒绝接收请求