前言

在中大型互联网项目中,单机 Redis 存在三大硬伤:内存容量上限、单机写 QPS 瓶颈、单点故障丢失数据。Redis 3.0 推出原生 Cluster 集群,是官方唯一分布式分片方案,彻底解决哨兵模式无法水平扩展的痛点。本文从底层原理、三种集群架构对比、哈希槽分片机制、SpringBoot 集成实战、生产高频故障(脑裂、跨 key 报错、分布式锁失效)、扩容缩容运维全流程拆解,覆盖面试 + 业务开发双场景,具备完整落地价值。

一、Redis 三种集群架构横向对比(选型核心依据)

Redis 高可用分为三层:主从复制、哨兵 Sentinel、Cluster 分片集群,三者不是替代关系,是递进关系。

1. 主从复制(基础底座)

  • 架构:1 主 N 从,主负责写,从同步全量数据、分担读请求
  • 优势:部署简单、读写分离、数据多副本备份
  • 致命缺陷:主宕机需人工切换;所有节点存储全量数据,内存翻倍浪费;写只能单机承载,无法扩容
  • 适用:测试环境、单机小缓存

2. 哨兵 Sentinel(高可用,但不分片)

在主从基础上增加哨兵监控集群,自动故障转移:半数哨兵判定主下线,自动选举从晋升新主。

  • 优点:自动主从切换、客户端自动获取主节点、运维成本低
  • 缺点:无分片能力,所有节点存完整数据;写 QPS 受单机限制,数据量超百 GB 内存严重浪费
  • 标准生产配置:1 主 2 从 + 3 哨兵(最小高可用)
  • 适用:读多写少、QPS≤5 万、数据量 < 100G 的后台管理、用户基础信息缓存

3. Redis Cluster(分片分布式集群,生产主流)

无中心分布式架构,数据按哈希槽分片存储,多主节点分担读写,每个主搭配从节点实现高可用,是海量并发 / 大数据量业务唯一解。

  • 优点:
    1. 数据分片存储,内存水平扩展,新增节点分摊槽位
    2. 多主节点并行接收写请求,突破单机写 QPS 瓶颈
    3. 主节点宕机,对应从自动升级为主,保障高可用
    4. 无中间代理,客户端直连节点,性能损耗极低
  • 缺点:
    1. 不支持跨多槽多 key 操作(mget/mset多 key 分布不同主节点直接报错)
    2. 架构复杂,扩容缩容需要迁移槽位,运维成本更高
    3. 主从异步复制,极端网络分区存在脑裂数据丢失风险
  • 标准生产最小配置:3 主 3 从(3 个主分片,每个主配 1 个从,满足半数投票故障检测)
  • 适用:电商大促、商品热点缓存、百万级并发、数据量超 100GB、高写 QPS 业务

二、Redis Cluster 核心底层原理:16384 哈希槽分片机制

1. 什么是哈希槽 slot

Redis Cluster 固定划分0~16383 共 16384 个哈希槽,所有数据 key 全部归属某一个槽,槽绑定主节点,数据跟随槽存储。为什么固定 16384(2^14):

  1. 槽数量适中,集群元数据(槽与节点映射)占用内存极小,节点间同步压力低
  2. 扩容缩容仅迁移槽,无需重新计算全部 key,平衡一致性哈希缺陷
  3. CRC16 (key) % 16384 快速定位槽位,计算成本极低

2. Key 路由定位流程

  1. 客户端计算 key:slot = CRC16(key) % 16384
  2. 客户端连接任意集群节点,节点查询本地槽映射表:
    • 槽归属当前节点:直接执行读写
    • 槽归属其他节点:返回MOVED 槽 ip:port重定向指令
  3. 智能客户端(Lettuce/Redisson)本地缓存完整槽映射,下次直接访问目标节点,规避重复重定向损耗

3. 3 主 3 从集群槽分配示例

  • Master1:0 ~ 5460
  • Master2:5461 ~ 10922
  • Master3:10923 ~ 16383每个主节点绑定 1 台从节点,从节点仅同步对应主的全部槽数据,不分配独立槽,不处理写请求。

4. 故障自动转移机制

集群所有节点通过 PING-PONG 心跳互相通信,节点下线判定规则:

  1. 单个节点标记疑似下线pfail
  2. 超过半数主节点确认该节点下线,判定正式下线fail
  3. 自动将该主对应的从节点晋升为新主,接管全部哈希槽,集群恢复正常读写。

三、集群扩容 / 缩容:槽位在线迁移(不中断业务)

Cluster 最核心优势:在线增减节点,仅迁移哈希槽,业务无停机。

扩容流程(3 主→4 主)

  1. 启动新 Redis 实例,加入集群;
  2. 执行redis-cli --cluster reshard,自动从原有 3 个主节点迁出等量槽位到新主;
  3. 迁移过程分两步:
    • 源槽标记MIGRATING,目标槽标记IMPORTING
    • 逐个迁移槽内所有 key,迁移期间新旧节点均可读写,无数据丢失;
  4. 迁移完成,客户端自动刷新本地槽映射表,流量均衡分配至新节点。

缩容流程(4 主→3 主)

  1. 将待下线主节点所有槽位迁移至其他存活主;
  2. 槽全部迁移完毕后,执行命令删除该节点,完成缩容。

四、SpringBoot Java 客户端实战(Lettuce+Redisson 集群双方案)

SpringBoot 默认使用 Lettuce(NIO 非阻塞,线程安全)作为 Redis 底层客户端,Redisson 封装分布式锁、限流、队列等高级能力,生产项目同时引入两者。

1. Maven 依赖

<!-- Spring Redis 基础(内置Lettuce) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Redisson 集群、分布式锁专用 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.18.2</version>
</dependency>

2. application.yml 集群配置(3 主 3 从)

spring:
  redis:
    password: Redis@123456
    timeout: 3000ms
    cluster:
      # 填写集群全部6个节点IP端口
      nodes:
        - 127.0.0.1:7001
        - 127.0.0.1:7002
        - 127.0.0.1:7003
        - 127.0.0.1:7004
        - 127.0.0.1:7005
        - 127.0.0.1:7006
      max-redirects: 6 # 最大重定向次数,迁移槽位时生效
    lettuce:
      pool:
        max-active: 64
        max-idle: 16
        min-idle: 8
        max-wait: 2000ms

3. Lettuce StringRedisTemplate 基础操作(通用缓存)

@Resource
private StringRedisTemplate stringRedisTemplate;

public void cacheDemo() {
    // 单key操作无任何限制
    stringRedisTemplate.opsForValue().set("product:1001", "商品详情", 1, TimeUnit.HOURS);
    String data = stringRedisTemplate.opsForValue().get("product:1001");

    // 禁止跨槽多key!如下代码会直接抛出异常
    // stringRedisTemplate.opsForValue().multiSet(Map.of("k1","v1","k2","v2"));
}

4. Redisson 集群分布式锁(解决缓存击穿、并发更新竞争)

@Bean
public RedissonClient redissonClient() {
    Config config = new Config();
    ClusterServersConfig clusterConfig = config.useClusterServers();
    clusterConfig.addNodeAddress("127.0.0.1:7001","127.0.0.1:7002","127.0.0.1:7003","127.0.0.1:7004","127.0.0.1:7005","127.0.0.1:7006");
    clusterConfig.setPassword("Redis@123456");
    return Redisson.create(config);
}

// 业务使用分布式互斥锁
@Resource
private RedissonClient redissonClient;

public void updateHotProduct(Long productId) throws InterruptedException {
    String lockKey = "lock:product:" + productId;
    String cacheKey = "product:hot:" + productId;
    RLock lock = redissonClient.getLock(lockKey);
    try {
        boolean acquire = lock.tryLock(3, 10, TimeUnit.SECONDS);
        if (acquire) {
            // 串行更新缓存,解决并发set覆盖问题
            stringRedisTemplate.opsForValue().set(cacheKey, "新商品数据", 3600, TimeUnit.SECONDS);
        }
    } finally {
        if (lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
}

5. 多 key 跨槽报错解决方案

Cluster 禁止mget/mset操作多个不同槽 key,三种落地方案:

  1. 哈希标签 {}:强制多个 key 落在同一哈希槽,{order:1001}:info{order:1001}:stock,大括号内内容参与哈希计算;
  2. 循环单 key 批量读写,牺牲少量性能换取集群兼容;
  3. 数据聚合封装为 Hash 结构,单 key 存储多字段。

五、生产高频致命问题与解决方案(面试核心考点)

1. 集群脑裂 Split-Brain(最严重数据丢失问题)

现象

网络分区隔离,原主节点与集群大部分节点断开,客户端仍可写入旧主;集群剩余节点选举出新主。网络恢复后,旧主强制降级为从,全量同步新主数据,脑裂期间写入旧主的数据全部清空丢失。

防护配置(redis.conf)
# 主节点至少同步2个从节点才允许写入,减少脑裂写入窗口
min-replicas-to-write 2
# 从节点同步延迟超过10秒,主停止接收写请求
min-replicas-max-lag 10
分布式锁衍生风险

脑裂期间新旧主同时存在,分布式锁会出现两把锁,导致并发超卖。高一致性业务使用RedLock多节点锁方案兜底。

2. 槽位迁移 MOVED 重定向性能损耗

旧客户端无本地槽缓存,每次请求触发两次转发,QPS 高时性能减半。解决:统一使用 Lettuce/Redisson 智能客户端,启动自动拉取CLUSTER SLOTS缓存路由表。

3. 主从异步复制,分布式锁失效

主节点写入锁后未同步到从节点,主宕机从晋升新主,锁丢失,多线程同时获取锁。解决

  1. 金融等高一致性业务使用 RedLock;
  2. 普通业务搭配 AOF 持久化,降低同步丢失概率;
  3. 业务执行完成二次校验锁持有者。

4. 缓存雪崩 / 击穿集群适配方案

  1. 雪崩:所有 key 过期时间增加随机偏移,打散过期窗口;
  2. 击穿:热点 key 使用逻辑永不过期(CacheWrap 包装逻辑过期) + 分布式互斥锁双方案,避免槽位集中过期批量打库。

六、集群运维规范与最佳实践

  1. 最小部署标准:3 主 3 从,禁止单主单从、2 主集群(无法满足半数投票,故障转移失效);
  2. 节点物理隔离:主从节点部署不同服务器,避免单机宕机丢失分片全部数据;
  3. 持久化配置:开启 AOF 每秒刷盘,防止宕机数据丢失;
  4. 监控指标:持续监控cluster_state集群状态、pfail疑似下线节点、槽位分配均衡度;
  5. 禁止大 key:单 key 超过 100MB 迁移槽位阻塞集群,拆分 Hash/List;
  6. 扩容缩容低峰执行:凌晨低流量迁移槽,减少业务延迟;
  7. 集群不支持多 db,全部使用 db0,项目不要切换库。

七、三种集群架构选型总结

架构 分片扩容 自动故障转移 内存利用率 并发上限 适用场景
主从复制 不支持 人工切换 极低(全量副本) 单机上限 测试、小型单机缓存
哨兵 Sentinel 不支持 自动切换 极低(全量副本) 单机上限 低并发读多写少后台业务
Redis Cluster 支持槽位分片 自动切换 高(分片存储) 多主并行扩容 高并发、大数据量、大促核心缓存

结语

Redis Cluster 是中高级 Java 开发必掌握的分布式缓存架构,不仅要会配置使用,更要吃透哈希槽分片、脑裂故障、跨 key 限制、分布式锁集群陷阱等底层问题。日常开发中,绝大多数高并发缓存、分布式会话、限流场景都会基于 Cluster 集群落地,同时也是面试分布式缓存板块最高频的考点。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐