Lecture11-Redis-集群

文章目录

    [toc]

    单词词性音标含义
    clustern./ˈklʌstə(r)/集群(多节点分布式系统,自动分片 + 高可用)
    slotn./slɒt/槽位(共 16384 个,key 哈希后映射到某个槽,由节点管理)
    shardn./v./ʃɑːd/分片(数据按槽分布到不同节点)
    redirectv./n./ˌriːˈdaɪrekt/重定向(客户端连到错误节点时,返回 MOVED 指向正确节点)
    gossipn./v./ˈɡɒsɪp/八卦(集群节点间 Gossip 协议传播状态)
    failovern./ˈfeɪlˌəʊvə(r)/故障转移(主节点挂,从节点自动升为主)
    nodesn./nəʊdz/节点(集群中的每个 Redis 实例)
    coveragen./ˈkʌvərɪdʒ/覆盖(All 16384 slots covered 表示槽分配完整、集群健康)

    Lecture11-Redis-集群

    目标:搭建 Redis Cluster,理解槽(slot)分片,让数据分布到多台机器、单点故障自动转移,并让 SpringBoot 4 连接集群。

    1、为什么需要集群

    单机内存有限、单点风险高。集群解决两个问题:

    • 水平扩容:数据分片到多台机器,突破单机内存上限。
    • 高可用:每个主节点配从节点,主挂从升,自动故障转移(自带,无需哨兵)。

    对比:主从+哨兵只解决高可用、不解决容量;集群既分片又高可用。

    集群结构中:

    • 组内是主从结构,会自动同步数据;(同构)
    • 组和组之间没有数据同步机制,数据是不一样的(异构)

    2、槽(slot)分片原理

    Redis 为了让集群中各个主节点保存的数据尽量均衡(充分利用每一个服务器实例的资源),引入槽的概念;

    Redis Cluster 把数据空间划分成 16384 个槽(slot),不管集群中主节点数量是多少,槽的个数都是固定的 16384。

    也就是说,16384 个槽其实是一个『逻辑概念』,Redis 会把 16384 个槽全部映射到集群中所有主节点上。

    每个 key 通过哈希映射到某个槽,槽再分配到各主节点:

    key → CRC16(key) % 16384 = slot → 该 slot 所属的节点
    
    • 3 个主节点,每个分管约 5461 个槽。
    • 写一个 key 时,如果 key 的槽不在当前节点,返回 MOVED 错误并告诉你正确节点,客户端自动重定向。
    • 集群模式下客户端用 -c 连接,自动跟随重定向。

    cluster-slot


    3、搭建 6 节点集群(3 主 3 从)

    1、准备目录与 6 个配置

    mkdir -p /usr/local/redis_cluster
    sudo chown -R $USER:$USER redis_cluster/
    cp /opt/redis-8.0.6/redis/redis.conf /usr/local/redis_cluster/
    

    以端口 1000~6000 建 6 个实例(每个配置端口、日志、数据文件不同,另加集群开关):

    # redis-cluster-1000.conf(其余改端口号即可)
    include /usr/local/redis_cluster/redis.conf
    port 1000
    bind 0.0.0.0
    protected-mode no
    daemonize yes
    pidfile redis1000.pid
    logfile redis1000.log
    dir /usr/local/redis_cluster
    dbfilename dump1000.rdb
    
    # 集群相关
    cluster-enabled yes
    cluster-config-file nodes-1000.conf
    cluster-node-timeout 15000
    appendonly yes
    

    用 cp 复制 6 份后逐份改端口,或用脚本循环生成。


    2、启动 6 个实例

    redis-server /usr/local/redis_cluster/redis-cluster-1000.conf
    # ... 2000 ~ 6000 同样启动
    

    启动后每个目录会生成 nodes-*.conf(记录节点 ID 和槽分配)。


    3、创建集群

    redis-cli --cluster create \
      192.168.100.100:1000 \
      192.168.100.100:2000 \
      192.168.100.100:3000 \
      192.168.100.100:4000 \
      192.168.100.100:5000 \
      192.168.100.100:6000 \
      --cluster-replicas 1
    
    • --cluster-replicas 1:每个主节点配 1 个从节点。
    • 输入 yes 确认后,集群把 16384 个槽分配给 3 个主节点,从节点自动分配。

    4、验证集群

    # 集群整体状态
    redis-cli -c -p 1000 cluster info
    # cluster_state:ok
    # cluster_slots_assigned:16384
    
    # 节点与槽分布
    redis-cli -c -p 1000 cluster nodes
    # 3 个 master 分别连接 0-5460 / 5461-10922 / 10923-16383
    # 3 个 slave 分别 replicates 对应 master
    
    # 健康检查
    redis-cli --cluster check 192.168.100.100:1000
    # [OK] All 16384 slots covered.
    

    5、测试读写与重定向

    # -c 集群模式,自动跟随 MOVED 重定向
    redis-cli -c -p 1000
    127.0.0.1:1000> set name tom
    OK                      # 槽不在 1000 时,-c 会自动转到正确节点
    127.0.0.1:1000> get name
    "tom"
    

    不用 -c 连接时,写错节点会报 MOVED 错误并提示正确节点。


    4、故障转移测试

    # 关掉一个主节点(比如 1000)
    redis-cli -p 1000 shutdown
    
    # 等待 cluster-node-timeout 后,其从节点自动升级为新主
    redis-cli -c -p 2000 cluster nodes
    # 原 1000 的从节点变成 master,接管 0-5460 槽
    

    集群自带故障转移,无需哨兵。客户端(-c / SpringBoot Lettuce)会自动感知拓扑变化。


    5、对接 SpringBoot 4

    spring:
      data:
        redis:
          cluster:
            nodes:
              - 192.168.100.100:1000
              - 192.168.100.100:2000
              - 192.168.100.100:3000
            max-redirects: 3      # 分片迁移时最大重定向次数
          lettuce:
            pool:
              enabled: true
              max-active: 16
              max-idle: 8
            cluster:
              refresh:
                enabled: true     # 定期刷新集群拓扑
                period: 60000ms
    
    @Autowired
    private StringRedisTemplate redis;
    
    @Test
    void clusterOps() {
        redis.opsForValue().set("cluster:key", "cluster:value");
        String v = redis.opsForValue().get("cluster:key");
    }
    

    代码与单机完全一样——RedisTemplate 自动适配集群,无需改业务代码。


    6、架构对比

    方案数据分片高可用复杂度适用
    单机无无低学习/小流量
    主从 + 哨兵无有中读写分离 + 高可用
    Redis Cluster有有高大数据量 + 高可用

    7、课堂练习

    1. 用脚本生成 6 个集群配置文件并启动 6 个实例。
    2. 用 redis-cli --cluster create ... --cluster-replicas 1 创建集群。
    3. 用 cluster info、cluster nodes、cluster check 验证集群,确认 16384 槽全覆盖。
    4. 关掉一个主节点,观察其从节点自动升为主;用 -c 连接写入数据验证可用。
    5. 用 SpringBoot 4 通过 spring.data.redis.cluster.nodes 连接集群读写。

    8、本节验证

    • 理解集群解决容量与高可用、16384 slot 分片原理 ✅
    • 会搭建 6 节点集群(3 主 3 从),验证槽覆盖完整 ✅
    • 会用 -c 集群模式连接,理解 MOVED 重定向 ✅
    • 理解集群故障转移与架构对比,能对接 SpringBoot4 ✅
    end