分析&回答
Redis 的高可用主要依托于主从复制(replication)和 哨兵机制(sentinel)。
主从复制(replication)
Redis里面只支持一个主,不像Mysql、Nginx主从复制可以多主多从。
实现原理:从节点设置了主节点后,通过replication.c#replicationCron方法与master节点建立socket连接,每隔1秒执行一次。连接成功后从节点会创建一个专门处理复制工作的事件处理器,用于命令传播以及接收RDB文件等。如下图:
全量同步和增量同步就不展开了,这里主要看下高可用的情况:
- 主从复制,若主节点出现问题,则不能提供服务,需要人工修改配置将从变主
- 主从复制主节点的写能力单机,能力有限
- 单机节点的存储能力也有限
因此,主从复制并不能满足我们高可用的要求。
哨兵机制(sentinel)
哨兵节点:特殊的状态的redis服务,客户端通过连接sentinel节点,可获取到当前的master节点信息,哨兵尽量为奇数数量,防止脑裂问题(多个leader节点)
监控原理:master节点一定时间没发送心跳请求给sentinel节点的话,会被标记下线,选举新的slave节点为master节点,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性
Redis的哨兵(sentinel) 系统用于管理多个 Redis 服务器,该系统执行以下三个任务:
- 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
- 提醒(Notification):当被监控的某个Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。
自动故障迁移
标记下线的过程(故障转移)failover:
- 标记下线(主观下线):某个sentinel发现master节点超过时间(down-after-miliseconds)没发送心跳请求,该节点被标记为主观下线
- 询问其他监控节点的判定结果:多数认为下线则标记该节点为客观下线
- 通过leader选举出执行操作的sentinel节点(raft算法)
- 先发现故障节点的sentinel开始投票
- 超过半数票的节点作为leader
- sentinel leader节点通过slave no one和slave of指令重新指定master节点
- 原先下线的master节点恢复后会变成slave节点
选举新的master节点的指标:
- 断开连接时长、优先级排序(replica-priority 1)、复制数量(从master同步数据的增量复制数)、进程id(越小越优先)
- 断开时间过长可能丢失选举权
sentinel的几个超时指标:
- failover_start_time:当此选举失败后,与下一次选举之间的间隔时间。默认是当前时间加上1s内的随机毫秒数
- failover_state_change_time:故障转移中标记节点状态变更的时间
- failover_timeout:故障转移过程的超时时间。默认是3分钟
- election_timeout:sentinel选举超时时间,是默认选举超时时间和failover_timeout的最小值。默认是10s
缺点:
- 主从切换过程中的数据丢失:完整数据保存在master当中,同步给slave过程中,master节点宕机,可能导致slave不是完整数据,slave升级成新的master节点,会导致数据丢失
- 写节点无法水平扩容,哨兵机制适用在一主多从的部署当中,数据无法分片,分片需要部署多组主从、
反思&扩展
Redis 的同步机制?
同步机制又分为:
- 全同步是指slave启动时进行的初始化同步。
- 部分同步是指Redis运行过程中的修改同步。
一、全同步
全同步过程如下:
- 在slave启动时,会向master发送一条SYNC指令。
- master收到这条指令后,会启动一个备份进程将所有数据写到rdb文件中去。
- 更新master的状态(备份是否成功、备份时间等),然后将rdb文件内容发送给等待中的slave。
注意,master并不会立即将rdb内容发送给slave。而是为每个等待中的slave注册写事件,当slave对应的socket可以发送数据时,再讲rdb内容发送给slave。
二、部分同步
当Redis的master/slave服务启动后,首先进行全同步。之后,所有的写操作都在master上,而所有的读操作都在slave上。因此写操作需要及时同步到所有的slave上,这种同步就是部分同步。
部分同步过程如下:
- master收到一个操作,然后判断是否需要同步到salve。
- 如果需要同步,则将操作记录到aof文件中。
- 遍历所有的salve,将操作的指令和参数写入到savle的回复缓存中。
- 一旦slave对应的socket发送缓存中有空间写入数据,即将数据通过socket发出去。
喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!