文章目录
简介
为了解决主从模式无法自动故障转移与恢复的问题,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(哨兵)端口。
- 主从节点和哨兵节点分开部署,避免资源争用,提高稳定性。
常用命令:
java
# 查看集群信息
redis-cli -a <password> info replication
# 手动故障转移,必须在想要提升为主节点的从节点上执行
# 1.默认(安全)模式
# PS:数据零丢失,会等待从节点的数据与主节点完全同步后,再进行无损切换
redis-cli -a 你的密码 CLUSTER FAILOVER
# 2.强制(FORCE)模式
# PS:主节点不可用时使用。跳过与主节点的数据同步检查,直接发起故障转移,但仍需集群中多数主节点同意
redis-cli -a 你的密码 CLUSTER FAILOVER FORCE
# 3.接管(TAKEOVER)模式
# PS:最强硬、有数据丢失风险,完全忽略集群共识和数据一致性,从节点单方面宣布成为主节点
redis-cli -a 你的密码 CLUSTER FAILOVER TAKEOVER
# 哨兵手动切换
# 强制哨兵对指定的主节点(<master-name>)发起一次故障转移,无论该主节点当前是否真实下线。
# 哨兵会选举出一个从节点将其提升为新主节点,并将其他从节点指向新主节
redis-cli -p 26379 SENTINEL FAILOVER <master-name>
# 查看哨兵状态
redis-cli -p 26379 info sentinel
基础配置-所有节点
java
# 设置主机名(根据角色修改)
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-主从节点
java
// 方式一:源码编译
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
java
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 900 1
save 300 10
save 60 10000
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 no
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,在主节点配置基础上增加:
java
replicaof 192.168.1.101 6379 # 指向主节点IP和端口
masterauth your_master_password # 如果主节点设置了密码
- 其余配置与主节点相同,注意内存策略一致
验证:
java
1. 主节点:
./redis-cli -a 密码 info replication
输出应显示connected_slaves:2,并且从节点状态正常。
2. 从节点:
./redis-cli -a 密码 info replication
应看到role:slave,并显示主节点信息。
启动redis ./redis-server /data/redis/conf/redis.conf
哨兵节点配置
哨兵用于监控主从节点,实现自动故障转移,每个哨兵节点运行独立的哨兵进程。只需安装redis二进制,不需要启动Redis服务,也可以只安装哨兵(redis-sentinel)
- 安装
java
// 方式一:源码编译
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
java
# 基础配置
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
显示结果如下:
plain
# 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.101 SET testkey "hello"
- 在从节点获取:redis-cli -h 192.168.1.102 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 使配置生效
shell
# 提高连接队列大小,应对高并发连接
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持久化+内存淘汰策略
shell
# 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 900 1
save 300 10
save 60 10000
# AOF
# 如需更高数据安全性,开启AOF并设置
appendfsync everysec
# 如果磁盘IO成为瓶颈,可考虑关闭AOF,仅用RDB+主从复制
# 5.内存淘汰策略
# allkeys-lru适合一般缓存场景
# volatile-lru适合业务有明确过期需求
# 确保内存达到上限时能平滑淘汰数据,避免OOM
conf maxmemory-policy allkeys-lru
# 6.禁用或优化危险命令
rename-command FLUSHALL "" # 禁用
rename-command CONFIG "C0NFIG" # 重命名