知识模块
☕ Java 知识模块
十、中间件
Redis 主从复制

Redis 主从复制与高可用

Redis 提供了主从复制机制,实现数据的读写分离和高可用。

一、主从复制原理

1. 基本概念

  • 主节点(Master):负责写操作
  • 从节点(Slave):负责读操作,数据从主节点同步
        写请求

    ┌─────────────┐
    │   Master    │
    │  (主节点)    │
    └──────┬──────┘
           │ 复制
    ┌──────┴──────┐
    ↓             ↓
┌─────────┐  ┌─────────┐
│ Slave1  │  │ Slave2  │
└─────────┘  └─────────┘
    ↑             ↑
   读请求        读请求

2. 复制流程

1. 从节点连接主节点,发送 SYNC 命令
2. 主节点执行 BGSAVE,生成 RDB 快照
3. 主节点将 RDB 发送给从节点
4. 从节点加载 RDB 文件
5. 主节点将期间的写命令发送给从节点(增量复制)
6. 后续写命令持续同步

3. 配置方式

# 方式一:配置文件
replicaof 192.168.1.100 6379
 
# 方式二:命令行
REPLICAOF 192.168.1.100 6379
 
# 取消主从关系
REPLICAOF NO ONE

二、数据同步机制

1. 全量同步

触发条件:

  • 从节点第一次连接主节点
  • 从节点断开时间过长,复制积压缓冲区不足
从节点                    主节点
  │                         │
  │──── PSYNC ? -1 ────────→│  请求同步
  │                         │
  │←─── +FULLRESYNC ───────│  全量同步
  │                         │
  │                         │ BGSAVE
  │                         │ 生成RDB
  │                         │
  │←──── RDB 文件 ─────────│  发送快照
  │                         │
  │  加载RDB                │
  │                         │
  │←──── 增量命令 ─────────│  发送缓冲区命令
  │                         │

2. 增量同步

触发条件:

  • 从节点短暂断开后重连
  • 复制积压缓冲区中有足够的偏移量
从节点                    主节点
  │                         │
  │── PSYNC offset ────────→│  带偏移量请求
  │                         │
  │←── +CONTINUE ──────────│  增量同步
  │                         │
  │←── 缺失的命令 ─────────│  发送偏移量后的命令
  │                         │

3. 复制积压缓冲区

  • 环形缓冲区,默认 1MB
  • 存储最近的写命令
  • 配置建议:repl-backlog-size 100mb

三、哨兵机制(Sentinel)

1. 哨兵的作用

  • 监控:检测主从节点是否正常
  • 通知:节点异常时通知应用方
  • 自动故障转移:主节点故障时选举新主节点

2. 哨兵架构

        ┌──────────────────┐
        │   Sentinel 集群   │
        │  S1    S2    S3   │
        └────────┬─────────┘
                 │ 监控
    ┌────────────┼────────────┐
    ↓            ↓            ↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Master  │ │ Slave1  │ │ Slave2  │
└─────────┘ └─────────┘ └─────────┘

3. 故障转移流程

1. Sentinel 检测到 Master 下线
2. Sentinel 集群选举领头 Sentinel
3. 领头 Sentinel 从 Slave 中选举新 Master
4. 其他 Slave 复制新 Master
5. 通知客户端新 Master 地址

4. 主观下线 vs 客观下线

类型说明判定条件
主观下线(SDOWN)单个 Sentinel 认为节点下线心跳超时
客观下线(ODOWN)多数 Sentinel 认为主节点下线超过 quorum 数量

5. 哨兵配置

# sentinel.conf
port 26379
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

参数说明:

  • monitor:监控的主节点信息,2 表示 quorum 数量
  • down-after-milliseconds:判定下线的超时时间
  • parallel-syncs:故障转移时同时同步的从节点数量
  • failover-timeout:故障转移超时时间

四、Redis Cluster

1. 集群架构

Redis Cluster 采用无中心架构,数据分片存储在多个节点。

┌─────────┐  ┌─────────┐  ┌─────────┐
│ Master1 │  │ Master2 │  │ Master3 │
│ 0-5460  │  │5461-10922│ │10923-16383│
└────┬────┘  └────┬────┘  └────┬────┘
     │            │            │
┌────┴────┐  ┌────┴────┐  ┌────┴────┐
│ Slave1  │  │ Slave2  │  │ Slave3  │
└─────────┘  └─────────┘  └─────────┘

2. 数据分片

Redis Cluster 使用 16384 个哈希槽(slot):

# 计算键所属槽位
def slot(key):
    return CRC16(key) % 16384
  • 每个 Master 负责一部分槽位
  • 客户端可以连接任意节点
  • 节点间通过 Gossip 协议通信

3. 集群配置

# redis.conf
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-require-full-coverage yes

4. 集群命令

# 创建集群
redis-cli --cluster create \
  192.168.1.101:6379 \
  192.168.1.102:6379 \
  192.168.1.103:6379 \
  192.168.1.104:6379 \
  192.168.1.105:6379 \
  192.168.1.106:6379 \
  --cluster-replicas 1
 
# 查看集群信息
CLUSTER INFO
CLUSTER NODES

五、持久化机制

1. RDB(快照)

# 配置
save 900 1      # 900秒内有1次修改则保存
save 300 10     # 300秒内有10次修改则保存
save 60 10000   # 60秒内有10000次修改则保存
 
# 手动触发
SAVE            # 阻塞主进程
BGSAVE          # 后台fork子进程

优点

  • 文件紧凑,适合备份
  • 恢复速度快
  • 对性能影响小

缺点

  • 可能丢失最后一次快照后的数据
  • fork 大数据集时可能阻塞

2. AOF(日志)

# 配置
appendonly yes
appendfilename "appendonly.aof"
 
# 同步策略
appendfsync always     # 每次写入同步(最安全最慢)
appendfsync everysec   # 每秒同步(推荐)
appendfsync no         # 由操作系统决定
 
# AOF 重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

优点

  • 数据更安全,最多丢失 1 秒数据
  • 日志可读,便于分析

缺点

  • 文件体积大
  • 恢复速度慢
  • 对性能有一定影响

3. 混合持久化(Redis 4.0+)

aof-use-rdb-preamble yes

AOF 重写时,先写入 RDB 格式数据,再追加增量 AOF 命令。

六、面试高频问题

Q1: 主从复制延迟怎么解决?

  1. 使用异步复制(默认)
  2. 优化网络延迟
  3. 读写分离时,关键读操作走主节点
  4. 使用 WAIT 命令等待复制完成
WAIT numreplicas timeout
# 等待 numreplicas 个从节点确认,超时 timeout 毫秒

Q2: 哨兵如何选举新主节点?

选举优先级:

  1. 优先级配置 replica-priority
  2. 复制偏移量越大越优先
  3. runid 越小越优先

Q3: Redis Cluster 如何处理请求?

客户端 → 节点A

   计算 key 的 slot

  slot 属于节点B?
    ├── 是 → 处理请求
    └── 否 → MOVED 重定向 → 客户端重连节点B

Q4: RDB 和 AOF 如何选择?

场景推荐
数据安全要求高AOF
可以接受分钟级丢失RDB
兼顾安全和性能混合持久化
数据量大RDB

Q5: 如何保证主从一致性?

  1. 使用 WAIT 命令等待从节点同步
  2. 开启 min-replicas-to-write 配置
  3. 使用 Redis 6.0 的多线程复制
# 至少有1个从节点才能写入
min-replicas-to-write 1
min-replicas-max-lag 10

七、最佳实践

1. 生产架构推荐

客户端

┌──────────────┐
│   Sentinel   │  × 3(奇数个)
└──────┬───────┘

┌──────┴───────┐
↓              ↓
Master ←──→ Slave

   读写分离

2. 监控指标

  • 复制偏移量(master_repl_offset)
  • 从节点延迟(lag)
  • 主从连接状态
  • 持久化耗时

3. 运维建议

  • 主从节点放在不同机房
  • 哨兵节点数量建议奇数(3、5)
  • 合理设置复制积压缓冲区
  • 定期检查持久化文件

更新时间:2026年3月16日