运维之道 | Redis 哨兵(Sentinel)深入剖析 及 Sentinel 搭建部署(高可用)
前言
Redis高可用概述
在 Web 服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服(99.9%、99.99%、99.999% 等等)。在 Redis 层面,高可用的含义要宽泛一些,除了保证提供正常服务(如主从分离、快速容灾技术 等),还需要考虑数据容量扩展、数据安全等等。
在 Redis 中,实现 高可用的技术 主要包括 持久化
、复制
、哨兵
和 集群
,下面简单说明它们的作用,以及解决了什么样的问题:
- 持久化:持久化是最简单的高可用方法。它的主要作用是 数据备份,即将数据存储在 硬盘,保证数据不会因进程退出而丢失。
- 主从复制:复制是高可用 Redis 的基础,哨兵和集群都是在复制基础上实现高可用的。复制主要实现了数据的多机备份以及对于读操作的负载均衡和简单的故障恢复。缺陷是故障恢复无法自动化、写操作无法负载均衡、存储能力受到单机的限制。
- 哨兵:在复制的基础上,哨兵实现了自动化的故障恢复。缺陷是写操作无法负载均衡,存储能力受到单机的限制。
- 集群:通过集群,Redis 解决了写操作无法负载均衡以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。
主从切换技术的方法是
:当主服务器宕机后,需要手动把一台从服务器切换为主从服务器,这就需要人工干预,既费时费力,还会造成一段时间内服务不可用,这不是一种推荐的方式,更多的时候,我们优先考虑哨兵模式,它是当前企业应用的主流方式。
Redis Sentinel
是 Redis 高可用 的实现方案。Sentinel 是一个管理多个 Redis 实例的工具,它可以实现对 Redis 的 监控、通知、自动故障转移。
一、Redis Sentinel 的基本概念
1、Redis 的 主从复制模式
和 Sentinel 高可用架构
的示意图
2、Redis Sentinel 的架构图
3、Redis Sentinel的主要功能
Sentinel 的主要功能包括:主节点存活检测
、主从运行情况检测
、自动故障转移 (failover)
、主从切换
。Redis 的 Sentinel 最小配置是一主一从
;
Redis 的 Sentinel 系统可以用来管理多个 Redis 服务器,该系统可以执行以下四个任务:
- 监控: Sentinel 会不断的检查
主服务器
和从服务器
是否正常运行; - 通知: 当被监控的某个 Redis 服务器出现问题,Sentinel 通过
API 脚本
向 管理员 或者其他的 应用程序 发送通知; - 自动故障转移: 当
主节点
不能正常工作时,Sentinel 会开始一次自动的故障转移
操作,它会将与失效主节点是主从关系的其中一个从节点
升级为新的 主节点,并且将其他的从节点指向新的主节点
; - 配置提供者: 在 Redis Sentinel 模式下,客户端应用在初始化时连接的是
Sentinel 节点集合
,从中获取 主节点 的信息;
4、主观下线和客观下线
默认情况下,每个 Sentinel 节点会以 每秒一次
的频率对 Redis 节点
和 其它 的 Sentinel 节点
发送PING 命令
,并通过节点的回复
来判断节点是否在线
。
- 主观下线: 主观下线 适用于所有
主节点
和从节点
。如果在down-after-milliseconds
毫秒内,Sentinel 没有收到目标节点 的有效回复
,则会判定该节点 为 主观下线
; - 客观下线: 客观下线 只适用于
主节点
。如果 主节点 出现故障,Sentinel 节点会通过sentinel is-master-down-by-addr
命令,向其它 Sentinel 节点询问对该节点的 状态判断。如果超过<quorum> 个数
的节点判定主节点 不可达
,则该 Sentinel 节点会判断主节点 为 客观下线
。
5、Sentinel的通信命令
Sentinel 节点连接一个 Redis 实例的时候,会创建 cmd
和 pub/sub
两个 连接。Sentinel 通过 cmd 连接给 Redis 发送命令,通过 pub/sub 连接到 Redis 实例上的其他 Sentinel 实例。
Sentinel与Redis主节点和从节点交互的命令
命令 | 作 用 |
---|---|
PING | Sentinel 向 Redis 节点发送 PING 命令,检查节点的状态 |
INFO | Sentinel 向 Redis 节点发送 INFO 命令,获取它的 从节点信息 |
PUBLISH | Sentinel 向其监控的 Redis 节点 sentinel:hello 这个 channel 发布 自己的信息 及 主节点 相关的配置 |
SUBSCRIBE | Sentinel 通过订阅 Redis 主节点 和 从节点 的 sentinel:hello 这个 channnel,获取正在监控相同服务的其他 Sentinel 节点 |
Sentinel 与 Sentinel 交互的命令
命令 | 作 用 |
---|---|
PING | Sentinel 向其他 Sentinel 节点发送 PING 命令,检查节点的状态 |
SENTINEL:is-master-down-by-addr | 和其他 Sentinel 协商 主节点 的状态,如果 主节点 处于 SDOWN 状态,则投票自动选出新的 主节点 |
6、Redis Sentinel的工作原理
每个 Sentinel 节点都需要 定期执行 以下任务
每个 Sentinel 以 每秒钟 一次的频率
,向它所知的 主服务器、从服务器 以及其他 Sentinel 实例 发送一个 PING 命令
。
如果一个 实例(instance)距离 最后一次 有效回复 PING 命令的时间
超过 down-after-milliseconds
所指定的值,那么这个实例会被 Sentinel 标记为 主观下线
。
如果一个 主服务器 被标记为 主观下线,那么正在监视这个主服务器的所有 Sentinel 节点,要以每秒一次的频率确认主服务器的确进入了主观下线状态。
如果一个 主服务器 被标记为 主观下线,并且有足够数量的 Sentinel(至少要达到 配置文件 指定的数量)在指定的 时间范围内同意这一判断
,那么这个 主服务器 被标记为 客观下线。
在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率
,向它已知的所有 主服务器
和 从服务器
发送INFO 命令
。当一个 主服务器 被 Sentinel 标记为 客观下线 时,Sentinel 向下线主服务器 的所有从服务器 发送 INFO 命令的频率,会从 10 秒一次改为 每秒一次。
Sentinel 和其他 Sentinel 协商 主节点 的状态,如果 主节点 处于 SDOWN 状态,则投票自动选出新的 主节点。将剩余的从节点指向新的主节点进行数据复制。
当没有足够数量的 Sentinel 同意主服务器下线时,主服务器的客观下线状态就会被移除。当主服务器重新向Sentinel 的PING命令返回有效回复时,主服务器的主观下线状态就会被移除
。
注意:一个有效的 PING 回复可以是:+PONG、-LOADING 或者 -MASTERDOWN。如果 服务器 返回除以上三种回复之外的其他回复,又或者在 指定时间 内没有回复 PING 命令, 那么 Sentinel 认为服务器返回的回复 无效(non-valid)。
二、Redis Sentinel搭建
1、Redis Sentinel 部署须知
- 一个稳健的 Redis Sentinel 集群,应该使用至少
三个 Sentinel 实例
,并且保证讲这些实例放到 不同的机器 上,甚至不同的 物理区域 - Sentinel 无法保证
强一致性
。 - 常见的 客户端应用库
都支持 Sentinel
。 - Sentinel 需要通过不断的
测试
和观察
,才能保证高可用。
2、Redis Sentinel 节点规划
服务类型 | 主从复制 | IP | Port |
---|---|---|---|
Redis | Master | 192.168.182.11 | 16379 |
Redis | slave - 1 | 192.168.182.11 | 26379 |
Redis | slave - 2 | 192.168.182.11 | 36379 |
Sentinel | - | 192.168.182.11 | 16380 |
Sentinel | - | 192.168.182.11 | 26380 |
Sentinel | - | 192.168.182.11 | 36380 |
3、Redis-Server (主从复制)配置部署
- 分别在
/usr/local/bin/sentinel
目录下创建 sentinel-1、sentinel-2、sentinel-3 文件夹
[root@localhost sentinel]# mkdir sentinel-1 sentinel-2 sentinel-3
[root@localhost sentinel]# ls
sentinel-1 sentinel-2 sentinel-3
- 将
redis.conf
配置文件分别拷贝至 sentinel-1、sentinel-2、sentinel-3 文件夹下
[root@localhost bin]# cp redis.conf sentinel/sentinel-1
[root@localhost bin]# cp redis.conf sentinel/sentinel-2
[root@localhost bin]# cp redis.conf sentinel/sentinel-3
分别修改三份配置文件如下:
PS:配置文件务必要按顺序修改,否则会报错无法识别master
- 主节点:redis-16379
daemonize yes
pidfile /var/run/redis-16379.pid
logfile /var/log/redis/redis-16379.log
por