一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情
前言
redis主从复制架构中,如果出现了宕机,那resdis就不能正常使用了,影响业务和功能,如何解决这个问题呢?有人说是主从复制+哨兵,那么问题来了,哨兵机制了解吗?我们一起看看吧。
背景
主从复制架构中出现宕机的情况:
- 主Redis宕机 这个相对而言就会复杂一些,需要以下2步才能完成
- 第一步,在从数据库中执行SLAVEOF NO ONE命令,断开主从关系并且提升为主库继续服务
- 第二步,将主库重新启动后,执行SLAVEOF命令,将其设置为其他库的从库,这时数据就能更新回来
- 从Redis宕机 这个相对而言比较简单,在Redis中从库重新启动后会自动加入到主从架构中,自动完成同步数据。在 Redis2.8版本后,主从断线后恢复的情况下实现增量复制。
由于这个手动完成恢复的过程其实是比较麻烦的并且容易出错,所以Redis提供的哨兵(sentinel)的功能 来解决
哨兵机制(sentinel)的高可用
Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。如下图所示:
初始状态:
Server1掉线后状态:
升级Server2为新的主服务器:
哨兵的定时监控
- 每个哨兵节点每10秒会向主节点和从节点发送info命令获取最新拓扑结构图,哨兵配置时只要配置对主节点的监控即可,通过向主节点发送info,获取从节点的信息,并当有新的从节点加入时可以马上感知到
- 每个哨兵节点每隔2秒会向redis数据节点的指定频道上发送该哨兵节点对于主节点的判断以及当前哨兵节点的信息,同时每个哨兵节点也会订阅该频道,来了解其它哨兵节点的信息及对主节点的判断,其实就是通过消息publish和subscribe来完成的
- 每隔1秒每个哨兵会向主节点、从节点及其余哨兵节点发送一次ping命令做一次心跳检测,这个也是哨兵用来判断节点是否正常的重要依据
主观下线和客观下线
主观下线
所谓主观下线,就是单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络 不通等等原因)。sentinel会以每秒一次的频率向所有与其建立了命令连接的实例(master,从服务,其他sentinel)发ping命令,通过判断ping回复是有效回复,还是无效回复来判断实例时候在线(对该sentinel来说是“主观在线”)。sentinel配置文件中的down-after-milliseconds设置了判断主观下线的时间长度,如果实例在downafter-milliseconds毫秒内,返回的都是无效回复,那么sentinel回认为该实例已(主观)下线,修改其flags状态为SRI_S_DOWN。如果多个sentinel监视一个服务,有可能存在多个sentinel的down-aftermilliseconds配置不同,这个在实际生产中要注意。
客观下线
当主观下线的节点是主节点时,此时该哨兵3节点会通过指令sentinel is-masterdown-byaddr寻求其它哨兵节点对主节点的判断,如果其他的哨兵也认为主节点主观线下了,则当认为主观下线的票数超过了quorum(选举)个数,此时哨兵节点则认为该主节点确实有问题,这样就客观下线了,大部分哨兵节点都同意下线操作,也就说是客观下线
图解
哨兵lerder选举流程
如果主节点被判定为客观下线之后,就要选取一个哨兵节点来完成后面的故障转移工作,选举出一个leader的流程如下:
- 每个在线的哨兵节点都可以成为领导者,当它确认(比如哨兵3)主节点下线时,会向其它哨兵发ismaster-down-by-addr命令,征求判断并要求将自己设置为领导者,由领导者处理故障转移;
- 当其它哨兵收到此命令时,可以同意或者拒绝它成为领导者;
- 如果哨兵3发现自己在选举的票数num大于等于(sentinels)/2+1时,将成为领导者,如果没有超过,继续选举
自动故障转移机制
在从节点中选择新的主节点
sentinel状态数据结构中保存了主服务的所有从服务信息,领头sentinel按照如下的规则从从服务列表中挑选出新的主服务:
- 过滤掉主观下线的节点
- 选择slave-priority/ replica-priority最高的节点,如果由则返回没有就继续选择
- 选择出复制偏移量最大的系节点,因为复制偏移量越大则数据复制的越完整,如果由就返回了,没有就继续
- 选择run_id最小的节点
更新主从状态
- 通过slaveof no one命令,让选出来的从节点成为主节点;并通过slaveof命令让其他节点成为其从节 点。
- 将已下线的主节点设置成新的主节点的从节点,当其回复正常时,复制新的主节点,变成新的主节点的 从节点
- 当已下线的服务重新上线时,sentinel会向其发送slaveof命令,让其成为新主的从
哨兵进程的作用
- 监控( Monitoring ): 哨兵( sentinel ) 会不断地检查你的 Master 和 Slave 是否运作正常。
- 提醒( Notification ): 当被监控的某个 Redis 节点出现问题时, 哨兵( sentinel ) 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移( Automatic failover ):当一个Master不能正常工作时,哨兵( sentinel )会开始一次自动故障迁移操作
哨兵配置推荐
sentinel.conf
# 设置端口
port 26379
# 是否守护进程启动
daemonize no
# 守护进程运行的时候需要保留pidfile
pidfile /var/run/redis-sentinel.pid
# 日志文件
logfile "/root/log/sentinel.log"
## sentinel monitor master-group-name hostname port quorum
## quorum的解释如下:
##(1)至少多少个哨兵要一致同意,master进程挂掉了,或者slave进程挂掉了,或者要启动一个 故障转移操作
## (2)quorum是用来识别故障的,真正执行故障转移的时候,还是要在哨兵集群执行选举,选举一 个哨兵进程出来执行故障转移操作
## (3)假设有5个哨兵,quorum设置了2,那么如果5个哨兵中的2个都认为master挂掉了; 2个哨 兵中的一个就会做一个选举,选举一个哨兵出来,执行故障转移; 如果5个哨兵中有3个哨兵都是运行的,那么故障转移才会被允许执行。
# 原文是:Note that whatever is the ODOWN quorum, a Sentinel will require to
# be selected by the majority of the known Sentinels in order to
# start a failover, so no failover can be performed in minority.
sentinel monitor mymaster 127.0.0.1 6379 3
# down-after-milliseconds,超过多少毫秒跟一个redis实例断了连接(ping不通),哨兵就可能认为这个redis实例挂了
sentinel down-after-milliseconds mymaster 30000
# parallel-syncs,新的master别切换之后,同时有多少个slave被切换到去连接新master,重新做同步,数字越低,花费的时间越多
# 比如:master宕机了,4个slave中有1个切换成了master,剩下3个slave就要挂到新的master上面去
# 这个时候,如果parallel-syncs是1,那么3个slave,一个一个地挂接到新的master上面去,1 个挂接完,而且从新的master sync完数据之后,再挂接下一个。
# 如果parallel-syncs是3,那么一次性就会把所有slave挂接到新的master上去
sentinel parallel-syncs mymaster 1
#failover-timeout,执行故障转移的timeout超时时长,Default is 3 minutes.
sentinel failover-timeout mymaster 180000
结束
需要交流学习可以关注公众号【温故知新之java】,互相学习,一起进步。