从零起步学习Redis || 第十二章:Redis Cluster集群如何解决Redis单机模式的性能瓶颈及高可用分布式部署方案详解

引言:

在日常后端开发中,Redis 凭借其高性能与多样的数据结构,几乎成为系统缓存和分布式架构中的标配。然而,随着业务数据量的持续增长与系统高可用需求的提升,单机版 Redis 的性能瓶颈与单点故障问题逐渐显现。为了解决这些问题,Redis 官方推出了 Redis Cluster(集群模式) ------ 一种支持自动分片与高可用的分布式部署方案。

本文将通过通俗易懂的讲解与实际示例,带你深入理解 Redis Cluster 的工作原理:它是如何将数据分布到不同节点的?客户端又是如何知道该访问哪个节点?当节点出现故障时,Redis Cluster 又如何自动完成故障转移?无论你是刚接触 Redis 的初学者,还是希望系统化掌握分布式缓存机制的后端开发者,相信这篇文章都能帮你彻底搞懂 Redis Cluster 的核心机制。

一、为什么需要 Redis Cluster?

在单机模式下,Redis 性能非常高,但存在以下瓶颈:

  1. 内存容量限制:单机 Redis 受限于服务器内存,无法存储更大数据量。

  2. 性能瓶颈:所有请求都集中在一个实例上,吞吐量受限。

  3. 单点故障风险:主节点宕机会导致服务不可用。

  4. 扩展性差:水平扩展困难。

Redis Cluster(集群模式) 的目标就是:

  • 自动分片(sharding):把数据自动分散到多个节点上。

  • 高可用(HA):部分节点宕机时仍可继续提供服务。

  • 无中心架构:没有"中心节点",所有节点平等,去中心化管理。


二、Redis Cluster 的基本结构

Redis Cluster 通常由多个节点组成,每个节点可能是:

  • 主节点(Master):存放实际数据。

  • 从节点(Slave):主节点的备份,用于容灾和高可用。

例如,一个典型的 6 节点集群:

复制代码
3 个主节点(M1, M2, M3)
3 个从节点(S1, S2, S3)

S1 是 M1 的从节点,S2 是 M2 的从节点,S3 是 M3 的从节点。


三、数据分片机制(slot 槽)

Redis Cluster 把整个数据空间划分为 16384 个槽(hash slots)

  • 每个主节点负责管理一部分槽(比如 M1 管理 0~5460,M2 管理 5461~10922,M3 管理 10923~16383)。

  • 每条数据(key)通过以下算法映射到具体槽位:

    slot = CRC16(key) mod 16384

这样就能知道某个 key 应该放在哪个节点上。


四、Redis Cluster 的工作流程(核心原理)

示例场景:一个三主三从的 Redis Cluster

假设我们有一个 6 节点的 Redis 集群:

节点角色 IP 地址 负责的哈希槽范围
主节点 M1 192.168.1.10:6379 0 ~ 5460
主节点 M2 192.168.1.11:6379 5461 ~ 10922
主节点 M3 192.168.1.12:6379 10923 ~ 16383
从节点 S1 192.168.1.13:6379 M1 的从节点
从节点 S2 192.168.1.14:6379 M2 的从节点
从节点 S3 192.168.1.15:6379 M3 的从节点

Step 1:客户端启动并连接集群

Java 程序中创建 JedisCluster(或 LettuceClusterClient)对象,连接任意节点即可:

复制代码
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.1.10", 6379)); // 随便一个节点即可
JedisCluster cluster = new JedisCluster(nodes);

客户端会在启动时:

  1. 连接到任意节点(比如 M1);

  2. 发送命令 CLUSTER SLOTS

  3. 获取整个集群的槽分配表(slot map)

    复制代码
    [
      [0,5460, "192.168.1.10",6379],
      [5461,10922, "192.168.1.11",6379],
      [10923,16383, "192.168.1.12",6379]
    ]
  4. 客户端缓存该表,用于后续路由。


Step 2:客户端写入数据(SET 命令)

客户端执行:

复制代码
SET user:1001 "Tom"

流程如下:

  1. 客户端计算槽号:

    复制代码
    slot = CRC16("user:1001") % 16384 = 7000
  2. 查 slot 表,发现槽 7000 在范围 5461~10922 → 属于节点 M2。

  3. 客户端直接向 192.168.1.11:6379(M2) 发送命令:

    复制代码
    SET user:1001 "Tom"
  4. M2 存储键值对 {user:1001 -> Tom} 并返回 OK。

  5. M2 自动将数据同步到它的从节点 S2(主从复制)。

结果:

  • M2 存有数据;

  • S2 有一份副本;

  • 其他节点无此数据。


Step 3:客户端读取数据(GET 命令)

执行:

复制代码
GET user:1001
  1. 客户端再次计算 slot = 7000;

  2. 发现 M2 负责;

  3. 直接向 M2 发送 GET

  4. M2 返回 "Tom"

正常返回结果,无需中转或重定向。


Step 4:如果客户端访问了错误的节点

假设客户端因为缓存的 slot 表过期,错误地向 M1 发请求:

复制代码
GET user:1001

M1 检查发现:

  • key 的 slot(7000)不在自己负责范围(0~5460)。

  • 于是返回重定向响应:

    MOVED 7000 192.168.1.11:6379

客户端收到后:

  1. 更新 slot 表;

  2. 下次请求直接发往 M2。

这就是 Redis Cluster 的自动路由机制。


Step 5:集群节点之间的通信

每个节点之间通过 Gossip 协议 定期交换状态消息(默认每秒 10 次):

  • M1 向 M2、M3 发送 PING

  • M2 回复 PONG

  • 这些消息包含节点状态、槽分配、故障信息等。

目的:

  • 确保节点间状态同步;

  • 检测故障;

  • 传播集群配置变化。


Step 6:节点出现故障

假设主节点 M2 宕机。

  1. 其他节点检测到 M2 无响应,发出 PFAIL 标记;

  2. 多个节点达成共识 → 将其标记为 FAIL

  3. 其从节点 S2 发起选举,成为新的主节点;

  4. 集群广播消息更新:

    复制代码
    槽 5461~10922 现在由 192.168.1.14:6379 负责
  5. 客户端收到 MOVED 信息后更新路由:

    复制代码
    MOVED 7000 192.168.1.14:6379
  6. 客户端重新向 S2(新主)发送请求,服务恢复。

Redis Cluster 实现了自动故障转移,无需人工干预。


Step 7:节点恢复后重新加入

当 M2 修复重启后:

  1. 发送命令:

    复制代码
    CLUSTER MEET 192.168.1.14 6379
  2. 加入集群;

  3. 被设置为 S2 的从节点;

  4. 开始同步数据;

  5. 集群恢复到原有结构。


流程总结图(文字描述版)

复制代码
客户端 → 连接任意节点
        ↓
  获取槽分配信息(16384个slot)
        ↓
  根据 key 算 slot → 定位主节点
        ↓
  向对应节点发送命令(SET/GET等)
        ↓
  若访问错误 → MOVED/ASK 重定向
        ↓
  节点间Gossip通信保持一致
        ↓
  故障自动检测 + 从节点选举接管

总结

阶段 动作 说明
启动阶段 客户端获取 slot 分布表 从任意节点获取
写入阶段 客户端计算槽并路由 CRC16(key) % 16384
访问错误 节点返回 MOVED 或 ASK 客户端更新路由表
节点通信 Gossip 协议 保持节点状态一致
故障恢复 自动主从切换 无需人工干预

五、节点之间如何通信?

Redis Cluster 的节点之间使用 Gossip 协议 通信。

每个节点周期性地向其他节点发送消息,类型包括:

消息类型 作用
PING 探测节点是否在线
PONG PING 的响应
MEET 新节点加入集群
FAIL 节点被判定为失败
PUBLISH 集群广播消息(可用于 pub/sub)

通信特点:

  • 基于 TCP(默认端口号 + 10000,比如 Redis 端口是 6379,集群通信端口是 16379)。

  • 去中心化,每个节点都知道其他节点信息。

  • 通过定期 PING-PONG 交换来维护节点状态。


六、故障转移机制(Failover)

Redis Cluster 的高可用核心机制就是:主从复制 + 自动故障转移

故障检测

  1. 如果一个主节点被多数节点标记为"主观下线(PFAIL)";

  2. 多数节点达成一致后,会将其标记为"客观下线(FAIL)"。

故障转移步骤

  1. 该主节点的从节点(slave)会自动发起选举(failover)

  2. 被选中的从节点提升为新的主节点;

  3. 集群广播通知,更新槽分配信息;

  4. 客户端收到 MOVED 后自动重定向请求到新主节点。

整个过程几乎可以自动完成,客户端无需人工干预。


七、Redis Cluster 的特点与限制

优点:

  • 自动分片与负载均衡;

  • 高可用;

  • 无中心架构;

  • 客户端自动感知集群变化。

限制:

  • 不支持多键跨 slot 的事务(除非所有 key 落在同一 slot 上,可以使用 hash tag)。

  • 不支持 keys * 等全局命令。

  • 部署复杂度比单机更高。

相关推荐
间彧3 小时前
防盗链技术详解与SpringBoot实现方案
后端
ShooterJ3 小时前
Mysql小表驱动大表优化原理
数据库·后端·面试
程序员三明治3 小时前
【MyBatis从入门到入土】告别JDBC原始时代:零基础MyBatis极速上手指南
数据库·mysql·mybatis·jdbc·数据持久化·数据
ShooterJ3 小时前
MySQL基因分片设计方案详解
后端
PetterHillWater3 小时前
ANOVA在软件工程中的应用
后端
cxyxiaokui0013 小时前
还在用 @Autowired 字段注入?你可能正在写出“脆弱”的 Java 代码
java·后端·spring
回家路上绕了弯3 小时前
深入 Zookeeper 数据模型:树形 ZNode 结构的设计与实践
后端·zookeeper
cookqq3 小时前
MongoDB源码delete分析oplog:从删除链路到核心函数实现
数据结构·数据库·sql·mongodb·nosql
GeekAGI3 小时前
Redis 不同架构下的故障发现和自动切换机制
后端