Redis 配置读写分离:一主一从 + Sentinel 完整实战
一、前言
Redis 做读写分离,最常见的方案就是:
- 写请求走主节点
- 读请求走从节点
- 主从之间通过复制保持数据同步
- 再配合 Sentinel 做主节点监控和故障切换
需要先明确两点:
-
Redis 自身不会自动帮你做业务层面的读写路由
Redis 负责主从复制,但"哪些请求发主、哪些请求发从",通常还是要靠客户端代码、连接池、代理层或中间件来实现。
-
主从复制不等于高可用
如果只有主从,没有 Sentinel,那么主节点挂了以后,客户端仍然会写向旧主,必须人工切换。Sentinel 才是 Redis 官方提供的高可用组件,用于监控、发现故障和自动故障转移。
二、Redis 读写分离适用场景
适合使用 Redis 一主一从读写分离的场景主要有:
- 缓存型业务,读多写少
- 排行榜、配置缓存、会话缓存、热点数据缓存
- 对强一致要求没那么极端
- 需要初步提升读取能力
- 希望后续继续演进到高可用架构
不太适合的场景有:
- 刚写完必须立刻读到最新值
- 把 Redis 当作关键状态真值库使用
- 交易、订单、库存、支付等强一致链路
因为 Redis 默认复制是异步的,从节点存在短暂延迟,可能读到旧数据。
三、Redis 主从复制原理简介
Redis 主从复制大致流程如下:
- 主从建立连接
- 从节点向主节点发起同步
- 主节点将写命令流持续发送给从节点
- 如果连接中断,从节点重连后优先尝试部分重同步
- 如果部分重同步失败,则进行全量同步
- 全量同步时,主节点会生成数据快照并发送给从节点
所以你要知道:
- 主从之间不是实时强一致
- 从节点有可能延迟
- 主节点故障前最后一小段写入,可能还没同步到从节点
这也是后面线上部署时必须重点考虑的一致性问题。
四、方案一:同一台机器部署 Redis 一主一从
这个方案适合:
- 本地开发
- 功能验证
- 练习读写分离
- 学习主从复制
- 测试 Sentinel
不适合真正生产高可用,因为机器一挂,主从一起挂。
4.1 目录结构示例
假设 Redis 放在:
text
D:\redis\
建议目录如下:
text
D:\redis\
│
├─redis-server.exe
├─redis-cli.exe
│
├─master\
│ ├─redis-6379.conf
│ └─data\
│
└─slave\
├─redis-6380.conf
└─data\
提前手动创建数据目录:
text
D:\redis\master\data
D:\redis\slave\data
4.2 主库配置
文件:D:\redis\master\redis-6379.conf
conf
port 6379
bind 127.0.0.1
protected-mode no
daemonize no
loglevel notice
logfile "D:/redis/master/redis-6379.log"
dir "D:/redis/master/data"
dbfilename dump.rdb
appendonly no
save 900 1
save 300 10
save 60 10000
rdbcompression yes
rdbchecksum yes
参数说明
port 6379
主节点监听端口。
bind 127.0.0.1
只允许本机访问。
protected-mode no
本机测试常用,生产环境不建议这样配置。
daemonize no
Windows 本地测试一般直接前台运行。
loglevel notice
日志级别。
logfile
日志文件路径。多实例部署时建议显式分开日志文件。
dir
RDB 工作目录。多实例时一定建议显式分开,否则主从可能写到同一目录。
dbfilename dump.rdb
RDB 文件名。
appendonly no
关闭 AOF,仅使用 RDB。
save 900 1 / 300 10 / 60 10000
RDB 快照规则。
rdbcompression yes / rdbchecksum yes
RDB 压缩和校验。
4.3 从库配置
文件:D:\redis\slave\redis-6380.conf
conf
port 6380
bind 127.0.0.1
protected-mode no
daemonize no
loglevel notice
logfile "D:/redis/slave/redis-6380.log"
dir "D:/redis/slave/data"
dbfilename dump.rdb
appendonly no
save 900 1
save 300 10
save 60 10000
rdbcompression yes
rdbchecksum yes
replicaof 127.0.0.1 6379
replica-read-only yes
关键参数说明
replicaof 127.0.0.1 6379
把当前实例配置为 6379 的从节点。
replica-read-only yes
从节点保持只读,避免误写。
4.4 启动命令
先启动主节点:
bat
cd /d D:\redis
redis-server.exe D:\redis\master\redis-6379.conf
再启动从节点:
bat
cd /d D:\redis
redis-server.exe D:\redis\slave\redis-6380.conf
4.5 验证主从状态
查看主节点复制信息:
bat
redis-cli.exe -p 6379 INFO replication
主节点正常时,一般能看到类似:
text
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=...
查看从节点复制信息:
bat
redis-cli.exe -p 6380 INFO replication
从节点正常时,一般能看到类似:
text
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
4.6 测试数据同步
向主节点写数据:
bat
redis-cli.exe -p 6379
执行:
redis
set user:name redis_test
get user:name
去从节点读取:
bat
redis-cli.exe -p 6380
执行:
redis
get user:name
如果返回一致,说明同步成功。
五、方案二:多台机器部署 Redis 一主一从
这个方案才更接近线上部署形态。
假设有两台机器:
- 主节点:
192.168.1.10 - 从节点:
192.168.1.11
5.1 主节点配置
主节点配置文件 /etc/redis/redis-6379.conf
conf
bind 192.168.1.10 127.0.0.1
protected-mode yes
port 6379
daemonize yes
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis-6379.log
dir /data/redis/6379
dbfilename dump.rdb
appendonly no
save 900 1
save 300 10
save 60 10000
rdbcompression yes
rdbchecksum yes
5.2 从节点配置
从节点配置文件 /etc/redis/redis-6379.conf
conf
bind 192.168.1.11 127.0.0.1
protected-mode yes
port 6379
daemonize yes
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis-6379.log
dir /data/redis/6379
dbfilename dump.rdb
appendonly no
save 900 1
save 300 10
save 60 10000
rdbcompression yes
rdbchecksum yes
replicaof 192.168.1.10 6379
replica-read-only yes
5.3 启动命令
主节点启动:
bash
redis-server /etc/redis/redis-6379.conf
从节点启动:
bash
redis-server /etc/redis/redis-6379.conf
验证方式和单机一样:
bash
redis-cli -h 192.168.1.10 -p 6379 INFO replication
redis-cli -h 192.168.1.11 -p 6379 INFO replication
5.4 多机部署需要注意什么
1. 网络必须互通
从节点必须能访问主节点端口。
2. 主从至少分开机器
否则没有机器级高可用价值。
3. 读写分离仍需要客户端配合
Redis 不会自动把你的读请求转发到从节点。
4. 只能提升读能力,不能解决单机容量瓶颈
如果数据量和写流量已经成为瓶颈,后续应考虑 Cluster。
六、给主从加密码认证
如果主节点启用了密码或 ACL,从节点复制时也要认证。
6.1 传统密码方式
主节点:
conf
requirepass 123456
从节点:
conf
replicaof 192.168.1.10 6379
masterauth 123456
replica-read-only yes
6.2 ACL 方式(更推荐)
主节点:
conf
user default off
user app_rw on >AppPass123 ~* +@all
user replica-user on >ReplicaPass123 +psync +replconf +ping
从节点:
conf
replicaof 192.168.1.10 6379
masteruser replica-user
masterauth ReplicaPass123
replica-read-only yes
七、Sentinel 是什么,为什么需要它
主从复制只能同步数据,不能自动切主。
如果主节点挂了,没有 Sentinel 的情况下,你通常要手动做这些事:
- 找到可用从节点
- 提升为主节点
- 修改其他从节点复制关系
- 修改应用配置
这显然不适合线上。
Sentinel 的核心能力是:
- 监控 Redis 主从实例
- 发现主节点故障
- 选举新主节点
- 自动故障转移
- 向客户端提供当前主节点地址
八、Sentinel 一主一从的推荐部署方式
如果你只是练习,可以:
- 1 个主 Redis
- 1 个从 Redis
- 3 个 Sentinel
虽然 Redis 只有一主一从,但 Sentinel 建议至少部署 3 个,这样才有多数派仲裁意义。
假设:
- Redis Master:
192.168.1.10:6379 - Redis Replica:
192.168.1.11:6379 - Sentinel1:
192.168.1.20:26379 - Sentinel2:
192.168.1.21:26379 - Sentinel3:
192.168.1.22:26379
九、Sentinel 配置文件示例
文件:/etc/redis/sentinel-26379.conf
conf
port 26379
bind 0.0.0.0
protected-mode yes
daemonize yes
pidfile /var/run/redis-sentinel-26379.pid
logfile /var/log/redis/sentinel-26379.log
sentinel monitor mymaster 192.168.1.10 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
如果主节点有密码:
conf
sentinel auth-pass mymaster 123456
如果使用 ACL:
conf
sentinel auth-user mymaster sentinel-user
sentinel auth-pass mymaster SentinelPass123
十、Sentinel 参数详解
10.1 sentinel monitor mymaster 192.168.1.10 6379 2
含义:
mymaster:主节点逻辑名称192.168.1.10 6379:主节点地址2:法定票数 quorum
也就是至少需要足够多的 Sentinel 共同确认主节点故障,才能继续推进后续流程。
10.2 sentinel auth-pass mymaster 123456
当 Redis 开启密码时,Sentinel 连接 Redis 也需要认证。
10.3 sentinel auth-user mymaster sentinel-user
当 Redis 使用 ACL 时,Sentinel 连接 Redis 需要用户名。
10.4 sentinel down-after-milliseconds mymaster 5000
表示 Sentinel 连续 5000 毫秒无法正确联系主节点时,就会把它判定为主观下线。
10.5 sentinel failover-timeout mymaster 60000
故障转移相关的超时时间窗口。
10.6 sentinel parallel-syncs mymaster 1
故障转移后,允许多少个 replica 同时重新同步新主。
值越小,failover 完成越慢,但能减少同时重同步对系统的冲击。
十一、Sentinel 启动方式
11.1 使用 sentinel 模式启动
bash
redis-server /etc/redis/sentinel-26379.conf --sentinel
或者:
bash
redis-sentinel /etc/redis/sentinel-26379.conf
具体以你的安装包是否包含 redis-sentinel 可执行文件为准。
11.2 查看 Sentinel 状态
连接 Sentinel:
bash
redis-cli -p 26379
查看主节点:
redis
SENTINEL get-master-addr-by-name mymaster
查看所有主节点:
redis
SENTINEL masters
查看某个主节点下的从节点:
redis
SENTINEL replicas mymaster
查看监控它的 Sentinel:
redis
SENTINEL sentinels mymaster
十二、Sentinel 故障切换验证
这是整套方案里最重要的验证步骤。
12.1 前置状态确认
先确认:
- 主节点正常
- 从节点正常
- 3 个 Sentinel 正常启动
SENTINEL masters能看到主节点信息
12.2 模拟主节点宕机
在主节点机器上停掉 Redis:
bash
redis-cli -p 6379 shutdown
或者直接停服务。
12.3 观察 Sentinel 日志
你会在 Sentinel 日志里看到类似过程:
- 标记主节点下线
- 多个 Sentinel 协同确认
- 选举 leader Sentinel
- 提升从节点为新主
- 修改复制拓扑
12.4 再次查询主节点地址
redis
SENTINEL get-master-addr-by-name mymaster
如果返回的地址变成了原来的从节点 IP,说明故障转移成功。
12.5 验证新的主从角色
去原从节点执行:
bash
redis-cli -h 192.168.1.11 -p 6379 INFO replication
应看到:
text
role:master
这说明它已被提升为主节点。
十三、客户端如何接入读写分离与 Sentinel
这里必须强调:
13.1 读写分离不是 Redis 自动做的
Redis 只做复制,不做应用请求路由。
你的客户端通常要维护:
- 主节点连接池:负责写
- 从节点连接池:负责读
13.2 Sentinel 模式下不能写死主节点地址
因为主节点可能切换。
客户端要支持通过 Sentinel 获取当前主节点地址。
13.3 线上建议的路由规则
建议至少这样分层:
- 强一致接口:只读主
- 普通读缓存:读从
- 写后马上读的接口:短时间强制读主
- 普通写:写主
因为 Redis 默认异步复制,读从节点可能读到旧数据。
十四、常见问题与排查方法
14.1 主从不通,master_link_status:down
常见原因:
- 从节点
replicaof地址写错 - 主节点没启动
- 网络不通
- 主节点有密码,但从节点没配置
masterauth - 防火墙未放行
14.2 主从同步慢
原因可能有:
- 网络延迟高
- 主节点负载高
- 首次全量同步数据量太大
- 磁盘写入性能差
14.3 从节点不能写
这是正常现象,因为配置了:
conf
replica-read-only yes
14.4 Sentinel 明明启动了,但没触发切主
重点排查:
- Sentinel 数量不够
monitor配置错误quorum设置过大- Sentinel 到 Redis 网络不通
auth-pass或auth-user没配置- Redis 只是短暂抖动,未达到
down-after-milliseconds
14.5 同一台机器能不能做主从加 Sentinel
能做,适合学习和测试。
但不适合生产高可用,因为宿主机一挂,Redis 和 Sentinel 都一起失效。
十五、线上部署建议
如果只是最小可用的一主一从读写分离,线上建议至少做到:
- 主从分开机器
- Sentinel 至少 3 个
- 开启认证
- 只开放内网访问
- 做复制监控和延迟监控
- 业务区分强一致读和普通读
- 不要把关键强一致数据完全依赖在异步复制的从节点读取上
十六、总结
本文完整演示了 Redis 一主一从读写分离的两种部署方式:
- 同机一主一从,适合本地测试
- 多机一主一从,适合线上基础部署
同时补充了 Sentinel 的完整配置、参数说明、启动和故障切换验证流程。
最后再总结一句:
- 主从复制 解决数据同步和读扩展
- Sentinel 解决高可用和自动切主
- 客户端 负责真正的读写路由
- 异步复制 决定了从节点读天然存在短暂延迟
如果后续数据量继续增大、单机内存或写入压力继续上升,那下一步就该考虑 Redis Cluster,而不是继续只靠一主一从扩展。