云计算百科
云计算领域专业知识百科平台

Redis 学习笔记(五):高可用——主从复制与哨兵集群

单机 Redis 挂了怎么办?数据怎么备份?这篇讲 Redis 的高可用方案:主从复制让数据有备份、读写分离,哨兵让故障自动切换,保证服务不中断。


一、为什么需要主从复制?

1.1 单机 Redis 的隐患

单机部署 Redis 有三个问题:

  • 单点故障 — 这台机器一挂,所有依赖 Redis 的服务全部瘫痪
  • 数据没有备份 — 机器磁盘损坏,内存里的数据全没了
  • 读性能瓶颈 — 所有读请求都压在一台机器上,扛不住高并发
  • 1.2 主从复制的思路

    主从复制(Master-Slave Replication):一台主节点(Master)负责写,一台或多台从节点(Slave)负责读,数据实时同步到从节点。

    写请求
    ↓
    ┌───┴───┐
    │ Master │ ← 唯一能写的
    └───┬───┘
    复制同步 │
    ┌──────┴──────┐
    ┌──┴──┐ ┌──┴──┐
    │Slave1│ │Slave2│ ← 只负责读
    └─────┘ └─────┘
    ↑ 读请求 ↑ 读请求

    主从复制解决了三个问题:

  • 容灾备份 — 主节点挂了,从节点还有数据,可以顶上
  • 读写分离 — 写走主节点,读走从节点,分担读压力,提升吞吐
  • 高可用基础 — 配合哨兵,主节点故障能自动切换

  • 二、如何配置主从

    2.1 命令行方式(临时)

    从节点上用 slaveof 指定主节点:

    # 在从节点上执行
    SLAVEOF 192.168.1.100 6379
    # 让当前节点成为 192.168.1.100:6379 的从节点

    2.2 配置文件方式(推荐)

    在从节点的 redis.conf 里加:

    # 指定主节点地址
    slaveof 192.168.1.100 6379
    # 主节点有密码就配置
    masterauth 123456

    重启从节点即可生效。

    2.3 查看复制状态

    用 info replication 查看:

    127.0.0.1:6379> info replication
    role:master # 角色:主节点
    connected_slaves:2 # 有2个从节点


    三、复制原理

    3.1 全量复制 vs 增量复制

    主从同步分两种情况:

    第一次同步(全量复制):

  • 从节点发 PSYNC 请求
  • 主节点生成 RDB 快照(内存数据的完整镜像),同时把期间的新命令记录在复制积压缓冲区
  • 主节点把 RDB 发给从节点,从节点加载,得到主节点的完整数据
  • 主节点把积压缓冲区里的新命令补发给从节点
  • 后续同步(增量复制):

    • 主节点每次写操作,都把命令发给从节点执行
    • 从节点持续跟进主节点的最新状态

    3.2 断线重连

    如果主从连接中断,从节点重连后,会尝试用增量复制补上断开的命令——只要命令还在复制积压缓冲区里就能补;如果断了太久缓冲区被覆盖,就退化成全量复制。


    三-补充、Redis 持久化:RDB 与 AOF

    主从复制的全量复制依赖 RDB,所以这里把 Redis 的持久化机制一起讲了。持久化解决的是"Redis 重启后数据不丢"的问题。

    3.1 为什么需要持久化

    Redis 数据在内存里,一重启就没了。但如果 Redis 挂了重启后数据全部丢失,缓存还得重新从数据库加载,高并发下瞬间压垮数据库。所以要把数据落盘。

    Redis 有两种持久化方式:RDB(快照) 和 AOF(追加日志)。

    3.2 RDB 快照持久化

    RDB 是把某个时刻的内存数据完整保存成一个二进制文件(默认 dump.rdb)。主从全量复制传的就是这个文件。

    触发方式:

    • 手动 SAVE(阻塞)或 BGSAVE(后台异步)
    • 配置自动触发:N秒内M次写就保存

    # 60秒内有1000次写,就生成快照
    save 60 1000

    优点: 文件小、加载快、适合备份
    缺点: 是"某个时间点的快照",两次快照之间的数据可能丢

    3.3 AOF 追加持久化

    AOF 是把每次写命令追加到日志文件里。重启时重放日志,恢复数据。

    # 开启AOF
    appendonly yes
    # 写策略:always每次写都落盘 / everysec每秒落盘 / no交给系统
    appendfsync everysec

    优点: 数据丢失少(everysec最多丢1秒数据)
    缺点: 文件大、重启加载慢

    3.4 两种怎么选

    对比RDBAOF
    数据完整性 可能丢两次快照间数据 everysec最多丢1秒
    文件大小 小 大
    恢复速度 快 慢
    占用CPU 生成快照时高 写日志持续

    生产实践:两个都开,RDB 做冷备,AOF 保证数据。 Redis 4.0 之后还支持 AOF 重写和混合持久化,这里不展开。


    四、哨兵模式(Sentinel)

    4.1 主从复制的缺点

    主从复制解决了备份和读压力,但有个大问题:主节点挂了,系统就停了。

    • 主节点宕机后,从节点虽然有数据,但不会自动升级为主节点
    • 写请求仍然指向已宕机的主节点,服务中断,需要人工介入

    4.2 哨兵是什么

    哨兵(Sentinel)就是 Redis 的"监控+自动故障转移"组件。 它干三件事:

  • 监控 — 持续监控主从节点是否存活
  • 通知 — 节点故障时通知其他节点和管理员
  • 自动故障转移 — 主节点挂了,自动把某个从节点提升为新主节点,并通知其他从节点和客户端重新连接
  • 哨兵 Sentinel
    │ 监控
    ├── 监控 Master
    ├── 监控 Slave1
    └── 监控 Slave2

    4.3 哨兵架构

    实际部署时,哨兵本身也要多实例部署(一般3个或以上),避免哨兵自己也变成单点:

    ┌── Sentinel1
    Master ← ├── Sentinel2 ← 三个哨兵互相监控,共同决策
    └── Sentinel3
    │
    Slave1 Slave2

    为什么哨兵要多数? 哨兵判断主节点是否故障,采用"主观下线 + 客观下线"机制:

    • 一个哨兵发现联系不上主节点 → 主观下线(自己判断)
    • 多数哨兵(超过一半)都认为主节点下线 → 客观下线(大家一致)→ 才触发故障转移

    这样不会因为网络抖动一个哨兵误判就切换。

    4.4 故障转移流程

    1. 主节点 Master 突然宕机
    2. 哨兵发现,标记主观下线
    3. 多数哨兵确认 → 客观下线
    4. 哨兵们选举一个 Leader 哨兵
    5. Leader 哨兵从从节点里选一个(优先选数据最全、优先级最高、runid最小的)
    6. 把这个从节点提升为新 Master
    7. 通知其他从节点重新指向新 Master
    8. 通知客户端,客户端连接新 Master

    整个过程自动完成,业务无需人工介入,服务不中断。


    五、哨兵的部署

    5.1 配置文件

    每台哨兵机器的 sentinel.conf:

    # 监听主节点(mymaster是自定义名称)
    sentinel monitor mymaster 192.168.1.100 6379 2
    # 2表示:至少2个哨兵同意才算客观下线

    # 主节点密码
    sentinel auth-pass mymaster 123456

    # 主节点宕机后,多少毫秒内没响应算主观下线
    sentinel down-after-milliseconds mymaster 5000

    # 故障转移后,同时能同步到几个从节点
    sentinel parallel-syncs mymaster 1

    5.2 启动哨兵

    redis-sentinel /path/to/sentinel.conf

    启动多个哨兵实例,每个用不同配置(port不同)。

    5.3 Java 客户端连接哨兵

    // 配置哨兵地址
    Set<String> sentinels = new HashSet<>(Arrays.asList(
    "192.168.1.101:26379",
    "192.168.1.102:26379",
    "192.168.1.103:26379"
    ));

    // Jedis 连接哨兵,自动发现当前主节点
    JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);

    try (Jedis jedis = pool.getResource()) {
    jedis.set("name", "小明");
    }

    客户端通过哨兵找到当前的主节点,主节点切换后,哨兵会告知客户端新地址,客户端自动重连。


    六、脑裂问题(Split Brain)

    6.1 什么是脑裂

    哨兵模式下有个经典问题——脑裂。场景:

    主节点和哨兵之间的网络断了(但主节点本身没挂)
    哨兵判断主节点"客观下线"(多数同意)
    触发故障转移,把一个从节点提升为新主节点
    同时,原主节点其实还活着,还在接受写请求
    → 现在有两个"主节点"在写数据,两边数据不一致(脑裂)

    原主节点网络恢复后,哨兵会让它变成从节点,但它已经写了很多数据,和真正的主节点不一致,这些数据就丢了。

    6.2 怎么解决

    两个关键配置:

    # 主节点必须至少有1个从节点连接
    # 否则停止接收写请求
    min-slaves-to-write 1

    # 从节点与主节点的最大延迟超过10秒
    # 主节点也停止接收写请求
    min-slaves-max-lag 10

    意思是:主节点如果发现自己连不上从节点(或从节点太慢),就拒绝写请求,而不是傻傻地继续写。这样即使发生脑裂,原主节点也不会写入新数据,等它恢复成从节点时,数据还是干净的。


    七、Redis Cluster 集群(了解)

    主从+哨兵解决了高可用,但还有个问题:数据量太大,一台主节点存不下。

    Redis Cluster 是官方的集群方案,解决海量数据问题:

    • 把数据分成 16384 个哈希槽(hash slot),分布到多个主节点
    • 每个主节点负责一部分槽
    • 每个主节点可以有从节点(高可用)
    • 客户端根据 key 的哈希值路由到对应节点

    Cluster
    ├── 节点A:槽 0-5460
    ├── 节点B:槽 5461-10922
    └── 节点C:槽 10923-16383

    什么时候用 Cluster? 单台 Redis 内存不够、需要横向扩展容量时。中小项目单主+哨兵就够了,不用上集群。


    八、选型总结

    方案解决的问题适用场景
    单机 无 开发测试
    主从复制 备份、读压力 数据要有备份
    主从 + 哨兵 高可用、自动切换 生产环境标配
    Cluster 海量数据、横向扩展 数据量巨大的场景

    生产环境标配:主从复制 + 哨兵。 既保证数据有备份,又保证主节点故障自动切换,服务不中断。


    本篇小结

    • 主从复制:主写从读,数据实时同步,解决备份和读压力
    • 全量复制用 RDB 快照,增量复制持续同步,断线用缓冲区补
    • 哨兵监控主从,主节点挂了自动把从节点提升为新主,故障转移自动完成
    • 哨兵要多实例部署(≥3个),靠"多数同意"避免误判
    • 脑裂用 min-slaves-to-write 配置防止主节点孤军写数据
    • 数据量太大用 Cluster,把数据分散到多个节点
    • 生产标配:主从 + 哨兵
    • 下一篇进入高并发专题:缓存穿透、击穿、雪崩
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Redis 学习笔记(五):高可用——主从复制与哨兵集群
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!