02-Redis高可用与复制
- 主从复制:全量复制 + 增量复制,断线重连优先增量
- 哨兵模式:监控、选主、通知,基于 Raft 投票选 Leader
- 脑裂问题:用 min-slaves-to-write 限制主库写入条件
- 选型:小规模用主从 + 哨兵,大规模用 Cluster
1. 主从复制
主库负责写,从库负责读,数据从主库同步到从库。这个和持久化配合使用,保证数据不丢。
1.1 全量复制
从库第一次连接主库,或者断线太久 backlog 追不上,触发全量复制:
从库发 psync → 主库执行 bgsave 生成 RDB → 发送 RDB → 从库加载
→ 主库把这期间的增量命令(replication buffer)也发过去
1.2 增量复制
正常同步时,主库把写命令写入 repl_backlog_buffer(环形缓冲区),从库持续读取执行。
断线重连后,只要偏移量还在 backlog 范围内,就走增量同步,不用全量。
repl-backlog-size 1mb # 根据写入速度 × 预估断线时间 × 2 来设置
1.3 主从从模式
从库多了,主库压力大。可以让从库再挂从库,分散压力:
主库 → 从库1 → 从库2、从库3
2. 哨兵模式
哨兵负责三件事:监控、选主、通知。
2.1 监控
哨兵周期性地给主从库发 PING 命令,检测是否在线。
单个哨兵可能误判,所以用多个哨兵组成集群一起判断。
2.2 哨兵集群怎么组建
基于 pub/sub 机制。
多个哨兵都连到主库,订阅 sentinel:hello 频道,通过这个频道互相知道对方的 IP 和端口,然后建立连接。
哨兵还会向主库发 INFO 命令,拿到从库列表,再和每个从库建立连接。
2.3 选主流程
分两步:筛选 + 打分
筛选条件:
- 从库当前是否在线
- 历史网络连接状态好不好
打分规则(按优先级):
| 优先级 | 规则 | 说明 |
|---|---|---|
| 1 | slave-priority | 从库优先级配置,值越小优先级越高 |
| 2 | slave_repl_offset | 复制进度,offset 越大得分越高 |
| 3 | 从库 ID | ID 小的得分高 |
先比优先级,一样再比复制进度,还一样就比 ID。
2.4 投票机制
基于 Raft 协议 进行选举。获得多数票(N/2+1)的哨兵成为 Leader,由它执行故障转移。
2.5 通知
选好新主库后:
- 通知其他从库执行
replicaof,连到新主库 - 通知客户端,把请求发到新主库
3. 脑裂问题
什么是脑裂:主库网络抖动,哨兵判定它下线并选出新主库,但原主库其实还活着,这时候出现两个主库。
客户端还在往原主库写数据,等原主库重新加入集群变成从库时,这些数据就丢了。
3.1 怎么解决
调整三个参数:
| 参数 | 含义 |
|---|---|
| min-slaves-to-write | 主库能写入的最少从库数量 |
| min-slaves-max-lag | 从库给主库发 ACK 的最大延迟(秒) |
| down-after-milliseconds | 多久没响应判定下线(毫秒) |
举个例子:
min-slaves-to-write = 1
min-slaves-max-lag = 10s
down-after-milliseconds = 10s
主库卡住 15s → 哨兵判定下线 → 开始主从切换。同时,因为主库卡了 15s,没有从库能在 10s 内完成数据复制,所以主库拒绝写入。
这样切换完成后,只有新主库能接收请求,不会丢数据。
4. 三种部署方式怎么选
| 主从复制 | 哨兵模式 | Cluster | |
|---|---|---|---|
| 高可用 | 无自动故障转移 | 自动故障转移 | 自动故障转移 |
| 数据分片 | 否 | 否 | 是 |
| 横向扩展 | 否 | 否 | 是 |
| 适合数据量 | < 10GB | < 10GB | 不限 |
| 适合 QPS | < 10 万 | < 10 万 | 不限 |
| 复杂度 | 低 | 中 | 高 |
小规模用主从 + 哨兵,数据量大或 QPS 高就上 Cluster。
5. 缓冲区
主从复制涉及几种缓冲区:
| 缓冲区 | 用途 | 能调大小吗 |
|---|---|---|
| 客户端输入缓冲区 | 存客户端发来的命令 | 不能 |
| 客户端输出缓冲区 | 存返回给客户端的数据 | 能 |
| 主从复制缓冲区 | 主库发给从库的数据 | 能 |
| 复制积压缓冲区 | 环形缓冲区,存增量同步的命令 | 能 |
所有缓冲区溢出的处理方式都一样:直接关闭连接。
配置方式:
# 普通客户端:硬限制 0,软限制 64MB/60s
client-output-buffer-limit normal 0 0 0
# 从库客户端:硬限制 256MB,软限制 64MB/60s
client-output-buffer-limit replica 256mb 64mb 60
# 发布订阅:硬限制 32MB,软限制 8MB/60s
client-output-buffer-limit pubsub 32mb 8mb 60