Redis哨兵模式深度解析与实战部署
文章目录
一、Redis哨兵模式理论架构详解
1.1 哨兵模式的核心架构组成
Redis哨兵模式(Sentinel)是一种分布式高可用解决方案,其架构由两大核心部分构成:
哨兵节点(Sentinel Nodes):
- 特殊的Redis节点,不存储数据,仅负责监控与决策
- 通常部署为多节点集群(建议至少3个节点),避免单点故障
- 节点间通过流言协议(Gossip)交换状态信息
数据节点(Data Nodes):
- 包括主节点(Master)和从节点(Slave)
- 主节点负责读写操作,从节点提供数据冗余和读服务
- 主从节点通过复制(Replication)机制保持数据一致
基础架构拓扑图
+----------------+
| Sentinel 1 |
+--------+-------+
|
+--------+-------+
| Sentinel 2 |
+--------+-------+
|
+--------+-------+
| Sentinel 3 |
+--------+-------+
|
+---------------------+---------------------+
| |
+---------v---------+ +---------v---------+ +---------v---------+
| Master (M) | | Slave 1 (R1) | | Slave 2 (R2) |
| IP: 192.168.1.10 | | IP: 192.168.1.11 | | IP: 192.168.1.12 |
| Port: 6379 | | Port: 6379 | | Port: 6379 |
+-------------------+ +-------------------+ +-------------------+
1.2 哨兵节点的核心功能模块
1.2.1 监控模块(Monitoring)
- 三大定时任务:
- 每10秒:向主从节点发送
INFO
命令,获取复制状态与从节点列表 - 每2秒:通过主节点的
__sentinel__:hello
频道发布自身状态,与其他哨兵节点交换信息 - 每1秒:向所有主从节点及哨兵节点发送
PING
命令,检测节点存活状态
- 每10秒:向主从节点发送
1.2.2 决策模块(Decision Making)
主观下线(SDOWN, Subjective Down):
- 单个哨兵节点发现目标节点超过
down-after-milliseconds
时间未响应PING
,判定为SDOWN - 仅针对主节点会触发后续客观下线流程,从节点和哨兵节点SDOWN后无后续操作
- 单个哨兵节点发现目标节点超过
客观下线(ODOWN, Objective Down):
- 当监控同一主节点的哨兵中,超过
quorum
数量的节点认为主节点SDOWN,判定为ODOWN - 仅主节点存在ODOWN状态,是故障转移的前提条件
- 当监控同一主节点的哨兵中,超过
1.2.3 故障转移模块(Failover)
领导者哨兵选举:
- 采用Raft算法的简化版,满足"超过半数节点投票"原则
- 选举过程:
- 发现主节点ODOWN的哨兵节点向其他哨兵发送选举请求
- 其他哨兵节点首次接收到请求时投票
- 获得超过半数+
quorum
投票的哨兵成为领导者 - 选举冲突时等待随机延时后重试
新主节点选举:
- 领导者哨兵按以下优先级筛选新主:
- 过滤掉不健康(连接失败/响应超时)的从节点
- 选择
slave-priority
最高的从节点(值越小优先级越高,默认100) - 优先级相同则选择复制偏移量(replication offset)最大的从节点
- 偏移量相同则选择RunID最小的从节点
- 领导者哨兵按以下优先级筛选新主:
状态更新流程:
- 新主节点执行
SLAVEOF NO ONE
脱离从节点身份 - 其他从节点执行
SLAVEOF new_master_ip new_master_port
指向新主 - 故障主节点恢复后自动成为新主的从节点
- 新主节点执行
1.3 关键配置参数解析
参数名称 | 配置位置 | 作用描述 | 典型值 |
---|---|---|---|
sentinel monitor | 哨兵配置文件 | 定义监控的主节点信息,格式为master-name ip port quorum |
sentinel monitor mymaster 192.168.1.10 6379 2 |
down-after-milliseconds | 主从/哨兵配置文件 | 判定节点主观下线的超时时间(毫秒) | 30000(30秒) |
failover-timeout | 哨兵配置文件 | 故障转移的最大超时时间,通常为down-after-milliseconds 的10倍 |
180000(3分钟) |
parallel-syncs | 哨兵配置文件 | 故障转移时从节点并行同步新主的最大数量,降低主节点负载 | 1 |
slave-priority | 从节点配置文件 | 从节点优先级,值越小优先级越高,0表示不参与主节点选举 | 100 |
二、Redis哨兵模式实战部署指南
2.1 环境规划与准备
2.1.1 资源列表
节点角色 | 操作系统 | 配置 | IP地址 | 主机名 | 端口 |
---|---|---|---|---|---|
主节点 | OpenEuler 24 | 2C4G | 192.168.207.140 | master | 6379 |
从节点1 | OpenEuler 24 | 2C4G | 192.168.207.141 | slave01 | 6379 |
从节点2 | OpenEuler 24 | 2C4G | 192.168.207.142 | slave02 | 6379 |
哨兵节点1 | OpenEuler 24 | 2C4G | 192.168.207.137 | sentinel01 | 26379 |
哨兵节点2 | OpenEuler 24 | 2C4G | 192.168.207.138 | sentinel02 | 26379 |
哨兵节点3 | OpenEuler 24 | 2C4G | 192.168.207.139 | sentinel03 | 26379 |
2.1.2 基础环境配置(所有节点执行)
# 1. 关闭防火墙(避免端口访问限制)
systemctl stop firewalld # 停止防火墙服务
systemctl disable firewalld # 禁止防火墙开机自启
# 2. 关闭SELinux(避免安全策略干扰)
setenforce 0 # 临时关闭SELinux
sed -i "s/^SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config # 永久关闭
# 3. 修改主机名(根据节点角色设置)
# 在master节点执行:
hostnamectl set-hostname master
# 在slave01节点执行:
hostnamectl set-hostname slave01
# 在slave02节点执行:
hostnamectl set-hostname slave02
# 在sentinel01节点执行:
hostnamectl set-hostname sentinel01
# 在sentinel02节点执行:
hostnamectl set-hostname sentinel02
# 在sentinel03节点执行:
hostnamectl set-hostname sentinel03
# 4. 刷新主机名配置
exec bash
2.2 部署Redis主从集群
2.2.1 安装Redis服务(主从节点执行)
# 1. 安装编译依赖
dnf -y install gcc gcc-c++ make tar
# 2. 解压Redis源码包(假设下载的是redis-6.2.4.tar.gz)
tar -zxvf redis-6.2.4.tar.gz -C /usr/src/
# 3. 编译并安装Redis(指定安装路径)
cd /usr/src/redis-6.2.4/
make && make PREFIX=/usr/local/redis install # PREFIX指定安装目录
# 4. 创建软链接方便调用
ln -s /usr/local/redis/bin/* /usr/local/bin/
# 5. 创建配置文件目录
mkdir /etc/redis
2.2.2 主节点配置(master节点)
# 1. 复制默认配置文件
cp /usr/src/redis-6.2.4/redis.conf /etc/redis/6379.conf
# 2. 编辑主节点配置文件
vim /etc/redis/6379.conf
# 以下为关键配置项(行号为Redis 6.2默认配置位置):
bind 127.0.0.1 192.168.207.140 # 75行,监听本地回环地址和节点IP,允许远程访问
port 6379 # 98行,Redis服务端口
daemonize yes # 257行,以守护进程方式运行
pidfile /var/run/redis_6379.pid # 289行,PID文件路径
loglevel notice # 297行,日志级别(notice为普通日志)
logfile "/var/log/redis_6379.log" # 302行,日志文件路径
requirepass redis123 # 新增,设置访问密码(生产环境建议设置)
# 3. 创建系统服务脚本
cat > /etc/systemd/system/redis.service << 'EOF'
[Unit]
Description=Redis Database Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /etc/redis/6379.conf
ExecStop=/usr/local/bin/redis-cli -h 127.0.0.1 -p 6379 shutdown
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# 4. 启动服务并设置开机自启
systemctl daemon-reload
systemctl start redis
systemctl enable redis
# 5. 验证服务启动
netstat -anpt | grep 6379
# 输出示例:tcp 0 0 192.168.207.140:6379 0.0.0.0:* LISTEN
2.2.3 从节点配置(slave01/slave02节点)
# 1. 复制默认配置文件(与主节点相同步骤)
cp /usr/src/redis-6.2.4/redis.conf /etc/redis/6379.conf
# 2. 编辑从节点配置文件(以slave01为例)
vim /etc/redis/6379.conf
# 关键配置项(在主节点配置基础上修改):
bind 127.0.0.1 192.168.207.141 # 75行,修改为从节点IP
port 6379 # 98行,端口保持一致
daemonize yes # 257行,守护进程模式
pidfile /var/run/redis_6379.pid # 289行,PID文件路径
loglevel notice # 297行,日志级别
logfile "/var/log/redis_6379.log" # 302行,日志文件路径
requirepass redis123 # 与主节点密码一致
replicaof 192.168.207.140 6379 # 新增,指定主节点IP和端口(Redis 6.2+使用replicaof替代slaveof)
slave-priority 100 # 新增,从节点优先级(默认100,值越小优先级越高)
# 3. 创建系统服务脚本(与主节点相同)
cat > /etc/systemd/system/redis.service << 'EOF'
[Unit]
Description=Redis Database Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /etc/redis/6379.conf
ExecStop=/usr/local/bin/redis-cli -h 127.0.0.1 -p 6379 shutdown
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# 4. 启动服务并设置开机自启
systemctl daemon-reload
systemctl start redis
systemctl enable redis
# 5. 验证主从复制状态
# 在主节点执行:
redis-cli -h 192.168.207.140 -p 6379 -a redis123
127.0.0.1:6379> info replication
# 输出应包含:
# role:master
# connected_slaves:2
# slave0:ip=192.168.207.141,port=6379,...
# slave1:ip=192.168.207.142,port=6379,...
# 在从节点执行:
redis-cli -h 192.168.207.141 -p 6379 -a redis123
127.0.0.1:6379> info replication
# 输出应包含:
# role:slave
# master_host:192.168.207.140
# master_port:6379
# master_link_status:up
2.3 部署哨兵集群
2.3.1 安装哨兵服务(所有哨兵节点执行)
# 1. 安装编译依赖(与Redis主从节点相同)
dnf -y install gcc gcc-c++ make tar
# 2. 解压Redis源码包(使用与主从相同的源码包)
tar -zxvf redis-6.2.4.tar.gz -C /usr/src/
# 3. 编译并安装Redis(哨兵本质是特殊的Redis节点)
cd /usr/src/redis-6.2.4/
make && make install # 无需指定PREFIX,默认安装到/usr/local/bin
# 4. 创建配置文件目录
mkdir /etc/redis
2.3.2 哨兵节点配置(以sentinel01为例,sentinel02/sentinel03仅IP不同)
# 1. 复制默认配置文件
cp /usr/src/redis-6.2.4/redis.conf /etc/redis/sentinel.conf
# 2. 编辑哨兵配置文件
vim /etc/redis/sentinel.conf
# 关键配置项(注释为配置说明):
port 26379 # 哨兵服务端口,默认26379,与Redis数据端口区分
bind 0.0.0.0 # 监听所有网络接口,允许其他哨兵节点连接
daemonize yes # 以守护进程方式运行
pidfile /var/run/redis-sentinel-26379.pid # 哨兵PID文件
loglevel notice # 日志级别
logfile "/var/log/redis-sentinel.log" # 哨兵日志文件
dir "/tmp" # 持久化文件存储目录(哨兵不存储数据,可设为临时目录)
sentinel monitor mymaster 192.168.207.140 6379 2 # 监控主节点,quorum=2表示至少2个哨兵同意才判定主节点故障
sentinel down-after-milliseconds mymaster 30000 # 主节点30秒未响应判定为SDOWN
sentinel failover-timeout mymaster 180000 # 故障转移超时时间180秒
sentinel parallel-syncs mymaster 1 # 故障转移时从节点并行同步数量1
# 3. 创建系统服务脚本
cat > /etc/systemd/system/redis-sentinel.service << 'EOF'
[Unit]
Description=Redis Sentinel Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-sentinel /etc/redis/sentinel.conf
ExecStop=/usr/local/bin/redis-cli -h 127.0.0.1 -p 26379 shutdown
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# 4. 启动哨兵服务并设置开机自启
systemctl daemon-reload
systemctl start redis-sentinel
systemctl enable redis-sentinel
# 5. 验证哨兵启动
ps -aux | grep redis-sentinel
# 输出示例:root 12345 0.5 0.3 165064 9232 ? Ssl 10:00 0:01 /usr/local/bin/redis-sentinel *:26379 [sentinel]
# 6. 查看哨兵状态
redis-cli -p 26379
127.0.0.1:26379> info sentinel
# 输出应包含:
# sentinel_masters:1
# master0:name=mymaster,status=ok,address=192.168.207.140:6379,slaves=2,sentinels=3
2.4 哨兵集群完整配置文件示例
哨兵配置文件(sentinel.conf)完整内容:
# 基本设置
port 26379 # 哨兵服务端口,默认26379
bind 0.0.0.0 # 监听所有IP,允许远程访问
daemonize yes # 守护进程模式
pidfile "/var/run/redis-sentinel-26379.pid" # PID文件路径
loglevel notice # 日志级别
logfile "/var/log/redis-sentinel.log" # 日志文件
dir "/tmp" # 工作目录,哨兵不存储数据,可设为临时目录
# 监控配置
sentinel monitor mymaster 192.168.207.140 6379 2 # 监控主节点,quorum=2
sentinel down-after-milliseconds mymaster 30000 # 30秒未响应判定为SDOWN
sentinel failover-timeout mymaster 180000 # 故障转移超时时间180秒
sentinel parallel-syncs mymaster 1 # 故障转移时1个从节点并行同步
# 安全设置(生产环境建议启用)
# requirepass sentinel123 # 哨兵认证密码
# masterauth redis123 # 连接主节点的密码
2.5 故障转移实战演练
2.5.1 模拟主节点故障
# 1. 在主节点停止Redis服务
systemctl stop redis
# 2. 在哨兵节点查看状态变化(以sentinel01为例)
redis-cli -p 26379
127.0.0.1:26379> info sentinel
# 等待约30秒后,输出应显示主节点已切换:
# master0:name=mymaster,status=ok,address=192.168.207.141:6379,slaves=2,sentinels=3
# (假设slave01被选为新主,IP为192.168.207.141)
2.5.2 验证新主节点状态
# 1. 在新主节点(假设为slave01)查看角色
redis-cli -h 192.168.207.141 -p 6379 -a redis123
127.0.0.1:6379> info replication
# 输出应显示:
# role:master
# connected_slaves:1 # 原slave02成为新主的从节点
# 2. 在原从节点slave02查看主节点信息
redis-cli -h 192.168.207.142 -p 6379 -a redis123
127.0.0.1:6379> info replication
# 输出应显示:
# role:slave
# master_host:192.168.207.141 # 指向新主节点
2.5.3 原主节点恢复后状态
# 1. 在原主节点(master)重启Redis服务
systemctl start redis
# 2. 查看原主节点角色
redis-cli -h 192.168.207.140 -p 6379 -a redis123
127.0.0.1:6379> info replication
# 输出应显示:
# role:slave
# master_host:192.168.207.141 # 自动成为新主的从节点
三、哨兵模式运维与优化建议
3.1 核心参数调优策略
参数 | 优化场景 | 调整建议 |
---|---|---|
quorum | 多机房部署 | 设置为(哨兵节点数/2)+1 ,确保跨机房选举一致性 |
down-after-milliseconds | 高网络延迟环境 | 调整为(网络RTT*2)+5000 毫秒,避免误判 |
failover-timeout | 大数据量主从同步 | 设置为(数据集大小/网络带宽)*2 秒,确保同步完成 |
parallel-syncs | 高并发场景 | 降低为1,避免新主节点带宽耗尽 |
slave-priority | 人工指定优先级 | 将性能更好的从节点设置为更低优先级(如50) |
3.2 监控与告警配置建议
3.2.1 关键监控指标
- 哨兵状态:
sentinel_master_status
(主节点状态)、sentinel_leader_epoch
(选举纪元) - 节点健康:
redis_instance_status
(节点存活状态)、redis_master_link_status
(主从连接状态) - 复制延迟:
redis_repl_backlog_histlen
(复制积压缓冲区长度)、redis_slave_lag
(从节点延迟)
3.2.2 告警规则设置
- 主节点主观下线:单个哨兵检测到主节点SDOWN时触发预警
- 主节点客观下线:超过
quorum
数量哨兵判定主节点ODOWN时触发紧急告警 - 故障转移超时:超过
failover-timeout
未完成切换时触发告警 - 哨兵节点失联:超过
down-after-milliseconds
时间未收到哨兵心跳时触发告警
3.3 生产环境最佳实践
哨兵节点部署:
- 至少部署3个哨兵节点,且分布在不同物理机/机房
- 哨兵节点配置与数据节点分离,避免资源竞争
容灾演练:
- 每季度进行一次主节点故障转移演练
- 模拟网络分区场景,验证哨兵选举的正确性
配置备份:
- 定期备份Redis主从配置与哨兵配置
- 配置文件中记录当前架构拓扑与负责人信息
安全加固:
- 启用
requirepass
认证,避免未授权访问 - 限制哨兵节点的网络访问权限,仅允许内部通信
- 启用
四、总结
Redis哨兵模式通过分布式监控架构与自动化故障转移机制,为Redis主从集群提供了高可用保障。其核心价值在于:
- 自动化容灾:无需人工干预即可完成主节点故障检测与切换,恢复时间通常在秒级
- 分布式决策:多哨兵节点协作避免单点误判,基于Raft算法的选举机制保证决策一致性
- 无缝兼容:与原生Redis主从架构兼容,无需修改业务代码即可部署
- 轻量级设计:哨兵节点资源消耗低,适合各种规模的集群部署
竞争
容灾演练:
- 每季度进行一次主节点故障转移演练
- 模拟网络分区场景,验证哨兵选举的正确性
配置备份:
- 定期备份Redis主从配置与哨兵配置
- 配置文件中记录当前架构拓扑与负责人信息
安全加固:
- 启用
requirepass
认证,避免未授权访问 - 限制哨兵节点的网络访问权限,仅允许内部通信
- 启用
四、总结
Redis哨兵模式通过分布式监控架构与自动化故障转移机制,为Redis主从集群提供了高可用保障。其核心价值在于:
- 自动化容灾:无需人工干预即可完成主节点故障检测与切换,恢复时间通常在秒级
- 分布式决策:多哨兵节点协作避免单点误判,基于Raft算法的选举机制保证决策一致性
- 无缝兼容:与原生Redis主从架构兼容,无需修改业务代码即可部署
- 轻量级设计:哨兵节点资源消耗低,适合各种规模的集群部署
在实际应用中,合理的架构设计、参数调优与定期演练是保障哨兵模式稳定运行的关键。对于高可用性要求极高的场景,结合哨兵模式与Redis Cluster可进一步提升系统容灾能力,为核心业务提供更坚实的数据访问保障。