目录
简介
在分布式系统架构中,Redis作为高性能键值存储中间件,其可用性直接影响业务稳定性。单节点Redis存在单点故障风险,一旦宕机将导致缓存层失效,甚至引发级联故障。Redis哨兵模式(Sentinel)通过引入轻量级的监控与自动故障转移机制,完美解决了这一问题。
一、Redis哨兵模式概述
1.1 为什么需要哨兵模式?
在传统的一主多从Redis架构中,从节点虽能实现数据冗余和读写分离,但主节点故障时需要手动切换,存在以下痛点:
- 手动切换耗时费力,影响服务连续性
- 故障发现不及时,可能导致长时间服务不可用
- 人工操作易出错,存在误操作风险
哨兵模式(Sentinel)正是为解决这些问题而生,它具备以下核心能力:
- 自动监控主从节点运行状态
- 主节点故障时自动执行故障转移
- 多哨兵节点协作决策,避免单点误判
1.2 哨兵模式架构组成
哨兵模式的基础架构由两部分组成:
- 哨兵节点(Sentinel Node):
- 特殊的Redis节点,不存储数据
- 独立进程,通常部署多个(建议至少3个)
- 负责监控和决策
- 数据节点(Data Node):
- 包括主节点(Master)和从节点(Slave)
- 存储实际Redis数据
- 主节点提供写服务,从节点提供读服务
最基础的哨兵架构示意图:
S1 ----监控---- M
S2 ----监控---- R1(Slave of M)
S3 ----监控---- R2(Slave of M)
1.3 核心工作原理
哨兵节点通过三大定时任务实现监控:
- 每10秒:向主从节点发送
INFO
命令,获取从节点列表和状态 - 每2秒:向主从节点和其他哨兵发送自身信息,实现哨兵发现
- 每1秒:向所有节点发送
PING
命令,检测节点存活状态
故障判定流程:
- 主观下线(SDOWN):单个哨兵发现节点超时未响应
PING
,认为其"主观下线" - 客观下线(ODOWN):当超过
quorum
个哨兵都认为主节点主观下线时,判定为"客观下线"(从节点和哨兵只有主观下线)
故障转移流程:
- 哨兵节点通过Raft算法选举领导者哨兵
- 领导者哨兵从从节点中挑选新主:
- 过滤不健康的从节点
- 选择优先级最高的从节点(
replica-priority
配置) - 优先级相同则选复制偏移量最大的(数据最新)
- 仍相同则选
runID
最小的
- 执行主从关系重配置:
- 新主执行
SLAVEOF NO ONE
- 其他从节点指向新主
- 旧主恢复后自动成为新主的从节点
二、环境准备
2.1 节点规划表
操作系统 |
配置 |
IP地址 |
主机名 |
角色 |
OpenEuler24 |
2C4G |
192.168.207.131 |
sentinel01 |
哨兵节点 |
OpenEuler24 |
2C4G |
192.168.207.165 |
sentinel02 |
哨兵节点 |
OpenEuler24 |
2C4G |
192.168.207.166 |
sentinel03 |
哨兵节点 |
OpenEuler24 |
2C4G |
192.168.207.167 |
master |
主节点 |
OpenEuler24 |
2C4G |
192.168.207.168 |
slave01 |
从节点 |
OpenEuler24 |
2C4G |
192.168.207.169 |
slave02 |
从节点 |
2.2 基础环境配置(所有节点执行)
# 1. 关闭防火墙(避免端口阻塞)
systemctl stop firewalld # 停止防火墙服务
systemctl disable firewalld # 禁止防火墙开机自启
# 2. 关闭内核安全机制(SELinux)
setenforce 0 # 临时关闭SELinux
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config # 永久关闭
# 3. 修改主机名(根据节点角色设置)
# 在sentinel01节点执行:
hostnamectl set-hostname sentinel01
# 在sentinel02节点执行:
hostnamectl set-hostname sentinel02
# 在sentinel03节点执行:
hostnamectl set-hostname sentinel03
# 在master节点执行:
hostnamectl set-hostname master
# 在slave01节点执行:
hostnamectl set-hostname slave01
# 在slave02节点执行:
hostnamectl set-hostname slave02
# 4. 使主机名修改生效(重启或刷新hostname)
exec bash # 刷新当前shell会话,使主机名立即生效
配置解释:
- 关闭防火墙和SELinux是为了确保节点间通信畅通,避免6379(Redis)和26379(哨兵)端口被拦截
- 正确设置主机名便于后续管理和识别节点角色
-
exec bash
命令用于在不重启的情况下刷新主机名配置
三、部署Redis主从集群
3.1 安装Redis服务(主从节点均执行)
# 1. 安装编译依赖
yum -y install gcc gcc-c++ make # 安装GCC编译器和make工具,用于编译Redis源码
# 2. 解压Redis源码
tar -zxvf redis-6.2.4.tar.gz -C /usr/src/ # 将Redis源码解压到/usr/src目录
# 3. 编译并安装Redis
cd /usr/src/redis-6.2.4/ # 进入Redis源码目录
make && make PREFIX=/usr/local/redis install # 编译并安装到/usr/local/redis目录
# 4. 创建软链接方便命令调用
ln -s /usr/local/redis/bin/* /usr/local/bin/ # 将Redis命令链接到系统路径
# 5. 创建配置文件目录
mkdir /etc/redis # 创建Redis配置文件存放目录
# 6. 复制默认配置文件
cp /usr/src/redis-6.2.4/redis.conf /etc/redis/6379.conf # 复制默认配置并命名为6379.conf
配置解释:
-
gcc
和make
是编译Redis源码的必要工具 -
PREFIX
参数指定Redis的安装路径,避免与系统默认路径冲突 - 软链接使
redis-cli
、redis-server
等命令可在任意目录执行 - 配置文件单独存放便于管理和维护
3.2 编写系统服务脚本(主从节点均执行)
# 创建Redis系统服务脚本
cat > /etc/systemd/system/redis.service << 'EOP'
[Unit]
Description=Redis # 服务描述
After=network.target # 网络服务启动后启动Redis
[Service]
Type=forking # 后台运行模式
ExecStart=/usr/local/redis/bin/redis-server /etc/redis/6379.conf # 启动命令及配置文件
WantedBy=multi-user.target # 多用户模式下启动
[Install]
EOP
配置解释:
-
systemd
服务脚本允许通过systemctl
命令管理Redis服务 -
ExecStart
指定Redis服务器的启动命令和配置文件路径 -
WantedBy=multi-user.target
确保系统进入多用户模式时自动启动Redis
3.3 主节点(master)配置
# 编辑Redis配置文件
vim /etc/redis/6379.conf
# 主要配置修改内容:
bind 127.0.0.1 192.168.207.167 # 监听本地回环地址和节点IP,允许远程访问
port 6379 # Redis服务端口(默认98行存在)
daemonize yes # 以守护进程方式运行(默认257行,修改为yes)
pidfile /var/run/redis_6379.pid # PID文件路径(默认289行存在)
logfile "/var/log/redis_6379.log" # 日志文件路径(添加到203行左右)
loglevel notice # 日志级别(默认297行存在)
# 启动服务并设置开机自启
systemctl daemon-reload # 重新加载systemd配置
systemctl start redis # 启动Redis服务
systemctl enable redis # 设置开机自启
# 检查端口监听
netstat -anpt | grep 6379 # 查看6379端口是否正常监听
配置解释:
-
bind
配置允许Redis监听特定IP,生产环境建议只监听必要IP -
daemonize yes
使Redis在后台运行,不占用终端 -
logfile
指定日志文件位置,便于排查问题 -
netstat
命令用于验证Redis服务是否正常启动并监听端口
3.4 从节点(slave01/slave02)配置
# 以slave01为例,slave02配置类似
vim /etc/redis/6379.conf
# 主要配置修改内容(与主节点类似):
bind 127.0.0.1 192.168.207.168 # 从节点IP
port 6379 # 端口不变
daemonize yes # 守护进程模式
pidfile /var/run/redis_6379.pid # PID文件
logfile "/var/log/redis_6379.log" # 日志文件
loglevel notice # 日志级别
# 最重要配置:设置主节点关系
replicaof 192.168.207.167 6379 # 指定主节点IP和端口(添加到配置文件末尾)
# 启动服务并设置开机自启(与主节点相同)
systemctl daemon-reload
systemctl start redis
systemctl enable redis
# 检查端口监听
netstat -anpt | grep 6379
配置解释:
- 从节点配置与主节点基本相同,唯一区别是通过
replicaof
命令指定主节点 -
replicaof
命令告诉从节点从哪个主节点复制数据(Redis 5.0+使用replicaof
,旧版本用slaveof
) - 从节点启动后会自动连接主节点并开始数据同步
3.5 验证主从关系
主节点验证:
redis-cli # 连接Redis客户端
127.0.0.1:6379> info replication # 查看复制状态
# 输出关键信息解释:
# Replication role:master # 角色为主节点
# connected_slaves:2 # 连接的从节点数量
# slave0:ip=192.168.207.168,port=6379, state=online # 从节点1信息
# slave1:ip=192.168.207.169,port=6379, state=online # 从节点2信息
从节点验证:
redis-cli # 连接从节点Redis
127.0.0.1:6379> info replication # 查看复制状态
# 输出关键信息解释:
# Replication role:slave # 角色为从节点
# master_host:192.168.207.167 # 主节点IP
# master_port:6379 # 主节点端口
# master_link_status:up # 主从连接状态正常
四、部署Redis哨兵集群
4.1 部署哨兵节点(所有哨兵节点操作相同)
# 1. 安装编译依赖(与Redis相同)
yum -y install gcc gcc-c++ make
# 2. 解压Redis源码(使用同一源码包)
tar -zxvf redis-6.2.4.tar.gz -C /usr/src/
# 3. 编译Redis(哨兵使用Redis自带的sentinel程序)
cd /usr/src/redis-6.2.4/
make && make install # 编译并安装,无需指定PREFIX,使用默认路径
# 4. 创建配置文件目录
mkdir /etc/redis
# 5. 复制Redis配置文件(哨兵配置基于Redis配置修改)
cp /usr/src/redis-6.2.4/redis.conf /etc/redis/6379.conf
配置解释:
- 哨兵本质是特殊的Redis节点,使用Redis源码编译即可
- 无需单独安装,编译Redis时会生成
redis-sentinel
可执行文件 - 配置文件基于Redis默认配置修改,添加哨兵特有配置
4.2 配置哨兵节点
vim /etc/redis/6379.conf # 编辑哨兵配置文件
# 主要配置修改内容:
bind 0.0.0.0 # 监听所有IP,允许其他节点访问(生产环境可限制IP)
daemonize yes # 守护进程模式
port 26379 # 哨兵默认端口(默认98行,修改为26379)
# 关键哨兵配置(添加到文件末尾):
sentinel monitor master 192.168.207.167 6379 2 # 监控主节点
# 解释:
# sentinel monitor:哨兵监控命令
# master:主节点名称(自定义)
# 192.168.207.167 6379:主节点IP和端口
# 2:quorum参数,至少2个哨兵同意才判定主节点故障
# 其他可选配置(根据需求添加):
sentinel down-after-milliseconds master 5000 # 主节点超时5000ms判定为SDOWN
sentinel failover-timeout master 180000 # 故障转移超时时间180000ms
sentinel parallel-syncs master 1 # 故障转移时同时同步的从节点数
配置解释:
-
bind 0.0.0.0
允许所有IP访问哨兵,便于其他哨兵和数据节点通信 -
port 26379
是哨兵的默认端口,需与Redis服务端口(6379)区分 -
sentinel monitor
是哨兵的核心配置,指定监控的主节点和quorum值 -
down-after-milliseconds
配置决定了哨兵检测节点故障的灵敏度 -
failover-timeout
配置故障转移的最大等待时间
4.3 编写哨兵系统服务脚本
# 创建哨兵系统服务脚本
cat > /etc/systemd/system/redis.service << 'EOP'
[Unit]
Description=Redis Sentinel # 服务描述为哨兵
After=network.target # 网络服务启动后启动
[Service]
Type=forking # 后台运行模式
ExecStart=/usr/local/bin/redis-sentinel /etc/redis/6379.conf # 启动哨兵命令
WantedBy=multi-user.target # 多用户模式启动
[Install]
EOP
配置解释:
- 与Redis服务脚本类似,区别在于
ExecStart
使用redis-sentinel
命令 - 哨兵使用相同的配置文件路径,但端口已修改为26379
- 服务描述明确标识为哨兵,便于管理
4.4 启动哨兵并验证
# 启动哨兵服务
systemctl daemon-reload # 重新加载systemd配置
systemctl start redis # 启动哨兵服务
systemctl enable redis # 设置开机自启
# 检查哨兵进程
ps -aux | grep redis # 应看到redis-sentinel进程
# 连接哨兵查看状态
redis-cli -p 26379 # 连接哨兵端口
127.0.0.1:26379> info sentinel # 查看哨兵信息
# 输出关键信息解释:
# sentinel_masters:1 # 监控的主节点数量
# master:name=master, status=ok # 主节点状态正常
# address=192.168.207.167:6379 # 主节点地址
# slaves=2 # 从节点数量
# sentinels=3 # 哨兵数量(当3个哨兵都启动后显示)
五、实战:模拟主节点故障与故障转移
5.1 手动停止主节点服务
# 在master节点执行:
systemctl stop redis # 停止Redis服务
# 等待片刻(约10-20秒),在哨兵节点查看状态
redis-cli -p 26379 # 连接哨兵
127.0.0.1:26379> info sentinel # 查看哨兵信息
# 关键输出变化:
# master:name=master, status=ok # 状态仍为ok,但地址已变更
# address=192.168.207.169:6379 # 新主节点IP(假设slave02被选为新主)
# slaves=2 # 从节点数量不变,旧主成为新主的从节点
5.2 故障转移原理解析
1. 故障检测阶段:
- 哨兵节点每秒向主节点发送
PING
,主节点停止后超时未响应 - 哨兵sentinel01首先判定主节点主观下线(SDOWN)
- sentinel01向其他哨兵询问是否也认为主节点下线
- 当超过
quorum=2
个哨兵同意时,主节点被判定为客观下线(ODOWN)
2. 领导者选举阶段:
- 发现主节点ODOWN的哨兵发起选举(Raft算法)
- 哨兵A向其他哨兵发送选举请求
- 其他哨兵未投票时会同意A成为领导者
- 当A获得超过半数(≥2)的选票时,成为领导者哨兵
3. 新主选举与重配置阶段:
- 领导者哨兵从从节点中按规则挑选新主(如slave02)
- 对新主执行
SLAVEOF NO ONE
,使其成为主节点 - 其他从节点执行
SLAVEOF 新主IP 6379
- 旧主恢复后自动执行
SLAVEOF 新主IP 6379
,成为从节点
5.3 旧主恢复验证
# 在master节点重新启动Redis服务
systemctl start redis # 启动旧主节点
# 等待片刻后,在哨兵节点查看状态
redis-cli -p 26379
127.0.0.1:26379> info sentinel
# 关键输出:
# master:address=192.168.207.169:6379 # 新主仍为slave02
# slaves=2 # 从节点包括旧主master和另一个从节点
# 旧主节点状态为slave,指向新主
六、哨兵模式的优势
6.1 优势
- 自动化故障转移:无需人工干预,秒级完成主从切换
- 多哨兵协作:基于多数投票机制,避免单点误判
- 高可用性:哨兵自身也是分布式架构,避免哨兵单点故障
- 无缝集成:兼容现有Redis主从架构,配置简单
6.2 生产环境建议
- 哨兵节点数量:建议部署奇数个(3/5/7),至少3个,满足
quorum = (n/2)+1
- 节点部署:哨兵节点应部署在不同物理机/机架,避免共置故障
- 参数调优:
-
down-after-milliseconds
:根据网络延迟设置,默认30000ms -
failover-timeout
:建议设置为down-after-milliseconds * (2n+1)
-
quorum
:设置为哨兵数量的一半+1,如3个哨兵设为2
- 定期演练:定期模拟主节点故障,验证故障转移流程
- 监控告警:监控哨兵状态、主从延迟、故障转移事件
七、总结
Redis哨兵模式通过分布式监控与自动化故障转移机制,为Redis集群提供了强大的高可用性保障。从原理上看,它通过多哨兵协作、Raft选举和智能故障转移,解决了单节点Redis的单点风险;从实践上看,其部署流程清晰,配置简单,能够无缝融入现有架构。
在实际应用中,合理的节点规划、参数调优和定期演练是保障哨兵模式稳定运行的关键。随着云原生技术的发展,哨兵模式作为轻量级高可用方案,将继续在缓存层容灾中发挥重要作用,为关键业务提供稳定的数据访问保障。