Redis 哨兵模式高可用架构部署与优化
简介
为了解决 主从模式无法自动故障转移与恢复的问题,Redis 引入了哨兵模式。主要是在主从复制的基础上加入哨兵节点,用于监控主节点和从节点状态。当主节点发生故障时,哨兵节点可以自动进行故障转移,选择一个从节点升级为主节点,并通知其他从节点和应用程序进行更新。
优点:可以动态切换主从库,适合中心型公司首选。
缺点:
- 单个 Master 主节点提供写服务,Redis 存储的数据有限(<10G),并发量不足(<3w)。
- 自动切换主从库会产生访问瞬断的情况,切换没有那么快。
工作原理:
- 哨兵节点定期向所有主节点和从节点发送 PING 命令,如果在指定的时间内未收到 PONG 响应,哨兵节点会将该节点标记为主观下线。
- 如果一个主节点被多数哨兵节点标记为主观下线,那么它将被标记为客观下线。
- 当主节点被标记为客观下线时,哨兵节点会触发故障转移过程,它会从所有健康的从节点中选举一个新的主节点。
- 并将所有从节点切换到新的主节点实现自动故障转移。同时哨兵节点会更新所有客户端的配置指向新的主节点。
生产级部署文档
硬件:1 主 2 从 3 哨兵,针对中大型公司(日活百万级至千万级,QPS 10 万+)的场景:
| 角色 | IP 地址 | 主机名 | 硬件配置 | 操作系统 |
|---|---|---|---|---|
| 主节点 | 192.168.1.10 | redis-m1 | 16 核 / 64GB / 1TB | CentOS 7.9 |
| 从节点 1 | 192.168.1.11 | redis-s1 | 16 核 / 64GB / 1TB | CentOS 7.9 |
| 从节点 2 | 192.168.1.12 | redis-s2 | 16 核 / 64GB / 1TB | CentOS 7.9 |
| 哨兵 1 | 192.168.1.13 | sentinel1 | 16 核 / 64GB / 1TB | CentOS 7.9 |
| 哨兵 2 | 192.168.1.14 | sentinel2 | 16 核 / 64GB / 1TB | CentOS 7.9 |
| 哨兵 3 | 192.168.1.15 | sentinel3 | 16 核 / 64GB / 1TB | CentOS 7.9 |
说明:
- 所有服务器之间网络互通,防火墙开放 6379(Redis)和 26379(哨兵)端口。
- 主从节点和哨兵节点分开部署,避免资源争用,提高稳定性。
常用命令:
# 查看集群信息
redis-cli -a <password> info replication
# 手动故障转移,必须在想要提升为主节点的从节点上执行
# 1.默认(安全)模式
# PS:数据零丢失,会等待从节点的数据与主节点完全同步后,再进行无损切换
redis-cli -a your_password CLUSTERFAILOVER
# 2.强制(FORCE)模式
# PS:主节点不可用时使用。跳过与主节点的数据同步检查,直接发起故障转移,但仍需集群中多数主节点同意
redis-cli -a your_password CLUSTERFAILOVER FORCE
# 3.接管(TAKEOVER)模式
# PS:最强硬、有数据丢失风险,完全忽略集群共识和数据一致性,从节点单方面宣布成为主节点
redis-cli -a your_password CLUSTERFAILOVERTAKEOVER
# 哨兵手动切换
# 强制哨兵对指定的主节点(<master-name>)发起一次故障转移,无论该主节点当前是否真实下线。
# 哨兵会选举出一个从节点将其提升为新主节点,并将其他从节点指向新主节
redis-cli -p 26379 SENTINEL FAILOVER <master-name>
# 查看哨兵状态
redis-cli -p 26379 info sentinel
基础配置 - 所有节点
# 设置主机名(根据角色修改)
hostnamectl set-hostname redis-m1 # 主节点
hostnamectl set-hostname redis-s1 # 从节点 1
hostnamectl set-hostname redis-s2 # 从节点 2
hostnamectl set-hostname sentinel1 # 哨兵 1
hostnamectl set-hostname sentinel2 # 哨兵 2
hostnamectl set-hostname sentinel3 # 哨兵 3
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 或者开放端口
# firewall-cmd --permanent --add-port=6379/tcp --add-port=26379/tcp
# firewall-cmd --reload
# 关闭 SELinux(临时)
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
安装 Redis-主从节点
# 方式一:源码编译
cd /usr/local/src
wget https://download.redis.io/releases/redis-7.2.4.tar.gz
tar xzf redis-7.2.4.tar.gz
cd redis-7.2.4
make && make install PREFIX=/usr/local/redis
# 创建数据目录和配置目录
mkdir -p /data/redis/{data,logs,conf,run}
useradd redis -s /sbin/nologin -M
chown -R redis:redis /data/redis /usr/local/redis
# 启动 redis[暂时不启动]
./redis-server /data/redis/conf/redis.conf
配置主从复制
主节点配置
编辑 /data/redis/conf/redis.conf
bind 192.168.1.10 127.0.0.1 # 设置绑定 IP,允许外部访问
protected-mode no # 保护模式,如果在非本地网络
port 6379 # 设置端口
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no # 由 systemd 管理,不后台运行
supervised systemd
pidfile /data/redis/run/redis_6379.pid
loglevel notice
logfile "/data/redis/logs/redis-6379.log"
databases 16
# 主节点认证密码(可选,建议设置)
requirepass Redis123
masterauth Redis123
# 持久化配置 RDB+AOF
save 9001
save 30010
save 6010000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump-6379.rdb
dir /data/redis/data
# AOF 配置(可根据需求选择开启)
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
# 内存管理(根据实际内存调整,留出系统内存)
maxmemory 48GB
maxmemory-policy allkeys-lru # 淘汰策略
# 慢日志
slowlog-log-slower-than 10000
slowlog-max-len 128
# 其他优化
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
启动 redis: ./redis-server /data/redis/conf/redis.conf
从节点配置
- 两个从节点配置基本相同,只需修改 replicaof 指向主节点。
编辑 /data/redis/conf/redis.conf,在主节点配置基础上增加:
replicaof 192.168.1.10 6379 # 指向主节点 IP 和端口
masterauth your_master_password # 如果主节点设置了密码
- 其余配置与主节点相同,注意内存策略一致。
验证:
# 1. 主节点
./redis-cli -a password info replication
# 输出应显示 connected_slaves:2,并且从节点状态正常。
# 2. 从节点
./redis-cli -a password info replication
# 应看到 role:slave,并显示主节点信息。
启动 redis: ./redis-server /data/redis/conf/redis.conf
哨兵节点配置
哨兵用于监控主从节点,实现自动故障转移,每个哨兵节点运行独立的哨兵进程。只需安装 redis 二进制,不需要启动 Redis 服务,也可以只安装哨兵(redis-sentinel)
- 安装
# 方式一:源码编译
cd /usr/local/src
wget https://download.redis.io/releases/redis-7.2.4.tar.gz
tar xzf redis-7.2.4.tar.gz
cd redis-7.2.4
make && make install PREFIX=/usr/local/redis
# 创建数据目录和配置目录
mkdir -p /data/sentinel/{data,logs,conf,run}
useradd redis -s /sbin/nologin -M
chown -R redis:redis /data/sentinel /usr/local/redis
- 配置
哨兵配置文件(所有哨兵节点基本一致),编辑 /data/sentinel/conf/sentinel.conf
# 基础配置
port 26379
daemonize no
supervised systemd
pidfile /data/sentinel/run/sentinel_26379.pid
logfile "/data/sentinel/logs/sentinel-26379.log"
dir /data/sentinel/data
# 监控主节点,2 表示至少 2 个哨兵同意故障转移
sentinel monitor redis-m1 192.168.1.10 6379 2
# 哨兵连接主节点的密码(如果设置了 requirepass)
sentinel auth-pass redis-m1 Redis123
# 主观下线时间,默认 30 秒
sentinel down-after-milliseconds mymaster 30000
# 故障转移超时时间,默认 180 秒
sentinel failover-timeout mymaster 180000
# 同时并行同步数,故障转移后可以同时有 1 个从节点同步新主
sentinel parallel-syncs mymaster 1
# 保护模式关闭(如果不需要)
protected-mode no
- 启动
./redis-sentinel /data/sentinel/conf/sentinel.conf
- 验证
在任意哨兵节点执行:
./redis-cli -p 26379 info sentinel
显示结果如下:
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.10:6379,slaves=2,sentinels=3
高可用验证
主从复制测试
- 在主节点设置键:
redis-cli -h 192.168.1.10 SET testkey "hello" - 在从节点获取:
redis-cli -h 192.168.1.11 GET testkey应返回 "hello"。
故障转移测试
- 在主节点上执行:
systemctl stop redis - 等待 30 秒左右(down-after-milliseconds 配置),哨兵会检测到主观下线,随后发起投票,选举新的主节点。可以在哨兵日志中查看故障转移过程:
tail -f /data/sentinel/logs/sentinel-26379.log - 故障转移完成后,查看当前主节点:
/usr/local/redis/bin/redis-cli -p 26379 sentinel get-master-addr-by-name mymaster返回新的主节点 IP 和端口,旧主节点恢复后会自动成为新主的从节点。
性能测试
总写能力:仅主节点处理写,最大写 QPS 约 5 万~8 万(保守估计 3 万+)。
总读能力:主节点 + 两个从节点均可处理读,假设读请求均匀分发,最大读 QPS 可达15 万~24 万。
总混合 QPS:在读写比例 2:8 下,整体 QPS 可达 10 万~15 万。
性能优化
硬件优化
在 所有 Redis 节点(主、从)的 /etc/sysctl.conf 中添加,并执行 sysctl -p 使配置生效
# 提高连接队列大小,应对高并发连接
net.core.somaxconn = 1024
# 允许内存过载,避免 Redis 启动时因内存分配失败
vm.overcommit_memory = 1
# 禁用透明大页,减少内存延迟波动
# 立即生效
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 永久生效
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
chmod +x /etc/rc.local
Redis 优化
最大内存 + 多线程 + 最大客户端连接数 +RDB/AOF 持久化 + 内存淘汰策略
# Redis 配置优化
# 1.物理内存:建议为物理内存的 50%,留出部分给 OS 和持久化子进程(如 bgsave)
maxmemory 32GB
# 2.启用多线程 IO 处理网络读写:建议 min(总核数 - 2, 8)。
# 超过 8 个线程后,性能提升会变得非常有限,甚至可能因为线程切换开销而导致收益下降,建议逐步调优
io-threads 8
# 主节点允许线程处理读操作
# 默认是 no,即只使用多线程来处理写操作(向客户端回写结果)。
# 设置为 yes,多线程也会处理读操作(从客户端读取命令和解析协议)
io-threads-do-reads yes
# 3.网络
# 最大客户端连接数,根据并发量调整,默认 10000,可适当提高
maxclients 20000
# 客户端空闲超时,设为 0 禁用(保持长连接)
timeout 0
# TCP keepalive,检测死连接
tcp-keepalive 300
# 4.持久化策略,根据业务对数据安全的要求权衡性能。
# RDB 快照:如果允许少量数据丢失,可仅使用 RDB,并降低快照频率(例如)
save 9001
save 30010
save 6010000
# AOF
# 如需更高数据安全性,开启 AOF 并设置 appendfsync everysec
# 如果磁盘 IO 成为瓶颈,可考虑关闭 AOF,仅用 RDB+ 主从复制
# 5.内存淘汰策略
# allkeys-lru 适合一般缓存场景
# volatile-lru 适合业务有明确过期需求
# 确保内存达到上限时能平滑淘汰数据,避免 OOM
maxmemory-policy allkeys-lru
# 6.禁用或优化危险命令
rename-command FLUSHALL ""
rename-command CONFIG "C0NFIG"


