适用场景 & 前置条件
反模式警告(何时不适用)
⚠️ 以下场景不推荐使用本方案:
单机小流量场景:QPS < 1000,单实例足够,引入 Sentinel 反而增加复杂度
需要强一致性:Redis 主从复制是异步的,主节点宕机可能丢失数据,金融交易等场景不适用
已有 Redis Cluster:Redis Cluster 本身提供高可用和分片,无需 Sentinel
对延迟极度敏感:Sentinel 故障切换需要 15-30 秒,实时交易系统可能不满足
云环境托管 Redis:AWS ElastiCache、阿里云 Redis 已提供高可用,无需自建
替代方案对比:
环境与版本矩阵
版本差异说明:
Redis 6.2 vs 7.0:7.0 支持 ACL(访问控制列表)、更好的 Sentinel 性能
Redis 7.0 新增
SENTINEL CONFIG命令,支持动态修改 Sentinel 配置Ubuntu apt 源的 Redis 版本较旧,生产环境建议编译安装最新稳定版
阅读导航
📖 建议阅读路径:
快速上手(30分钟):→ 快速清单 → 实施步骤 Step 1-6 → 验证测试
深入理解(60分钟):→ 最小必要原理 → 实施步骤完整版 → 监控告警 → 最佳实践
故障排查:→ 常见故障与排错 → 调试思路 → FAQ
快速清单(Checklist)
准备阶段
准备3台服务器(或虚拟机),配置网络互通
检查系统版本与内核兼容性(
uname -r)安装 Redis 6.2+(
redis-server --version)配置防火墙开放 6379、26379 端口
实施阶段
配置 Redis 主节点(
/etc/redis/redis.conf)配置 Redis 从节点(2个,指向主节点)
配置 Sentinel 哨兵(3个,监控主节点)
启动所有 Redis 和 Sentinel 服务
验证阶段
测试主从复制(
redis-cli -p 6379 INFO replication)模拟主节点故障(
kill -9主节点 Redis 进程)验证自动故障切换(15-30秒内完成)
验证数据一致性(从节点数据完整)
监控阶段
配置 Prometheus 监控(Redis Exporter)
配置告警规则(主从切换、复制延迟)
配置 Grafana 面板
准备阶段
架构流程图

环境检查与 Redis 安装
目标: 在3台服务器上安装 Redis 并验证版本
RHEL/CentOS 命令:
# 检查系统版本
cat /etc/redhat-release
uname -r
# 安装 Redis(官方 repo)
yum install -y redis
# 配置最新版仓库源
vim /etc/yum.repos.d/redis.repo
[Redis]
name=Redis
baseurl=http://packages.redis.io/rpm/rockylinux8
enabled=1
gpgcheck=1
curl -fsSL https://packages.redis.io/gpg > /tmp/redis.key
sudo rpm --import /tmp/redis.key
sudo yum install redis
Ubuntu/Debian 命令:
# 检查系统版本
lsb_release -a
uname -r
# 安装 Redis
apt update
apt install -y redis-server
# 配置最新版仓库源
sudo apt-get update
sudo apt-get install lsb-release curl gpg
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
# 或使用 PPA 获取新版本(仅在Ubuntu下有效,不支持Debian)
add-apt-repository ppa:redislabs/redis
apt update && apt install -y redis-server
二进制包安装:
# 或编译安装最新版本(推荐生产环境)
# 安装编译插件
# centos
yum install -y gcc make tcl
# debian
apt install build-essential
# 获取最新版安装包
wget https://download.redis.io/redis-stable.tar.gz
tar -zxvf redis-stable.tar.gz && cd redis-stable
make && make install
# 安装到系统路径
cp src/redis-server /usr/local/bin/
cp src/redis-cli /usr/local/bin/
cp src/redis-sentinel /usr/local/bin/
# 创建配置目录
mkdir -p /etc/redis
mkdir -p /var/lib/redis
mkdir -p /var/log/redis
useradd -r -s /bin/false redis
chown -R redis:redis /var/lib/redis /var/log/redis关键参数解释:
1.
make编译时会自动运行测试,确保二进制文件正确2.
/var/lib/redis:Redis 数据目录(RDB/AOF 文件存储位置)3.
useradd -r:创建系统用户(无登录权限),安全运行 Redis
执行前验证:
# 检查编译依赖
gcc --version
make --version
# 预期输出:gcc 8.x+ / make 4.x+
# 检查网络连通性(3台服务器互相测试)
ping -c 3 192.168.1.10 # 主节点
ping -c 3 192.168.1.11 # 从节点1
ping -c 3 192.168.1.12 # 从节点2
执行后验证:
# 检查 Redis 版本
redis-server --version
# 预期输出:Redis server v=7.2.4 [已实测]
# 检查文件权限
ls -ld /var/lib/redis /var/log/redis
# 预期输出:drwxr-xr-x redis redis
# 测试 Redis 启动
redis-server --port 9999 &
redis-cli -p 9999 PING
# 预期输出:PONG
redis-cli -p 9999 SHUTDOWN
常见错误示例:
# 错误1:编译失败
error: 'struct redisServer' has no member named 'xxx'
# 解决:更新 gcc 版本(yum install -y gcc-toolset-11)
# 错误2:权限不足
MISCONF Redis is configured to save RDB snapshots
# 解决:chown redis:redis /var/lib/redis配置防火墙
RHEL/CentOS(firewalld):
# 开放 Redis 端口
firewall-cmd --permanent --add-port=6379/tcp
firewall-cmd --permanent --add-port=26379/tcp
firewall-cmd --reload
# 验证
firewall-cmd --list-ports
# 预期输出:6379/tcp 26379/tcp
Ubuntu/Debian(ufw):
# 开放端口
ufw allow 6379/tcp
ufw allow 26379/tcp
ufw reload
# 验证
ufw status
# 预期输出:6379/tcp ALLOW 26379/tcp ALLOW
iptables(通用):
# 开放端口
iptables -A INPUT -p tcp --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp --dport 26379 -j ACCEPT
# 保存规则
iptables-save > /etc/iptables/rules.v4 # Debian/Ubuntu
service iptables save # RHEL/CentOS 7实施阶段
配置 Redis 主节点
配置文件路径:/etc/redis/redis.conf(主节点:192.168.1.10)
完整配置示例(带逐行注释):
# 网络配置
bind 0.0.0.0 # 监听所有网卡(生产环境建议指定 IP)
protected-mode no # 关闭保护模式(建议配置密码后关闭)
port 6379 # Redis 监听端口
# 通用配置
daemonize yes # 后台运行
pidfile /var/run/redis_6379.pid # PID 文件位置
logfile /var/log/redis/redis.log # 日志文件
dir /var/lib/redis # 数据目录
databases 16 # 数据库数量(默认16个)
# 安全配置
requirepass YourStrongPassword123 # 设置密码(必需!)
masterauth YourStrongPassword123 # 主从复制密码(从节点需要)
# 持久化配置 - RDB
save 900 1 # 900秒内至少1次写入则保存
save 300 10 # 300秒内至少10次写入则保存
save 60 10000 # 60秒内至少10000次写入则保存
stop-writes-on-bgsave-error yes # RDB 失败时停止写入
rdbcompression yes # RDB 压缩
rdbchecksum yes # RDB 校验和
dbfilename dump.rdb # RDB 文件名
# 持久化配置 - AOF(推荐开启)
appendonly yes # 开启 AOF
appendfilename "appendonly.aof" # AOF 文件名
appendfsync everysec # 每秒同步(平衡性能与安全)
no-appendfsync-on-rewrite no # rewrite 时不进行 fsync
auto-aof-rewrite-percentage 100 # AOF 文件增长100%时 rewrite
auto-aof-rewrite-min-size 64mb # AOF 文件最小64MB时 rewrite
# 主从复制配置(主节点无需配置 replicaof)
replica-serve-stale-data yes # 从节点断连时继续提供服务
replica-read-only yes # 从节点只读
repl-diskless-sync no # 使用磁盘同步(稳定)
repl-diskless-sync-delay 5 # 无盘同步延迟
repl-ping-replica-period 10 # 主节点 ping 从节点间隔
repl-timeout 60 # 复制超时时间
repl-backlog-size 1mb # 复制积压缓冲区大小
min-replicas-to-write 1 # 至少1个从节点在线才允许写入
min-replicas-max-lag 10 # 从节点最大延迟10秒
# 内存管理
maxmemory 2gb # 最大内存限制(根据服务器配置调整)
maxmemory-policy allkeys-lru # 内存满时淘汰策略(LRU)
# 慢查询日志
slowlog-log-slower-than 10000 # 记录执行时间超过10ms的命令
slowlog-max-len 128 # 慢查询日志最大长度
# 客户端连接
maxclients 10000 # 最大客户端连接数
timeout 300 # 客户端空闲超时(秒)
关键参数解释:
1.
min-replicas-to-write 1:至少1个从节点在线才允许写入,防止脑裂时数据丢失2.
appendfsync everysec:每秒刷盘一次,平衡性能与数据安全(最多丢失1秒数据)3.
maxmemory-policy allkeys-lru:内存满时使用 LRU 算法淘汰所有键(适合缓存场景)
执行前验证:
# 检查配置文件语法(Redis 7.0+)
redis-server /etc/redis/redis.conf --test-memory 1
# 确认端口未被占用
ss -tunlp | grep 6379
# 预期输出:无输出(端口未占用)
执行后验证:
# 启动 Redis
systemctl start redis
# 或手动启动:
redis-server /etc/redis/redis.conf
# 检查进程
ps -ef | grep redis-server
# 预期输出:redis xxx redis-server 0.0.0.0:6379
# 测试连接(需要密码)
redis-cli -h 192.168.1.10 -p 6379 -a YourStrongPassword123 PING
# 预期输出:PONG [已实测]
# 检查配置
redis-cli -h 192.168.1.10 -a YourStrongPassword123 CONFIG GET requirepass
# 预期输出:1) "requirepass" 2) "YourStrongPassword123"
# 写入测试数据
redis-cli -h 192.168.1.10 -a YourStrongPassword123 SET testkey "hello-redis"
redis-cli -h 192.168.1.10 -a YourStrongPassword123 GET testkey
# 预期输出:hello-redis
常见错误示例:
# 错误1:端口被占用
Could not create server TCP listening socket 0.0.0.0:6379: bind: Address already in use
# 解决:kill 占用端口的进程或修改端口
# 错误2:权限不足
Can't open the log file: Permission denied
# 解决:chown redis:redis /var/log/redis
# 错误3:密码认证失败
NOAUTH Authentication required
# 解决:redis-cli -a YourStrongPassword123
配置Redis从节点
从节点1(192.168.1.11)和从节点2(192.168.1.12)配置差异:
在主节点配置基础上,仅修改以下内容:
# 从节点配置差异
replicaof 192.168.1.10 6379 # 指定主节点 IP 和端口
masterauth YourStrongPassword123 # 主节点密码(必需)
replica-read-only yes # 从节点只读(推荐)
# 可选:修改日志和 PID 文件名(避免冲突)
pidfile /var/run/redis_6379.pid
logfile /var/log/redis/redis.log
执行步骤(在从节点1和从节点2执行):
# 1. 复制主节点配置文件
scp root@192.168.1.10:/etc/redis/redis.conf /etc/redis/redis.conf
# 2. 修改配置文件
vim /etc/redis/redis.conf
# 添加:replicaof 192.168.1.10 6379
# 3. 启动 Redis
systemctl start redis
# 或手动启动
redis-server /etc/redis/redis.conf
执行后验证:
# 从节点检查复制状态
redis-cli -h 192.168.1.11 -a YourStrongPassword123 INFO replication
# 预期输出:
# role:slave
# master_host:192.168.1.10
# master_port:6379
# master_link_status:up
# master_sync_in_progress:0
# 从节点验证数据同步
redis-cli -h 192.168.1.11 -a YourStrongPassword123 GET testkey
# 预期输出:hello-redis [已实测]
# 主节点检查从节点连接
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO replication
# 预期输出:
# role:master
# connected_slaves:2
# slave0:ip=192.168.1.11,port=6379,state=online,offset=xxx
# slave1:ip=192.168.1.12,port=6379,state=online,offset=xxx
常见错误示例:
# 错误1:主从连接失败
master_link_status:down
# 诊断命令:
redis-cli -h 192.168.1.11 -a YourStrongPassword123 INFO replication | grep master_link_down_since
# 解决:检查网络、防火墙、主节点密码
# 错误2:从节点数据不一致
# 诊断:检查复制偏移量
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO replication | grep offset
redis-cli -h 192.168.1.11 -a YourStrongPassword123 INFO replication | grep offset
# 解决:等待同步完成或手动触发 REPLICAOF no one 再重新同步配置Sentinel哨兵
Sentinel 配置文件路径:/etc/redis/sentinel.conf
完整配置示例(3个 Sentinel 节点相同配置):
# Sentinel 基础配置
port 26379 # Sentinel 监听端口
daemonize yes # 后台运行
pidfile /var/run/redis-sentinel.pid # PID 文件
logfile /var/log/redis/sentinel.log # 日志文件
dir /var/lib/redis # 工作目录
# 监控主节点
sentinel monitor mymaster 192.168.1.10 6379 2 # 监控主节点,2票判定下线
sentinel auth-pass mymaster YourStrongPassword123 # 主节点密码
sentinel down-after-milliseconds mymaster 5000 # 5秒无响应判定主观下线
sentinel parallel-syncs mymaster 1 # 故障切换时同时同步的从节点数
sentinel failover-timeout mymaster 180000 # 故障切换超时(3分钟)
# 通知脚本(可选)
# sentinel notification-script mymaster /path/to/notify.sh
# sentinel client-reconfig-script mymaster /path/to/reconfig.sh
# Sentinel 自身保护
sentinel deny-scripts-reconfig yes # 禁止通过 SENTINEL SET 修改脚本路径
关键参数解释:
1.
sentinel monitor mymaster 192.168.1.10 6379 2:•
mymaster:主节点名称(自定义)•
192.168.1.10 6379:主节点地址•
2:至少2个 Sentinel 认为主节点下线才触发故障切换(quorum)
2.
down-after-milliseconds 5000:5秒无响应判定主观下线(SDOWN)3.
parallel-syncs 1:故障切换时,一次只有1个从节点向新主节点同步(减轻负载)
执行步骤(在3台服务器上都执行):
# 1. 创建 Sentinel 配置文件
cat > /etc/redis/sentinel.conf <<'EOF'
port 26379
daemonize yes
pidfile /var/run/redis-sentinel.pid
logfile /var/log/redis/sentinel.log
dir /var/lib/redis
sentinel monitor mymaster 192.168.1.10 6379 2
sentinel auth-pass mymaster YourStrongPassword123
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
EOF
# 2. 设置权限
chown redis:redis /etc/redis/sentinel.conf
chmod 640 /etc/redis/sentinel.conf
# 3. 启动 Sentinel
redis-sentinel /etc/redis/sentinel.conf
# 或使用 systemd(需创建 service 文件)
systemctl start redis-sentinel
systemd service 文件(/etc/systemd/system/redis-sentinel.service):
[Unit]
Description=Redis Sentinel
After=network.target
[Service]
Type=forking
User=redis
Group=redis
ExecStart=/usr/local/bin/redis-sentinel /etc/redis/sentinel.conf
ExecStop=/bin/kill -s TERM $MAINPID
PIDFile=/var/run/redis-sentinel.pid
Restart=always
[Install]
WantedBy=multi-user.target
执行后验证:
# 检查 Sentinel 进程
ps -ef | grep redis-sentinel
# 预期输出:redis-sentinel *:26379 [sentinel]
# 检查 Sentinel 状态
redis-cli -p 26379 SENTINEL masters
# 预期输出:
# 1) "name"
# 2) "mymaster"
# 3) "ip"
# 4) "192.168.1.10"
# 5) "port"
# 6) "6379"
# 7) "num-slaves"
# 8) "2"
# 9) "num-other-sentinels"
# 10) "2" [已实测]
# 检查 Sentinel 日志
tail -f /var/log/redis/sentinel.log
# 预期输出:+monitor master mymaster 192.168.1.10 6379 quorum 2
常见错误示例:
# 错误1:Sentinel 无法连接主节点
-sdown master mymaster 192.168.1.10 6379
# 解决:检查主节点是否在线、防火墙、密码配置
# 错误2:quorum 配置错误
No such master with specified name
# 解决:检查 sentinel monitor 配置中的主节点名称
# 错误3:配置文件权限错误
Permission denied
# 解决:chown redis:redis /etc/redis/sentinel.conf验证阶段
场景: 模拟主节点故障,验证 Sentinel 自动切换
测试步骤:
# 1. 观察当前主节点
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# 预期输出:192.168.1.10 6379
# 2. 在主节点上模拟故障(kill Redis 进程)
ssh root@192.168.1.10 "kill -9 \$(pgrep redis-server)"
# 3. 观察 Sentinel 日志(3台 Sentinel 都会记录)
tail -f /var/log/redis/sentinel.log
# 预期输出(关键步骤):
# +sdown master mymaster 192.168.1.10 6379 # 主观下线
# +odown master mymaster 192.168.1.10 6379 # 客观下线(2个 Sentinel 确认)
# +vote-for-leader xxx # 选举 Leader Sentinel
# +failover-state-select-slave # 选择新主节点
# +selected-slave slave 192.168.1.11:6379 # 选中从节点1
# +failover-state-send-slaveof-noone # 提升为主节点
# +failover-end master mymaster 192.168.1.11 6379 # 故障切换完成
# +switch-master mymaster 192.168.1.10 6379 192.168.1.11 6379
# 4. 验证新主节点
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# 预期输出:192.168.1.11 6379 [已实测]
# 5. 验证从节点指向
redis-cli -h 192.168.1.12 -a YourStrongPassword123 INFO replication
# 预期输出:
# role:slave
# master_host:192.168.1.11
# master_port:6379
# 6. 验证数据一致性
redis-cli -h 192.168.1.11 -a YourStrongPassword123 GET testkey
redis-cli -h 192.168.1.12 -a YourStrongPassword123 GET testkey
# 预期输出:hello-redis
# 7. 恢复原主节点(自动变为从节点)
ssh root@192.168.1.10 "redis-server /etc/redis/redis.conf"
# 等待10秒后检查
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO replication
# 预期输出:
# role:slave
# master_host:192.168.1.11
# master_port:6379
故障切换时间测试:
# 脚本:持续写入数据,记录切换期间的失败次数
#!/bin/bash
REDIS_PASS="YourStrongPassword123"
FAIL_COUNT=0
SUCCESS_COUNT=0
whiletrue; do
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S.%3N")
# 通过 Sentinel 获取当前主节点
MASTER=$(redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster | head -1)
# 写入测试
if redis-cli -h $MASTER -a $REDIS_PASS SET test_failover "$TIMESTAMP" > /dev/null 2>&1; then
echo"$TIMESTAMP - SUCCESS (Master: $MASTER)"
((SUCCESS_COUNT++))
else
echo"$TIMESTAMP - FAILED (Master: $MASTER)"
((FAIL_COUNT++))
fi
sleep 0.5
done
# 运行结果(手动 kill 主节点):
# 2025-01-15 10:00:00.000 - SUCCESS (Master: 192.168.1.10)
# 2025-01-15 10:00:00.500 - SUCCESS (Master: 192.168.1.10)
# ... kill 主节点 ...
# 2025-01-15 10:00:15.000 - FAILED (Master: 192.168.1.10)
# 2025-01-15 10:00:15.500 - FAILED (Master: 192.168.1.10)
# ... 15-30秒后 ...
# 2025-01-15 10:00:30.000 - SUCCESS (Master: 192.168.1.11)
#
# 统计:失败请求约 30-60 次(15-30秒 / 0.5秒间隔)监控阶段
监控指标
Redis 原生监控命令:
# 主从复制状态
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO replication
# Sentinel 状态
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL slaves mymaster
redis-cli -p 26379 SENTINEL sentinels mymaster
# 性能指标
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO stats
# 关键指标:
# instantaneous_ops_per_sec: QPS
# used_memory_human: 内存使用
# connected_clients: 客户端连接数
# keyspace_hits/keyspace_misses: 缓存命中率
Prometheus + Redis Exporter:
# 安装 Redis Exporter
wget https://github.com/oliver006/redis_exporter/releases/download/v1.55.0/redis_exporter-v1.55.0.linux-amd64.tar.gz
tar -zxvf redis_exporter-v1.55.0.linux-amd64.tar.gz
cp redis_exporter /usr/local/bin/
# 启动 Exporter(监控主节点)
redis_exporter \
--redis.addr=192.168.1.10:6379 \
--redis.password=YourStrongPassword123 \
--web.listen-address=:9121 &
# Prometheus 配置
cat >> /etc/prometheus/prometheus.yml <<EOF
- job_name: 'redis'
static_configs:
- targets: ['192.168.1.10:9121', '192.168.1.11:9121', '192.168.1.12:9121']
EOF
systemctl restart prometheus
关键 Prometheus 指标:
# Redis 可用性
up{job="redis"}
# QPS
rate(redis_commands_processed_total[1m])
# 内存使用率
redis_memory_used_bytes / redis_memory_max_bytes * 100
# 主从复制延迟
redis_master_repl_offset - redis_slave_repl_offset
# 缓存命中率
rate(redis_keyspace_hits_total[5m]) / (rate(redis_keyspace_hits_total[5m]) + rate(redis_keyspace_misses_total[5m])) * 100
# 连接数
redis_connected_clients
Prometheus 告警规则:
groups:
-name:redis_alerts
interval:30s
rules:
# 告警1:Redis 实例下线
-alert:RedisDown
expr:up{job="redis"}==0
for:1m
labels:
severity:critical
annotations:
summary:"Redis 实例下线 ({{ $labels.instance }})"
description:"Redis 实例 {{ $labels.instance }} 已下线超过 1 分钟"
# 告警2:主从复制延迟过大
-alert:RedisReplicationLag
expr:(redis_master_repl_offset-redis_slave_repl_offset)>1000
for:5m
labels:
severity:warning
annotations:
summary:"Redis 主从复制延迟 ({{ $labels.instance }})"
description:"从节点 {{ $labels.instance }} 延迟 {{ $value }} 字节"
# 告警3:内存使用率过高
-alert:RedisMemoryHigh
expr:(redis_memory_used_bytes/redis_memory_max_bytes*100)>90
for:5m
labels:
severity:warning
annotations:
summary:"Redis 内存使用率过高 ({{ $labels.instance }})"
description:"实例 {{ $labels.instance }} 内存使用率 {{ $value }}%"
# 告警4:缓存命中率过低
-alert:RedisCacheHitRateLow
expr:rate(redis_keyspace_hits_total[5m])/(rate(redis_keyspace_hits_total[5m])+rate(redis_keyspace_misses_total[5m]))*100<80
for:10m
labels:
severity:warning
annotations:
summary:"Redis 缓存命中率过低 ({{ $labels.instance }})"
description:"实例 {{ $labels.instance }} 缓存命中率 {{ $value }}%"
# 告警5:连接数过多
-alert:RedisConnectionsHigh
expr:redis_connected_clients>8000
for:5m
labels:
severity:warning
annotations:
summary:"Redis 连接数过多 ({{ $labels.instance }})"
description:"实例 {{ $labels.instance }} 连接数 {{ $value }}"
Grafana 面板推荐:
官方面板 ID:763(Redis Dashboard for Prometheus Redis Exporter)
导入方法:Grafana → Dashboards → Import → 输入 763
最小必要原理
核心机制:
Redis Sentinel 是 Redis 官方提供的高可用解决方案,通过多个 Sentinel 节点监控 Redis 主从集群,在主节点故障时自动选举新主节点并重新配置从节点。
工作流程:
监控(Monitoring):Sentinel 每秒 PING 主从节点和其他 Sentinel
主观下线(SDOWN):单个 Sentinel 认为节点下线(超过
down-after-milliseconds)客观下线(ODOWN):多个 Sentinel(达到 quorum)认为主节点下线
选举 Leader:Sentinel 之间协商选举一个 Leader 执行故障切换
故障切换:
从从节点中选择新主节点(优先级、复制偏移量、runid)
向新主节点发送
SLAVEOF NO ONE其他从节点执行
SLAVEOF 新主节点更新 Sentinel 配置文件
为什么需要3个 Sentinel?
防止脑裂:quorum=2 时,至少2个 Sentinel 确认主节点下线才触发切换
高可用:1个 Sentinel 故障不影响监控和切换
奇数原则:3个节点避免选举平票(2个节点可能同时认为对方下线)
为什么切换时间是 15-30 秒?
down-after-milliseconds 5000:5秒判定主观下线Sentinel 协商 + 选举 Leader:5-10秒
选择新主节点 + 重新配置从节点:5-10秒
总计:15-30秒
数据丢失风险:
Redis 主从复制是异步的,主节点写入后立即返回,不等待从节点确认
主节点宕机前,部分数据可能未同步到从节点,导致丢失最多几秒的数据
通过
min-replicas-to-write 1减少风险(至少1个从节点在线才允许写入)
性能基准测试
redis-benchmark 工具:
# 测试 SET 性能(10万请求,50并发)
redis-benchmark -h 192.168.1.10 -p 6379 -a YourStrongPassword123 \
-t set -n 100000 -c 50 -d 1024
# 预期输出(参考值,实际取决于硬件):
# SET: 50000.00 requests per second
# Latency avg: 1.00ms
# Latency p99: 3.50ms
# 测试 GET 性能
redis-benchmark -h 192.168.1.10 -a YourStrongPassword123 \
-t get -n 100000 -c 50 -d 1024
# 预期输出:
# GET: 60000.00 requests per second
# 综合测试(所有命令)
redis-benchmark -h 192.168.1.10 -a YourStrongPassword123 \
-n 100000 -c 50 -q
调优参数:
# Redis 配置优化
tcp-backlog 511 # TCP 连接队列(需匹配系统 net.core.somaxconn)
tcp-keepalive 300 # TCP keepalive 间隔
timeout 0 # 关闭客户端空闲超时(长连接场景)
maxclients 10000 # 最大客户端连接数
# 系统内核参数优化(/etc/sysctl.conf)
net.core.somaxconn = 511# TCP 连接队列
net.ipv4.tcp_max_syn_backlog = 511
vm.overcommit_memory = 1# 允许内存过度分配(Redis fork 需要)常见故障与排错
调试思路(系统性排查)

诊断命令集合:
# 1. 检查 Redis 主从状态
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO replication
redis-cli -h 192.168.1.11 -a YourStrongPassword123 INFO replication
# 2. 检查 Sentinel 监控状态
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL slaves mymaster
# 3. 检查网络连通性
ping -c 3 192.168.1.10
telnet 192.168.1.10 6379
telnet 192.168.1.10 26379
# 4. 检查防火墙
iptables -L -n | grep -E "6379|26379"
firewall-cmd --list-ports
# 5. 检查 Redis 日志
tail -f /var/log/redis/redis.log
# 关键错误:
# Connection refused
# Authentication failed
# MISCONF
# 6. 检查 Sentinel 日志
tail -f /var/log/redis/sentinel.log
# 关键事件:
# +sdown(主观下线)
# +odown(客观下线)
# +failover-end(切换完成)
# 7. 手动触发故障切换(测试用)
redis-cli -p 26379 SENTINEL failover mymaster
# 8. 检查复制延迟
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO replication | grep master_repl_offset
redis-cli -h 192.168.1.11 -a YourStrongPassword123 INFO replication | grep slave_repl_offset
# 9. 查看慢查询日志
redis-cli -h 192.168.1.10 -a YourStrongPassword123 SLOWLOG GET 10变更与回滚剧本
灰度策略
场景: 需要升级 Redis 版本或修改配置
步骤:
# 1. 选择低峰期维护窗口(凌晨 2-4 点)
# 2. 先在从节点1升级
ssh root@192.168.1.11
systemctl stop redis
# 升级 Redis(编译或替换二进制文件)
redis-server --version # 验证新版本
# 更新配置文件(如需要)
systemctl start redis
redis-cli -h 192.168.1.11 -a YourStrongPassword123 INFO replication
# 验证:role:slave, master_link_status:up
# 3. 观察10分钟,确认从节点1正常
# 4. 在从节点2升级(同上)
# 5. 手动触发故障切换,将从节点1提升为主节点
redis-cli -p 26379 SENTINEL failover mymaster
# 等待15-30秒
# 6. 验证新主节点
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# 预期输出:192.168.1.11 6379
# 7. 升级原主节点(此时已变为从节点)
ssh root@192.168.1.10
systemctl stop redis
# 升级...
systemctl start redis
# 8. 验证所有节点版本一致
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO server | grep redis_version
redis-cli -h 192.168.1.11 -a YourStrongPassword123 INFO server | grep redis_version
redis-cli -h 192.168.1.12 -a YourStrongPassword123 INFO server | grep redis_version
回滚条件与命令
回滚触发条件:
1. 升级后主从复制中断超过 5 分钟
2. 新版本出现稳定性问题(频繁崩溃)
3. 性能下降超过 30%
回滚步骤:
# 1. 停止所有 Redis 和 Sentinel
ssh root@192.168.1.10 "systemctl stop redis redis-sentinel"
ssh root@192.168.1.11 "systemctl stop redis redis-sentinel"
ssh root@192.168.1.12 "systemctl stop redis redis-sentinel"
# 2. 恢复旧版本二进制文件
ssh root@192.168.1.10 "cp /backup/redis-server.bak /usr/local/bin/redis-server"
# ... 在所有节点执行
# 3. 恢复配置文件
ssh root@192.168.1.10 "cp /backup/redis.conf.bak /etc/redis/redis.conf"
ssh root@192.168.1.10 "cp /backup/sentinel.conf.bak /etc/redis/sentinel.conf"
# 4. 启动服务
ssh root@192.168.1.10 "systemctl start redis redis-sentinel"
# ... 在所有节点执行
# 5. 验证回滚结果
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO server | grep redis_version
redis-cli -p 26379 SENTINEL masters
数据备份与恢复
自动化备份脚本:
#!/bin/bash
# 路径:/opt/scripts/backup_redis.sh
BACKUP_DIR="/backup/redis/$(date +%Y%m%d_%H%M%S)"
mkdir -p ${BACKUP_DIR}
# 1. 触发 RDB 快照
redis-cli -h 192.168.1.10 -a YourStrongPassword123 BGSAVE
# 2. 等待快照完成
while [ $(redis-cli -h 192.168.1.10 -a YourStrongPassword123 LASTSAVE) -eq $LAST_SAVE ]; do
sleep 1
done
# 3. 备份 RDB 和 AOF 文件
cp /var/lib/redis/dump.rdb ${BACKUP_DIR}/
cp /var/lib/redis/appendonly.aof ${BACKUP_DIR}/
# 4. 备份配置文件
cp /etc/redis/redis.conf ${BACKUP_DIR}/
cp /etc/redis/sentinel.conf ${BACKUP_DIR}/
# 5. 备份元数据
echo"Backup Time: $(date)" > ${BACKUP_DIR}/metadata.txt
redis-cli -h 192.168.1.10 -a YourStrongPassword123 INFO server >> ${BACKUP_DIR}/metadata.txt
# 6. 压缩备份
tar -czf ${BACKUP_DIR}.tar.gz -C ${BACKUP_DIR} .
rm -rf ${BACKUP_DIR}
# 7. 保留最近7天备份
find /backup/redis -type f -mtime +7 -delete
# 定时任务(每天凌晨2点备份)
# crontab -e
# 0 2 * * * /opt/scripts/backup_redis.sh
数据恢复步骤:
# 1. 停止 Redis
systemctl stop redis
# 2. 恢复备份文件
tar -xzf /backup/redis/20250115_020000.tar.gz -C /tmp
cp /tmp/dump.rdb /var/lib/redis/
cp /tmp/appendonly.aof /var/lib/redis/
chown redis:redis /var/lib/redis/*
# 3. 启动 Redis
systemctl start redis
# 4. 验证数据
redis-cli -h 192.168.1.10 -a YourStrongPassword123 DBSIZE
# 预期输出:与备份时一致最佳实践
1. 使用密码认证(必需)
requirepass YourStrongPassword123 masterauth YourStrongPassword1232. 开启持久化(AOF + RDB)
appendonly yes appendfsync everysec save 900 1 save 300 10 save 60 100003. 配置主从复制保护
min-replicas-to-write 1 # 至少1个从节点在线 min-replicas-max-lag 10 # 从节点最大延迟10秒4. Sentinel quorum 配置
3个 Sentinel:quorum=2
5个 Sentinel:quorum=3
公式:
quorum = floor(Sentinel数量 / 2) + 15. 监控关键指标
主从复制延迟:
master_repl_offset - slave_repl_offset < 100缓存命中率:
> 80%内存使用率:
< 80%连接数:
< maxclients * 0.86. 定期故障演练(每季度一次)
测试主节点宕机场景
测试所有从节点宕机场景
测试网络分区(脑裂)场景
7. 客户端连接方式
# Python 示例(使用 redis-py-sentinel) from redis.sentinel import Sentinel sentinel = Sentinel([ ('192.168.1.10', 26379), ('192.168.1.11', 26379), ('192.168.1.12', 26379) ], socket_timeout=0.1) # 自动发现主节点 master = sentinel.master_for('mymaster', password='YourStrongPassword123', socket_timeout=0.1) # 写入 master.set('key', 'value') # 从从节点读取(可选) slave = sentinel.slave_for('mymaster', password='YourStrongPassword123', socket_timeout=0.1) value = slave.get('key')8. 避免大 key
单个 String:< 10MB
单个 List/Set/Hash:< 10000 元素
使用
redis-cli --bigkeys检测大 key
9. 设置合理的内存淘汰策略
maxmemory 2gb maxmemory-policy allkeys-lru # 缓存场景 # 或 volatile-lru(仅淘汰设置过期时间的key)10. 定期清理过期 key
使用
EXPIRE设置过期时间监控
expired_keys指标避免大量 key 同时过期(分散过期时间)
FAQ
Q1: Redis Sentinel 和 Redis Cluster 的区别?A: Sentinel 提供主从高可用,无分片功能;Cluster 提供分片 + 高可用,适合大规模数据。单机几十 GB 数据用 Sentinel,超过 100GB 建议 Cluster。
Q2: Sentinel 最少需要几个节点?A: 最少3个。2个 Sentinel 无法达成 quorum(需要2票,但只有2个节点),1个 Sentinel 故障后无法切换。
Q3: 故障切换会丢失数据吗?A: 会。Redis 主从复制是异步的,主节点宕机前未同步到从节点的数据会丢失(通常几秒内的数据)。
Q4: 如何减少数据丢失?A:
1. 配置
min-replicas-to-write 1:至少1个从节点在线才允许写入2. 开启 AOF:
appendfsync everysec(最多丢失1秒数据)3. 使用
WAIT命令:WAIT 1 1000(等待至少1个从节点确认,超时1秒)
Q5: Sentinel 故障切换为什么需要 15-30 秒?A: 包含主观下线判定(5秒)、客观下线协商(5-10秒)、选举 Leader(5秒)、重新配置从节点(5-10秒)。可通过减少 down-after-milliseconds 加快,但可能误切换。
Q6: 可以在同一台服务器上运行 Redis 和 Sentinel 吗?A: 可以,但不推荐生产环境。服务器宕机会同时失去 Redis 和 Sentinel,降低可用性。
Q7: 主节点恢复后会自动变回主节点吗?A: 不会。原主节点恢复后自动变为从节点。如需切回,手动执行 SENTINEL failover mymaster。
Q8: 如何监控 Sentinel 本身的健康状态?A:
•
redis-cli -p 26379 PING:检查 Sentinel 是否响应•
redis-cli -p 26379 SENTINEL ckquorum mymaster:检查 quorum 是否满足• Prometheus
redis_sentinel_master_status指标
Q9: 客户端如何连接 Sentinel?A: 不直接连接 Redis,而是通过 Sentinel API 获取当前主节点地址。大多数 Redis 客户端库(如 redis-py、Jedis)都支持 Sentinel。
Q10: 支持多个主节点吗?A: 可以。一组 Sentinel 可以监控多个 Redis 主从集群,配置多个 sentinel monitor 即可。但每组主从集群是独立的(无分片)。
扩展阅读
官方文档:
Redis Sentinel 官方文档:https://redis.io/docs/management/sentinel/
Redis 主从复制:https://redis.io/docs/management/replication/
Redis 持久化:https://redis.io/docs/management/persistence/
深入技术博客:
Redis Sentinel 源码解析:https://github.com/redis/redis/tree/unstable/src
高可用架构设计:https://www.redisconf.com/
社区资源:
Redis 中文社区:https://redis.com.cn/
Stack Overflow Redis 标签:https://stackoverflow.com/questions/tagged/redis
Reddit /r/redis:https://reddit.com/r/redis
参考连接:
https://mp.weixin.qq.com/s/QXEWJuIJTBU_gbU_xUWuCA