Redis学习笔记5之哨兵模式-高可用


参考链接:https://www.cnblogs.com/duanxz/p/4701831.html

系统的不可用与可用

不可用

  • 机器死了,宕机
  • JVM OOM 了
  • CPU 满载了
  • 磁盘满了,IO 各种异常

此时的系统无法提供正常服务

可用

当系统出现故障时,还能正常提供部分功能给用户
系统可以自动恢复,全年可用时间 99.99%

redis 一主两从不可用

redis 服务进程挂了
master 节点失效,导致不能写数据
怎么解决:主备切换,当发现 master 不可用时,自动切换 slave 为master
通过 redis 哨兵机制:sentinel

哨兵功能

  • 集群监控
    负责监控 master 和 slave 进程是否工作正常
  • 消息通知
    如果某个 redis 实例故障,哨兵负责发消息报警给管理员
  • 故障转移
    如果 master node 挂掉,会自动选一个 slave 作为 master
  • 配置中心
    如果发生故障转移,通知 client 客户端新的 master 地址

哨兵本身也是分布式部署的,作为哨兵集群工作

  1. 故障转移时,判断一个 master 是宕机,需要大部分哨兵同意才行,涉及到分布式选举问题
  2. 即使哨兵部分节点挂掉了,哨兵集群还是能正常工作的

哨兵的核心知识

  1. 哨兵集群至少需要 3 个节点来保证自己的健壮
  2. 哨兵+redis 主从架构不能保证数据不丢失,只能保证高可用

为什么哨兵只有 2 个节点无法正常工作

+------+      +------+
|  M1  |------|  R2  |
|  s1  |      |  s2  |
+------+      +------+
# 配置哨兵集群s1和s2有1个哨兵认为master宕机,就可以进行切换,同时选举其中一个哨兵来执行故障转移
quarum=1    
# 配置同时满足2个哨兵都运行着,才能允许执行故障转移
# 2/3/4个哨兵z正常配置2,5个哨兵配置3
majority=2
# * 如果是M1进程问题,可以正确的执行故障转移
# * 但是如果是M1和s1所在机器宕机了,这时不满足majority,不会正确执行故障转移

经典的3结点哨兵+主从

	    +------+
	    |  M1  |
	    |  s1  |
	    +------+	 
	       |
+------+   |   +------+
|  R2  |---|---|  R3  |
|  s2  |       |  s3  |
+------+       +------+
# 就算M1和s1所在机器挂了,也能满足
# quarum=2两个哨兵认为master宕机
# majority=2还有两个哨兵存活
quarum=2
majority=2

哨兵模式主备切换导致的数据丢失

导致数据丢失主要有两种原因:异步复制和集群脑裂

异步复制

当master宕机时,如果此时mater内存还有命令未及时同步给slave,当哨兵检测到mater宕机,就会进行故障转移。而未同步的内存数据就丢失了。

集群脑裂

master和哨兵集群由于网络原因,master被误判为宕机,然后哨兵选举出了新的master节点。而此时客户端跟旧的master网络没问题,还一直往旧master写数据,这时就产生了两个master节点提供服务。当我们取恢复旧master和哨兵的网络后,旧master可能变成slave node,此时从新的master同步数据后,原来旧master在和哨兵网络故障时间的数据就丢失了。

减少异步复制和集群脑裂造成的数据丢失

# 要求至少有min-slaves-to-write个slave,数据复制和同步的延迟不能超过min-slaves-max-lag秒
# 要求至少1个slave,数据复制和同步的延迟不能超过10秒
min-slaves-to-write 1
min-slaves-max-lag 10
  1. 减少异步复制的数据丢失
    如果所有的slave都复制数据的时间太长,master会拒绝写请求,降低数据丢失的风险
  2. 减少集群脑裂的数据丢失
    master如果不能给至少1个的slave发送数据,且超过10秒slave没有给自己ack消息,则旧master会拒绝写请求

拒绝客户端的写请求,客户端可以自己做降级限流,将数据缓存本地或写到消息队列,待集群正常工作了,再同步

哨兵的工作原理

sdown和odown转换机制

sdown主观宕机,如果一个哨兵觉得master宕机,就是主观宕机
odown客观宕机,quarum数量个哨兵觉得msater宕机,就是客观宕机

  • sdown达成条件:哨兵 ping msaster超过is-master-down-after-milliseconds毫秒数,就主观认为master宕机
  • sdown和odwon的转换条件:一个哨兵在指定时间内,收到quarum数量的哨兵也主观认为master sdown了,则认为odown了

哨兵和slave集群的相互发现

哨兵相互发现利用redis的pub/sub机制,往__sentinel__:hello这个channel里面发送消息,其他哨兵消费这个消息,感知其他哨兵存在

  1. 每隔两秒,每个哨兵都会往自己监控的master+slave集群的__sentinel__:hello发送自己的host、ip、runid和master的配置
  2. 每个哨兵还会消费自己监控master+slave集群的__sentinel__:hello的消息,感知监控这个集群的其他哨兵
  3. 每个哨兵还会通过这个交换master配置,相互进行监控配置的同步

slave配置的自动纠正

  1. 哨兵会纠正slave的一些配置,比如slave要称为master候选人,哨兵会确保slave已经复制现有的master所有数据
  2. 如果slave连接到了一个错误的master,故障转移之后,哨兵会确保slave连接到正确的master

slave→master的选举算法

如果一个master被认为odwon了,且majority的哨兵同意进行主备切换,会选举一个slave来执行主备切换这个动作,考虑条件:

  1. 跟master断开连接的时长
  2. slave的优先级:replica-priority 100,值越小,优先级越高
  3. 复制数据的offset
  4. run id:run id越小越有可能成为master

配置获取和配置传播

哨兵会从将要成为master的slave节点获取一份新的配置+版本号,进行主备切换

  • 如果成功则把新的master配置通知给其他哨兵
  • 如果失败,在其他哨兵等到failover-timeout后,会继续执行切换,重新获取配置+新版本号

哨兵+主从集群搭建

配置文件

# 绑定本机网卡ip,定义从哪个网卡访问sentinel服务
bind 192.168.56.10
# 端口号,默认26379
port 5000
# 是否守护线程启动,默认no
daemonize yes
# 定义进程文件位置
pidfile /var/run/redis_sentinel_5000.pid
# 定义日志文件位置
logfile /usr/local/redis/logs/redis_sentinel_5000.log
# 设置哨兵工作目录
dir /usr/local/redis/sentinel
# sentinel可以监控多个master-slave集群,可以为每个集群取一个逻辑名字
# 格式:sentinel <option_name> <master_name> <option_value>
# 2表示至少需要2个sentinel认为master宕机,quarum=2
sentinel monitor mymaster 192.168.56.10 6379 2
# 配置master的登陆密码
sentinel auth-pass mymaster 123456
# 超过30秒ping不到master,就主观认为master宕机
sentinel down-after-milliseconds mymaster 30000
# 设置主备切换后,slave从新master同步数据的并发节点数
# 如果是1,表示一个一个同步,一个挂接新master数据同步完了,另一个在挂接新master同步
sentinel parallel-syncs mymaster 3
# 故障转移超时时间,默认3分钟,如果超过3分钟,其他哨兵会重新进行主备切换
sentinel failover-timeout mymaster 180000

分别在各个虚拟机启动哨兵
通过redis-cli -p 6379 DEBUG sleep 30我么可以模拟主master失联30秒
sentinel会重新选举一个master
通过redis-cli访问5000,输入SENTINEL get-master-addr-by-name mymaster
可以观察到master结点已经转移
或者你观察日志

3371:X 07 Jun 2020 15:57:52.742 # Next failover delay: I will not start a failover before Sun Jun  7 16:03:52 2020
3371:X 07 Jun 2020 15:57:53.341 # +config-update-from sentinel dbcad3712228074945785232138c9b4b50d96325 192.168.56.11 5000 @ mymaster 192.168.56.10 6379
3371:X 07 Jun 2020 15:57:53.341 # +switch-master mymaster 192.168.56.10 6379 192.168.56.12 6379
3371:X 07 Jun 2020 15:57:53.342 * +slave slave 192.168.56.13:6379 192.168.56.13 6379 @ mymaster 192.168.56.12 6379
3371:X 07 Jun 2020 15:57:53.342 * +slave slave 192.168.56.11:6379 192.168.56.11 6379 @ mymaster 192.168.56.12 6379
3371:X 07 Jun 2020 15:57:53.342 * +slave slave 192.168.56.10:6379 192.168.56.10 6379 @ mymaster 192.168.56.12 6379
3371:X 07 Jun 2020 15:58:23.392 # +sdown slave 192.168.56.10:6379 192.168.56.10 6379 @ mymaster 192.168.56.12 6379
3371:X 07 Jun 2020 15:58:52.019 # -sdown slave 192.168.56.10:6379 192.168.56.10 6379 @ mymaster 192.168.56.12 6379

可以发现主master从192.168.56.10切换到了192.168.56.12
原来的master恢复后自动变为slave,但是可以发现最后两句日志,slave sdown了
进入客户端命令,输入sentinel slaves mymaster,可以发现

   29) "master-link-down-time"
   30) "1591517017000"
   31) "master-link-status"
   32) "err"

master-link-status error,10机器连接不是12机器
经过排查,是10机器原来为master,并不知道12机器的redis服务密码,因此我们需要手动设置一下
redis-cli登陆10机器,config set masterauth 123456就可以了,重新查看状态,会发现master-link-status ok
或者你master也要提前配置好masterauth,正常情况要求整个集群的密码都是一样的,方便主备切换。

下线sentinel步骤

  1. 停止sentinel进程
  2. 在所有sentinel节点执行:sentinel reset *,清理所有监控master+slave主从架构的状态
  3. 在所有sentinel节点执行:sentinel master mastername,查看所有sentinel对master数量是否达成一致
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值