Redis 主从复制与 Sentinel 高可用

深入 Redis 主从复制原理(全量/增量同步、复制偏移量)、Sentinel 哨兵自动故障转移机制与读写分离架构实践。

1. 主从复制(Replication)

1.1 复制流程

Slave 发起同步 ──→ Master 判断同步方式 ──→ 全量或增量同步

全量同步(首次或 runid 不匹配):
  1. Slave 发送 PSYNC ? -1
  2. Master 执行 BGSAVE → 生成 RDB
  3. Master 发送 RDB 到 Slave
  4. Slave 清空内存 → 加载 RDB
  5. Master 将新写入命令追加到 Replication Buffer → 发送给 Slave
  6. 进入持续同步模式

增量同步(offset 在 replication backlog 内):
  1. Slave 发送 PSYNC <runid> <offset>
  2. Master 检查 offset 是否在 backlog 中
  3. 直接发送缺失部分的命令 → Slave 执行
  4. 无需全量 RDB,快速恢复

1.2 关键概念

概念说明
runidMaster 的唯一标识,重启后改变
offset复制偏移量,Master 和 Slave 各自维护
replication backlogMaster 的固定大小缓存区(默认 1MB),存储最近命令
Replication Buffer每个 Slave 连接的独立输出缓存
# 查看复制状态
INFO replication
# role:master
# connected_slaves:2
# slave0:ip=192.168.1.2,port=6379,state=online,offset=123456,lag=0
# master_repl_offset:123456

1.3 配置

# Slave 配置
replicaof 192.168.1.1 6379
masterauth <password>
replica-read-only yes

# 允许 Slave 处理过期 key(默认)
replica-lazy-flush yes

2. Sentinel 哨兵模式

2.1 架构与职责

                Client (连接 Sentinel 获取地址)
                  │
  ┌───────────────┼───────────────┐
  │               │               │
Sentinel-1   Sentinel-2    Sentinel-3  (至少 3 个,奇数)
  │               │               │
  └───────────────┼───────────────┘
                  │
            ┌─────▼─────┐
            │  Master   │
            └─────┬─────┘
         ┌────────┴────────┐
    ┌────▼────┐       ┌────▼────┐
    │ Slave 1 │       │ Slave 2 │
    └─────────┘       └─────────┘

Sentinel 职责:
1. 监控:定时 ping Master/Slave/Sentinel
2. 通知:故障时通知管理员(通过脚本)
3. 自动故障转移:Master 宕机 → 选举新 Master
4. 配置提供:客户端向 Sentinel 询问当前 Master 地址

2.2 故障转移流程

1. Sentinel-1 发现 Master 无响应(主观下线,SDOWN)
2. 询问其他 Sentinel,多数同意 → 客观下线(ODOWN)
3. 选举 Leader Sentinel(Raft 算法)
4. Leader 选择最优 Slave 提升为 Master(选择优先级最高、复制最完整的)
5. 原 Slave 重新配置为新 Master 的 Slave
6. 客户端通过 Sentinel 获取新 Master 地址

2.3 Sentinel 配置

# sentinel.conf
sentinel monitor mymaster 192.168.1.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster password
参数说明
monitor监控的 Master,最后的 2 是「同意下线」的 Sentinel 数
down-after-milliseconds无响应判定为下线的时间
failover-timeout故障转移超时
parallel-syncs同时重新配置的 Slave 数

2.4 脑裂问题与解决

# 脑裂:网络分区时,原 Master 和 Sentinel 断开
# 原 Master 仍在写入,但已经不被 Sentinel 认可
# 分区恢复后,原 Master 的数据被覆盖 → 数据丢失

# 解决方案:主库最小从库数 + 延迟限制
min-replicas-to-write 1        # 至少有 1 个 Slave 同步才能写入
min-replicas-max-lag 10        # Slave 延迟超过 10 秒则拒绝写入

3. 读写分离

// Spring Boot + Lettuce 读写分离
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
    LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
        .readFrom(ReadFrom.REPLICA_PREFERRED)  // 优先从 Slave 读
        .build();

    RedisStaticMasterReplicaConfiguration config =
        new RedisStaticMasterReplicaConfiguration("master", 6379);
    config.addNode("slave1", 6379);
    config.addNode("slave2", 6379);

    return new LettuceConnectionFactory(config, clientConfig);
}

// 纯 Lettuce
RedisClient client = RedisClient.create("redis://master:6379");
StatefulRedisMasterReplicaConnection<String, String> conn = MasterReplica.connect(
    client, StringCodec.UTF8,
    RedisURI.create("redis://slave1:6379"),
    RedisURI.create("redis://slave2:6379")
);
conn.setReadFrom(ReadFrom.REPLICA_PREFERRED);

延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「redis」更多文章

  1. Redis 性能调优与生产监控
  2. 09. Java 客户端与 Spring Data Redis
  3. Redis 事务、Lua 脚本与原子操作