Redis哨兵 - 故障自动转移

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Sentinel 的核心配置:sentinel monitor mymaster 127.0.0.1 6379 2监控的主节点的名字、IP 和端口,最后一个2的意思是有几台 Sentinel 发现有问题,就会发生故障转移

相关链接

redis-GitHub-配置文件下载:https://github.com/redis/redis

redis 官网配置文件:https://redis.io/topics/config

redis哨兵原理 - 思维导图:https://kdocs.cn/l/spXDj5U6vDKF

实战演示的服务节点分布图 :https://kdocs.cn/l/sk1lDLmDbLqY

redis 主从复制搭建:https://blog.mailjob.net/posts/1586519326.html

redis广播:https://blog.mailjob.net/posts/2416487960.html

优秀文章: http://redis.cn/articles/20181020001.html

搭建步骤

# 让sentinel服务后台运行
daemonize yes
Sentinel 的核心配置:
sentinel monitor mymaster 127.0.0.1 6379 2
监控的主节点的名字、IP 和端口,
最后一个2的意思是有几台 Sentinel 发现有问题,就会发生故障转移
例如 配置为2,代表至少有2个 Sentinel 节点认为主节点 不可达,那么这个不可达的判定才是客观的。
对于设置的越小,那么达到下线的条件越宽松,反之越严格。一般建议将其设置为 Sentinel 节点的一半加1
注意:最后的参数不得大于conut(sentinel)
sentinel down-after-millseconds mymaster 30000
这个是超时的时间(单位为毫秒)。打个比方,当你去 ping 一个机器的时候,多长时间后仍 ping 不
通,那么就认为它是有问题
sentinel parallel-syncs mymaster 1
当 Sentinel 节点集合对主节点故障判定达成一致时, Sentinel 领导者节点会做故障转移操作,选出新
的主节点,原来的从节点会向新的主节点发起复制操 作, parallel-syncs 就是用来限制在一次故障转移
之后,每次向新的主节点发起复制操作的从节点个数,指出 Sentinel 属于并发还是串行。1代表每次只
能 复制一个,可以减轻 Master 的压力

sentinel auth-pass master-name password
如果 Sentinel 监控的主节点配置了密码,sentinel auth-pass 配置通过添加主节点的密码,防止
Sentinel 节点对主节点无法监控。
sentinel failover-timeout mymaster 180000
表示故障转移的时间(单位:毫秒)

Sentinel命令

sentinel是一个特殊的redis节点,它有自己专属的api;

1. sentinel masters 显示被监控的所有master以及它们的状态.
2. sentinel master 显示指定master的信息和状态;
3. sentinel slaves 显示指定master的所有slave以及它们的状态;
4. sentinel get-master-addr-by-name 返回指定master的ip和端口, 如果正在进行failover或者
   failover已经完成,将会显示被提升 为master的slave的ip和端口。
5. sentinel failover 强制sentinel执行failover,并且不需要得到其他sentinel的同意。 但是failover
   后会将最新的配置发送给其他 sentinel。

哨兵原理

为什么要做哨兵?

Redis 主从复制有一个缺点,当主机 Master 宕机以后,我们需要人工解决切换,如使用 slaveof no one 。

实际上主从复制 并没有实现高可用。

高可用侧重备份机器, 利用集群中系统的冗余,当系统中某台机器发生损坏的时候,其他后备的机器
可以迅速的接替它来启动服务

实现逻辑

Redis Sentinel 一个分布式架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节
点会对数据节点和其余 Sentinel 节点进行监 控,当它发现节点不可达时,会对节点做下线标识。
如果被标识的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数 Sentinel 节点都认为主节点
不可达时,它们会选举出一个 Sentinel 节点来 完成自动故障转移的工作,同时会将这个变化实时通知
给 Redis 应用方。

可查看上文中【实战演示的服务节点分布图 】转移图

Redis Sentinel 具有以下几个功能:

监控:Sentinel 节点会定期检测 Redis 数据节点、其余 Sentinel 节点是否可达
通知:Sentinel 节点会将故障转移的结果通知给应用方 主节点故障转移: 实现从节点晋升为主节
点并维护后续正确的主从关系
配置提供者: 在 Redis Sentinel 结构中,客户端在初始化的时候连接的是 Sentinel 节点集合 ,从
中获取主节点信息。

Redis Sentinel 包含多个节点好处:

对于节点的故障判断是由多个 Sentinel 节点共同完成,这样可以有效地防止误判。
Sentinel 节点集合是由若干个 Sentinel 节点组成的,这样即使个别 Sentinel 节点不可用,整个
Sentinel 节点集合依然是健壮的。

哨兵监控原理

请查阅上文中的【redis发布订阅】

img

三个定时任务
首先要讲的是内部 Sentinel 会执行以下三个定时任务。
每10秒每个 Sentinel 对 Master 和 Slave 执行一次 Info Replication 。
每2秒每个 Sentinel 通过 Master 节点的 channel 交换信息(pub/sub)。
每1秒每个 Sentinel 对其他 Sentinel 和 Redis 执行 ping 。
第一个定时任务,指的是 Redis Sentinel 可以对 Redis 节点做失败判断和故障转移,在 Redis 内部有三
个定时任务作为基础,来 Info Replication 发现 Slave 节点,这个命令可以确定主从关系。
第两个定时任务,类似于发布订阅, Sentinel 会对主从关系进行判定,通过 sentinel:hello 频道交互。
了解主从关系可以帮助更好的自动化操作 Redis 。然后 Sentinel 会告知系统消息给其它 Sentinel 节
点,最终达到共识,同时 Sentinel 节点能够互相感知到对方。

主观下线

​ 首先解析一下什么叫主观下线,所谓主观下线,就是单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。

​ sentinel会以每秒一次的频率向所有与其建立了命令连接的实例(master,从服务,其他sentinel)发ping命令,通过判断ping回复是有效回复,还是无效回复来判断实例时候在线(对该sentinel来说是“主观在线”)。

客观下线

​ 当sentinel监视的某个服务主观下线后,sentinel会询问其它监视该服务的sentinel,看它们是否也认为该服务主观下线,接收到足够数量(这个值可以配置)的sentinel判断为主观下线,既任务该服务客观下线,并对其做故障转移操作。

​ sentinel通过发送 SENTINEL is-master-down-by-addr ip port current_epoch runid,(ip:主观下线的服务id,port:主观下线的服务端口,current_epoch:sentinel的纪元,runid:*表示检测服务下线状态,如果是sentinel 运行id,表示用来选举领头sentinel)来询问其它sentinel是否同意服务下线。

选举领头sentinel

​ 一个redis服务被判断为客观下线时,多个监视该服务的sentinel协商,选举一个领头sentinel,对该redis服务进行古战转移操作。选举领头sentinel遵循以下规则:

​ 所有的sentinel都有公平被选举成领头的资格

​ 所有的sentinel都有且只有一次将某个sentinel选举成领头的机会(在一轮选举中),一旦选举某个sentinel为领头,不能更改

​ sentinel设置领头sentinel是先到先得,一旦当前sentinel设置了领头sentinel,以后要求设置sentinel为领头请求都会被拒绝

​ 每个发现服务客观下线的sentinel,都会要求其他sentinel将自己设置成领头

​ 当一个sentinel(源sentinel)向另一个sentinel(目sentinel)发送is-master-down-by-addr ip port current_epoch runid命令的时候,runid参数不是*,而是sentinel运行id,就表示源sentinel要求目标sentinel选举其为领头

​ 源sentinel会检查目标sentinel对其要求设置成领头的回复,如果回复的leader_runid和leader_epoch为源sentinel,表示目标sentinel同意将源sentinel设置成领头

​ 如果某个sentinel被半数以上的sentinel设置成领头,那么该sentinel既为领头

​ 如果在限定时间内,没有选举出领头sentinel,暂定一段时间,再选举

各个哨兵选举master依据点:

  • 选择健康状态从节点(排除主观下线、断线),排除5秒钟没有心跳的、排除主节点失联超过10*down-after-millisecends。
  • 选择最高优先级中复制偏移量最大的从机。
  • 如果还没有选出来,则按照ID排序,获取 run id 最小的从节点。

为什么要选偏移量最大的:偏移量大,代表复制的数据更全

为什么要选 run id 最小的:runid就是节点的运行id,最小的就是最先启动的,数据可能更全

如何进行故障转移

故障转移分为三个主要步骤

a. 从下线的主服务的所有从服务里面挑选一个从服务,将其转成主服务
sentinel状态数据结构中保存了主服务的所有从服务信息,领头sentinel按照如下的规则从从服务列表中挑选出新的主服务

删除列表中处于下线状态的从服务

删除最近5秒没有回复过领头sentinel info信息的从服务

删除与已下线的主服务断开连接时间超过 down-after-milliseconds*10毫秒的从服务,这样就能保留从的数据比较新(没有过早的与主断开连接)

领头sentinel从剩下的从列表中选择优先级高的,如果优先级一样,选择偏移量最大的(偏移量大说明复制的数据比较新),如果偏移量一样,选择运行id最小的从服务
b. 已下线主服务的所有从服务改为复制新的主服务
挑选出新的主服务之后,领头sentinel 向原主服务的从服务发送 slaveof 新主服务 的命令,复制新master
c. 将已下线的主服务设置成新的主服务的从服务,当其回复正常时,复制新的主服务,变成新的主服务的从服务

常见问题

客户端如何调用redis

Master可能会因为某些情况宕机了,如果在客户端是固定一个地址去访问,肯定是不合理的,所以客户
端请求是请求哨兵,从哨兵获取主机地址的信息,或者是 从机的信息。可以实现一个例子
1、随机选择一个哨兵连接,获取主机、从机信息
2、模拟客户端定时访问,实现简单轮训效果,轮训从节点
3、连接失败重试访问

思路
sentinel节点集合具备了监控、通知、自动故障转移、配置提供着若干功能,也就是说实际上最了解主
节点的就是sentinel节点集合,而各个主节点可以通过 进行标识的,所以,无论是那种编程语言的客户
端,如果需要正确地连接redis sentinel
1. 遍历sentinel节点集合获取一个可用的sentinel节点,sentinel会共享数据,所以从任意一个
sentinel节点获取主节点信息都可以
2. 通过 sentinel get-master-addr-by-name master-name 这个api来获取对应主节点的相关信息
3. 验证当前获取的“主节点”是真正的主节点,这样做的目的是未来放置故障转移期间主节点的变化
4. 保持和sentinel节点集合的“联系”,时刻获取关于主节点的相关“信息”

搭建报错问题

1、异步复制导致数据丢失

因为master->slave的复制是异步,所以可能有部分还没来得及复制到slave就宕机了,此时这些部分数
据就丢失了。

解决方案: 在异步复制的过程当中,通过 min-slaves-max-lag 这个配置,就可以确保的说,一旦 slave 复制数据
和 ack 延迟时间太长,就认为可能 master 宕机 后损失的数据太多了,那么就拒绝写请求,这样就可以
把master宕机时由于部分数据未同步到 slave 导致的数据丢失降低到可控范围内

2、集群脑裂导致数据丢失

脑裂,也就是说,某个master所在机器突然脱离了正常的网络,跟其它slave机器不能连接,但是实际
上master还运行着。

解决方案: 原redis主节点活了以后,会自动变成从节点。不用我们自己处理

哨兵启动报错

root@85cbceb66bad:/data# redis-server /etc/sentinel.conf --sentinel
*** FATAL CONFIG FILE ERROR (Redis 6.0.10) ***
Reading the configuration file, at line 336
>>> 'SENTINEL resolve-hostnames no'
Unrecognized sentinel configuration statement.

这个是由于 docker 按照的 redis 版本和 引入数据卷使用的哨兵配置文件,版本不一致导致的

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
5月前
|
运维 监控 NoSQL
Redis Sentinel哨兵模式部署
Redis Sentinel哨兵模式部署
110 2
|
6天前
|
缓存 NoSQL 网络协议
【Azure Redis】因为Redis升级引发了故障转移后的问题讨论
3:对于Redis的Server Load指标,每秒创建连接数的并发值,是否有建议呢? 【答】:为了避免将缓存推到 100% 服务器负载,建议将连接创建速率保持在每秒 30 个以下。
|
1月前
|
监控 NoSQL 算法
Redis Sentinel(哨兵)详解
Redis Sentinel(哨兵)详解
|
2月前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
3月前
|
运维 监控 NoSQL
【Redis】哨兵(Sentinel)原理与实战全解~炒鸡简单啊
Redis 的哨兵模式(Sentinel)是一种用于实现高可用性的机制。它通过监控主节点和从节点,并在主节点故障时自动进行切换,确保集群持续提供服务。哨兵模式包括主节点、从节点和哨兵实例,具备监控、通知、自动故障转移等功能,能显著提高系统的稳定性和可靠性。本文详细介绍了哨兵模式的组成、功能、工作机制以及其优势和局限性,并提供了单实例的安装和配置步骤,包括系统优化、安装、配置、启停管理和性能监控等。此外,还介绍了如何配置主从复制和哨兵,确保在故障时能够自动切换并恢复服务。
|
4月前
|
监控 NoSQL 算法
Redis问题之哨兵模式中的配置文件会在故障转移后发生什么变化如何解决
Redis问题之哨兵模式中的配置文件会在故障转移后发生什么变化如何解决
|
5月前
|
监控 NoSQL Java
redis哨兵架构
不过为了高可用一般都推荐至少三个哨兵节点。为什么推荐奇数个哨兵节点跟集群奇数个master节点类似。
42 0
redis哨兵架构
|
4月前
|
消息中间件 监控 NoSQL
Redis哨兵改集群
【7月更文挑战第7天】
|
4月前
|
缓存 NoSQL Redis
Redis复制、哨兵
Redis复制、哨兵
43 0