什么是可用性99.99%?就是指在一年内系统可用时间/一年的时间,这个百分比就是系统可用性。
之前讲过redis的主从架构,master负责写,slave负责读,如果slave挂了,不会影响可用性,但如果master挂了,没有redis来负责写,那redis就不可用了,本来redis就是处理大量并发读的,很多新的数据没办法写到redis中,那就会直接去mysql里查,大量请求就会把数据库压垮,那系统就变的不可用了。
那有没有办法让redis主从架构变得高可用呢?这时候哨兵集群要出场了,那什么是哨兵集群呢?就是启动一个哨兵,来监视master和slave节点,如果master节点挂了,自动把其中一个slave节点变成master节点,这个过程又叫做主备切换,也叫故障转移。这个切换过程可能只需要几分钟或者几秒,从而减少系统不可用的时间,达到4个9。
今天给大家讲讲哨兵(sentinel)集群:
哨兵是redis架构中非常重要的一个组件。哨兵集群的功能包括:
1、集群监控:负责监控redis master和slave进程是否正常工作。
2、消息通知:如果某个redis实例有故障,那么哨兵会发报警消息给管理员。
3、故障转移:如果master节点挂掉了,会把slave节点变为master节点。
4、配置中心:如果故障转移发生了,通知client客户端新的master地址。
哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作:
1、故障转移时,判断一个master节点是宕机了,需要大部分哨兵都同意才行,这里涉及到了选举问题。
2、即使部分哨兵节点挂了,哨兵集群还能继续工作。如果哨兵不是集群,那难以保证redis的高可用。
3、推荐使用sentinel2 ,相比sentinel1,sentinel2要稳定很多,算法也简单很多。
哨兵的核心知识:
1、哨兵至少要3个实例,来保证自己的健壮性;
2、哨兵+redis主从架构,只能保证redis高可用,不能保证数据的零丢失;
3、对于哨兵+redis主从架构,需要在测试环境和生产环境进行充足的测试和演练;
为什么哨兵集群只有2个节点无法正常工作?
经典的3节点哨兵集群
哨兵主备切换数据丢失问题:
一、异步复制:
把异步复制的情况通过图片来展示,更加直观表现整个过程
二、集群脑裂:
又叫网络分区;通俗的讲就是一个人本来只有一个脑袋来控制,变成了2个脑袋来控制,就出问题了;
如何解决数据丢失?
min-slaves-to-write 1
min-slaves-max-lag 10
这两个配置的意思是:至少有1个slave,数据复制和同步的延迟不能超过10秒;如果所有的slave,都超过10秒,那master就不再接受任何请求;
通过这两个配置可以减少异步复制和集群脑裂数据丢失。
master同步数据给slave,如果ack在10秒内没有返回,那么master会停止接受任何请求,这样就保证只会丢失10秒的数据,如果没有这个设置,那么你可能会丢更多的数据。
sdown和odown的转换
sdown是主观宕机,就是一个哨兵自己觉得master宕机了,那么就是主观宕机;
odown是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机;
sdown达到的条件很简单,一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机了;
sdown到odown的转换条件:就是一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵觉得一个master也sdown了,那么就认为是odown了,客观认为master宕机了;
哨兵集群的自动发现机制
哨兵相互之间的发现,是通过redis的pub/sub系统实现的。
每隔两秒,每个哨兵都会在__sentinel__:hello channel里发送一个消息,内容是自己的host、ip和runid还有对这个master的监控配置,每个哨兵还会跟其他哨兵交换对master的监控配置,互相进行监控配置的同步;
slave配置的自动纠正
哨兵会负责自动纠正slave的一些配置,比如slave如果被提升为master,哨兵会让其他slave连上新的master,并负责master数据;哨兵可以确保slave连上正确的master;
slave->master选举算法
如果master挂掉了,需要把slave切换为master,需要考虑这些因素:
1、跟master断开连接的时长
如果一个slave跟master断开连接已经超过了down-after-milliseconds的10倍,外加master宕机的时长,那么slave就被认为不适合选举为master
(down-after-milliseconds*10)+milliseconds_since_master_is_in_sdown_state
2、slave优先级
对优先级进行排序,slave-priority(可以配置)越低,优先级越高
3、复制offset
slave-priority相同,如果offset越靠后,优先级就越高
4、runid
如果2,3条件都相同,那么选runid比较小的slave
quorum和majority
每次一个哨兵做主备切换,首先需要quorum数量的哨兵认为odown,然后选举出一个哨兵来做切换,还得满足majority的条件,才能做主备切换;
2个哨兵majority:2;3个哨兵majority:2;4个哨兵majority:2;5个哨兵majority:3;
如果quorum<majority,比如5个哨兵,majority为3,quorum设置为2,那需要3个哨兵授权就可以切换
如果quorum>=majority,那必须quorum数量的哨兵都同意才能切换,比如:5个哨兵,quorum设置为5,那必须5个哨兵都同意
configuraition传播
如果主备切换成功之后,哨兵会把配置通知到slave,slave会比较version,如果version比我本地的新,那就修改相应的配置。
哨兵相关的一些配置
运行端口
port 5000
不修改的只能访问本机
bind 192.168.31.187
文件路径
dir /var/sentinal/5000
类似这种配置,来指定对一个master的监控,给监控的master指定的一个名称,同一套哨兵可以监控其他主从架构。
sentinel monitor master-group-name hostname port quorum
示例:sentinel monitor mymaster 192.168.31.187 6379 2
超过多少毫秒跟一个redis实例断了连接,哨兵就可能认为这个redis实例挂了
sentinel down-after-milliseconds mymaster 30000
执行故障转移的timeout超时时长
sentinel failover-timeout mymaster 60000
新的master做切换之后,同时有多少个slave被切换到去连接新master,重新做同步,数字越低,花费的时间越多。假设你的redis是1个master,4个slave,然后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
查看master的信息
sentinel master mymaster
查看slave的信息
SENTINEL slaves mymaster
查看哨兵的信息
SENTINEL sentinels mymaster
查看当前master的地址
SENTINEL get-master-addr-by-name mymaster
注意:本文归作者所有,未经作者允许,不得转载