Skip to content

分布式缓存

1.1 当前单点结构的问题

  1. 数据存储问题:Redis基于内存存储,服务重启可能会丢失数据

  2. 并发能力问题:单节点Redis并发能力虽然不错,但也无法满足618这样的高并发场景

  3. 故障恢复问题(容灾):Redis宕机,则服务不可用

  4. 存储能力问题:Redis基于内存,单节点能存储的数据量难以满足海量数据需求

    image-20260423175319273

1.2 Redis 持久化

1.2.1 RDB(全量备份)

  1. RDB 全称 Redis Database Backup file(Redis 数据备份文件),也被叫做 Redis 数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当 Redis 实例故障重启后,从磁盘读取快照文件,恢复数据。快照文件称为 RDB 文件,默认是保存在当前运行目录。

  2. 两个命令

    • save :由Redis主进程来执行RDB,会阻塞所有命令,生产模式禁用。

    • bgsave :开启子线程执行RDB,避免主进程受到影响。

      Redis在停机时会执行一次RDB,但是Redis突然宕机(进程崩溃、断电、硬件故障等)是不会执行RDB的。

  3. 配置

    配置项示例值详细说明
    save <m> <n>save 300 10触发规则:在 $m$ 秒内如果有 $n$ 个键发生改变,则自动触发 BGSAVE。可以配置多条。
    dbfilenamedump.rdb文件名:指定生成的快照文件的名称。
    dir./存储目录:RDB 文件和 AOF 文件的存放路径。
    stop-writes-on-bgsave-erroryes容错机制:如果后台快照保存失败,Redis 是否停止接收写命令(默认开启,起到预警作用)。
    rdbcompressionyes压缩开关:采用 LZF 算法对 RDB 文件进行压缩。开启会节省磁盘空间,但会稍微增加 CPU 开销。
    rdbchecksumyes数据校验:在 RDB 文件末尾添加 CRC64 校验码。开启会增加约 10% 的性能损耗,但数据更安全。
    rdb-del-sync-filesno同步删除:在没有开启持久化的实例中,是否删除同步拉取的 RDB 文件(通常用于主从同步)。
  4. 运行时命令

    如果你不想重启 Redis,可以通过客户端(redis-cli)直接操作:

    • SAVE:前台阻塞式保存。在生产环境严禁使用,因为它会阻塞主线程,导致 Redis 无法处理其他请求。
    • BGSAVE:后台异步保存。Redis 会 fork 出一个子进程来处理快照,主线程继续响应请求。
    • LASTSAVE:返回最近一次成功执行快照的时间戳(Unix timestamp)。
    • CONFIG SET save "60 10000":动态修改保存规则,无需重启。
  5. 底层原理

    • 执行RDB 的bgsave的时候,主线程会执行 fork 操作,将页表(虚拟内存和内存的映射关系,Redis就是通过虚拟内存来操作内存的)共享给子进程,子进程会对目标内存进行读操作,写新RDB文件,替换掉旧的RDB文件,最终的RDB文件是主进程 fork 那一刻的数据。主进程的写操作不会影响到子进程。
    • 主进程在执行 bgsave 的时候,如果有用户==写==那部分只读数据,主进程会将那部分数据进行拷贝,之后的读写操作都在拷贝数据上进行,因此极端情况下,如果数据全部被拷贝一遍,Redis会占用原本的2倍内存,所以要预留一部分空间给Redis。

    image-20260423181540465

  6. 总结

    image-20260423183638529

1.2.2 AOF(增量备份)

  1. AOF 全称 Append Only File(追加文件)。与 RDB 不同,它不是记录数据快照,而是记录 Redis 接受到的每一个写命令。当 Redis 重启时,会通过重新执行这些命令来恢复数据,就像“重放”录像带一样。

  2. AOF 默认是关闭的,需要修改 redis.conf 配置文件来开启:

    • appendonly yes :开启 AOF 功能。
    • appendfilename "appendonly.aof" :指定 AOF 文件名。
  3. 三种写回策略(appendfsync 策略

    由于磁盘 IO 慢,Redis 写入命令时会先写入内存缓存区(OS Cache),何时刷入磁盘由以下配置决定:

    策略刷盘时机优点缺点
    Always每执行一个写命令立即同步刷盘数据安全性最高,几乎不丢失性能最差,受限于磁盘 IO 瓶颈
    Everysec每秒同步一次(默认)性能与安全折中,兼顾吞吐量宕机时可能丢失 1 秒左右的数据
    No由操作系统控制刷盘时机性能最高安全性最低,丢失数据量不可控
  4. AOF 重写(Optimization)

    随着命令越来越多,AOF 文件会变得非常臃肿(比如给同一个 key 执行了 100 次 INCR,AOF 会记录 100 条命令,但其实只需要记录 1 条 SET 结果)。

    • bgrewriteaof:Redis 会执行该命令异步重写 AOF,剔除冗余命令,减小文件体积。
    • 自动重写配置
      • auto-aof-rewrite-percentage 100:对比上次重写后的体积,增长 100% 时触发。
      • auto-aof-rewrite-min-size 64mb:文件体积至少达到 64MB 才触发。
  5. 底层原理

    AOF 的工作流程主要分为四个步骤:命令追加 (Append)、文件写入 (Write)、文件同步 (Sync)、文件重写 (Rewrite)

    1. 命令追加:主线程在执行写命令后,将命令以 Redis 通讯协议 (RESP) 格式追加到 aof_buf 缓冲区。
    2. 异步刷盘:根据 appendfsync 的策略,由后台线程或操作系统将缓冲区内容写入磁盘。
    3. 重写机制 (Rewriting)
      • 主进程 fork 出一个子进程。
      • 子进程读取内存中的当前最新数据(不是读取旧 AOF 文件),将其转换为最简便的命令写入临时文件。
      • 一致性保证:在重写期间,主进程的新命令会同时写入 aof_bufaof_rewrite_buf(重写缓冲区)。
      • 替换:子进程写完新 AOF 后,主进程将重写缓冲区的内容追加到新文件,最后原子替换旧 AOF。

1.2.3 RDB 和 AOF 的优缺点

image-20260423194059124

1.3 Redis 主从

1.3.1 搭建主从结构

  1. 主从架构基本结构

    image-20260424085255087

    即搭建多个节点,由于Redis使用中大多是读多写少的场景,所以我们选择读写分离的策略,由主节点负责写操作,从节点负责读操作,再有主节点数据同步给从节点。

    架构的要在于如何进行集群的配置以及如何进行数据同步,以及之后的容灾(可用性),容灾之后我们会使用哨兵。、

  2. Redis集群搭建

    参考:Redis集群

    开启主从模式,有临时和永久两种模式:

    • 修改配置文件(永久生效)

      • 在redis.conf中添加一行配置:slaveof <masterip> <masterport>
    • 使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效):

      shell
      slaveof <masterip> <masterport>
    • INFO replication :查看集群信息
  3. 使用Docker搭建Redis集群

    • 编写配置文件(配置文件的位置要和docker-compose.yml 文件中挂载卷的位置保持一致)

      • master:

        yml
        # 允许所有 IP 连接
        bind 0.0.0.0
        # 端口(容器内固定为 6379)
        port 6379
        # 关闭保护模式
        protected-mode no
        # 开启 AOF 持久化(建议开启,保证数据安全)
        appendonly yes
        # 主节点密码(如果需要安全,建议设置)
        requirepass 123456
        # 从节点连接主节点所需的密码(主从密码建议设为一致)
        masterauth 123456
      • slave:

        yml
        bind 0.0.0.0
        port 6379
        protected-mode no
        appendonly yes
        requirepass 123456
        masterauth 123456
        
        # 【核心:指明主节点是谁】
        # 使用 docker-compose 时,可以直接写服务名 redis-master
        replicaof redis-master 6379
        
        # 【核心:声明 IP 和端口】
        # 告诉主节点,我的宿主机 IP 是这个
        replica-announce-ip 192.168.134.128
        # 告诉主节点,我在宿主机映射的端口是 7002(slave2 改为 7003)
        replica-announce-port 7002
    • 编写 docker-compose.yml

      yml
      services:
        master:
          image: redis:6.2.6
          container_name: redis-master
          volumes:
            - ./conf/master/redis.conf:/etc/redis/redis.conf
            - ./data/master:/data
          command: redis-server /etc/redis/redis.conf
          ports:
            - "7001:6379"
          networks:
            redis-net:
              ipv4_address: 172.20.0.10
      
        slave1:
          image: redis:6.2.6
          container_name: redis-slave1
          depends_on:
            - master
          volumes:
            - ./conf/slave1/redis.conf:/etc/redis/redis.conf
            - ./data/slave1:/data
          command: redis-server /etc/redis/redis.conf
          ports:
            - "7002:6379"
          networks:
            redis-net:
              ipv4_address: 172.20.0.11
      
        slave2:
          image: redis:6.2.6
          container_name: redis-slave2
          depends_on:
            - master
          volumes:
            - ./conf/slave2/redis.conf:/etc/redis/redis.conf
            - ./data/slave2:/data
          command: redis-server /etc/redis/redis.conf
          ports:
            - "7003:6379"
          networks:
            redis-net:
              ipv4_address: 172.20.0.12
      
      networks:
        redis-net:
          driver: bridge
          ipam:
            config:
              - subnet: 172.20.0.0/16

1.3.2 主从数据同步原理

1.3.2.1 全量同步

  1. 主从第一次同步是全量同步:

    image-20260424122039066

  2. Master 如何判断 slave 是不是第一次来同步数据?这里有两个概念:

    • Replication ld: 简称 replid, 是数据集的标记, id 一致则说明是同一数据集。每一个 master 都有唯一的 replid,slave 则会继承 master 节点的 replid

    • offset :偏移量,随着记录在 repl_baklog 中的数据增多而逐渐增大。 slave 完成同步时也会记录当前同步的 offset 。如果 slave 的 offset 小于 master 的 offset, 说明 slave 数据落后于 master, 需要更新。

      因此salve做数据同步,必须向master 声明自己的 replication id 和 offset, master 才可以判断到底需要同步哪些数据。

      所以master通过判断slave节点的 replication Id 是否和自己一致来判断 slave 节点是不是第一次来做数据同步。

      image-20260424122822704

  3. 总结,全量同步的流程:

    • 从节点向主节点发送增量同步请求
    • 主节点判断从节点的 replication ID 是否和自己的一致,判断是否是第一次同步
    • 如果是第一次同步,主节点执行 bgsave ,把 RDB 文件发送给从节点
    • 从节点清理掉本地数据,加载RDB文件
    • 主节点将执行bgsave期间完成的写操作命令记录在repl_baklog中,发送给从节点
    • 从节点执行这些命令,保持与 master 之间的同步

1.3.2.2 增量同步

  1. 增量同步过程

    image-20260424124414409

    • 主节点会判断 replication id 是否和自己的一样,如果一样,则根据 offset 进行增量同步。
    • repl_baklog 底层是实现是数组,master 和 slave 都有一个 offset,repl_baklog 大小有上限,写满后会覆盖最早的数据。进行增量同步时,主节点会判断当前自己的 offset 是否大于 slave 的offset,如果小于等于,则将 slave offset之后的命令发给 slave;如果大于,则进行全量同步。
  2. 可以从以下几个方面优化Redis主从集群:

    • 优化全量同步

      • 在 master 中配置 rep-diskless-sync yes 启用无磁盘复制,此时RDB文件就不会写入磁盘中,直接通过网络流发送给从节点,减少了磁盘IO时间。使用场景:磁盘IO比较慢,但是网络带宽比较快。

      • Redis单节点所占用内存不要过大,减少RDB导致的过多磁盘IO

    • 减少全量同步

      • 适当提高repl_baklog的大小(允许主从节点更大的数据差异),以及发现slave宕机时,尽快实现故障恢复(减少主从节点的数据差异),尽可能避免全量同步

      • 限制一个 master 上的 slave 节点数量,如果实在是太多 slave ,则可以采用主一从一从链式结构,减少 master 压力,实现这种架构,只需要后面的从节点指定前面的从节点为主节点即可

        image-20260424125730428

1.3.2.3 全量同步与增量同步的总结

  1. 简述全量同步和增量同步区别?

    • 全量同步:master 将完整内存数据生成 RDB, 发送 RDB 到 slave。后续命令则记录在 repl_baklog ,逐个发送给 slave。

    • 增量同步:slave 提交自己的 offset 到 master, master 获取repl-baklog 中从 offset 之后的命令给 slave。

  2. 什么时候执行全量同步?

    • slave 节点第一次连接 master 节点时

    • slave 节点断开时间太久,repl-baklog 中的 offset 已经被覆盖时

  3. 什么时候执行增量同步?

    • slave 节点断开又恢复,并且在 repl_baklog 中能找到 offset 时

1.4 Redis 哨兵

1.4.1 问题

slave节点宕机回复后可以找master节点同步数据,但是master节点宕机后,这期间的写操作就丢失了。

Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。

1.4.2 哨兵的作用和原理

  1. 哨兵的结构如下:

    image-20260424155930104

    由哨兵集群监控Redis主从节点的状态,在Redis主节点出现故障后,自动选举新节点为主节点,并将状态的变化通知给客户端(使用者)

  2. 哨兵的作用:

    • ==监控==:SentineI 会不断检查您的 master 和 slave是否按预期工作
    • ==自动故障恢复==:如果 master 故障, Sentinel 会将一个 slave 提升为 master。当故障实例恢复后也以新的 master 为主
    • ==通知==,Sentinel 充当 Redis 客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给 Redis 的客户端
  3. 哨兵==如何监控节点的服务状态==呢?

    sentinel 基于心跳机制监测服务状态,每隔 1 秒向集群的每个实例发送 ping 命令

    • 主观下线:如果某 sentinel 节点发现某实例未在规定时间响应,则认为该实例主观下线。
    • 客观下线:若超过指定数量 (quorum) 的 sentinel 都认为该实例主观下线,则该实例客观下线。quorum 值最好超过 sentinel 实例数量的一半。
  4. 哨兵(sentinel)==以什么为依据选择新的 master== 呢?

    一旦发现 master 故障,sentinel 需要在 salve 中选择一个作为新的 master, 选择依据是这样的:

    • 首先会判断 slave 节点与 master 节点断开时间长短,如果超过指定值 (down-after-milliseconds *10 )则会排除该slave 节点
    • 然后判断 slave 节点的 slave-priority 值,越小优先级越高,如果是 0 则永不参与选举
    • 如果 slave-prority 一样,则判断 slave 节点的 offset 值,越大说明数据越新,优先级越高
    • 最后是判断 slave 节点的运行 id 大小,越小优先级越高。

    即选择的大体原则是:选择数据最新的slave节点作为主节点,优先保证数据的一致性。

  5. 如何实现==故障转移==?

    当选中了其中一个 slave 为新的 master 后(例如 slave1),故障的转移的步骤如下:

    • sentinel 给备选的 slave1 节点发送 slaveof no one 命令,让该节点成为 master。
    • sentinel 给所有其它 slave 发送 slaveof 192.168.134.128 7002命令,让这些 slave 成为新 master 的从节点,开始从新的 master上同步数据。
    • 最后,sentinel 将故障节点标记为 slave(修改该节点的配置文件), 当故障节点恢复后会自动成为新的 master 的 slave 节点。

    image-20260424161709047

1.4.3 搭建哨兵集群

参考:Redis集群

1.4.4 RedisTemplate的哨兵模式

  1. 配置哨兵

    java
    spring:
      redis:
        # 哨兵模式配置
        sentinel:
          master: mymaster          # 对应哨兵配置文件中的 master 名称
          nodes: 
            - 192.168.134.128:26379 # 哨兵1号的IP和端口
            - 192.168.134.128:26380 # 哨兵2号
            - 192.168.134.128:26381 # 哨兵3号
        password: yourpassword     # 如果设置了密码,主从和哨兵通常共用一个
        database: 0
        lettuce:                   # SpringBoot 2.x 默认使用 Lettuce 驱动
          pool:
            max-active: 8
            max-wait: -1ms
  2. 配置读写分离

    java
    @Bean
    public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {
        // REPLICA_PREFERRED: 优先从从节点读,如果从节点挂了再读主节点
        return builder -> builder.readFrom(ReadFrom.REPLICA_PREFERRED);
    }

    这里的 ReadFrom 是配置 Redis 的读取策略, 是一个枚举,包括下面选择:

    • MASTER :从主节点读取
    • MASTER_PREFERRED: 优先从 master 节点读取, master 不可用才读取 replica
    • REPLICA : 从 slave (replica) 节点读取
    • REPLICA_REPLICA:优先从 slave (replica) 节点读取,所有的 slave 都不可用才读取 master

1.5 Redis分片集群

1.5.1 概念

  1. 分片集群(Cluster) 可以看作是 主从复制 + 哨兵(Sentinel) 的高级进化版。

  2. 分片集群解决数据量大的问题,传统的主从复制 + 哨兵的模式在数据量不断增大时,主节点的容量成为了瓶颈。分片集群通过插槽机制,将所有的数据分片存储到不同 Master 节点中,访问时,路由到指定节点。

  3. 为什么分片集群不需要额外的哨兵?

    在“主从+哨兵”模式下,哨兵是一个独立的第三方代理,负责监控和拨乱反正。但在 分片集群(Redis Cluster) 中,这些功能被集成到了每一个数据节点中:

    1. 节点互监(去中心化监控):集群中的每个节点都通过 Gossip 协议 互相交换信息。它们不再需要专门的哨兵来告诉自己“谁挂了”,节点之间会互相检测对方的心跳。
    2. 自动故障转移:如果一个 Master 挂了,集群中其他的 Master 会共同投票,从挂掉节点的 Slave 中选出一个新的 Master。这套选举逻辑和哨兵非常相似,只是执行者变成了 Master 节点本身。
    3. 配置中心功能:哨兵模式下,客户端通过哨兵获取 Master 地址;而在分片集群中,客户端可以连接任意节点,如果数据不在该节点,它会返回一个 MOVED 错误告诉客户端正确的去向。
  4. 客户端访问分片集群的流程

    当一个客户端(比如你的 Spring Boot 应用)想要读写一个 Key 时,流程如下:

    • 第一步:计算槽位 (Key -> Slot):客户端先对自己要操作的 Key 进行 CRC16 循环冗余校验,然后对 16384 取模,算出这个 Key 属于哪一个槽位。slot = CRC16(key) \pmod{16384}$$

    • 第二步:查找节点 (Slot -> Node):客户端查看本地缓存的“映射表”,寻找这个槽位对应的节点 IP 和端口。

    • 第三步:发送请求:客户端向目标节点发送请求。

    • 第四步:节点判断与响应 (核心环节)

      当节点收到请求后,它会先检查这个 Key 所属的槽位是否由自己负责:

      • 如果在自己这里:直接执行命令,返回结果。
      • 如果不在自己这里
        • 节点会查询自己内部记录的集群状态,找到真正负责该槽位的节点信息。
        • 节点给客户端回一个特殊的错误响应:MOVED [slot] [target_ip:port]
    • 第五步:客户端重定向

      客户端收到 MOVED 错误后,意识到自己本地的“映射表”过时了。它会做两件事:

      • 更新本地缓存:把该槽位与新节点的对应关系记下来。
      • 重新发送:向 MOVED 指向的新地址重新发送请求。
  5. 分片集群的代价

    • 多 Key 操作受限 (Multi-key Operations)

      这是开发中最头疼的地方。Redis 要求所有参与操作的 Key 必须在同一个哈希槽(Slot)中。

      • 事务与批处理:如果你想用 MSET 同时设置多个 Key,或者在 MULTI/EXEC 事务中操作多个 Key,如果这些 Key 被分配到了不同节点,操作会直接报错。
      • Lua 脚本:同样,Lua 脚本中涉及的所有 Key 也必须在同一个节点上。

      解决方案: 使用 Hash Tag。例如设置 Key 为 {user:100}info{user:100}order,Redis 只会对 {} 里的内容哈希,确保它们落到同一个节点。

    • 如果客户端访问的 Key 不在当前连接的节点上,Redis 会返回 MOVEDASK 错误。客户端必须能够解析这些错误,并自动重定向到正确的节点。

参考:Redis分片集群

1.5.2 散列插槽

1.5.2.1.插槽原理

Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到:

image-20210725155820320

数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:

  • key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分
  • key中不包含“{}”,整个key都是有效部分

例如:key是num,那么就根据num计算,如果是{itcast}num,则根据itcast计算。计算方式是利用CRC16算法得到一个hash值,然后对16384取余,得到的结果就是slot值。

image-20210725155850200

如图,在7001这个节点执行set a 1时,对a做hash运算,对16384取余,得到的结果是15495,因此要存储到103节点。

到了7003后,执行get num时,对num做hash运算,对16384取余,得到的结果是2765,因此需要切换到7001节点

1.5.2.1.小结

Redis如何判断某个key应该在哪个实例?

  • 将16384个插槽分配到不同的实例
  • 根据key的有效部分计算哈希值,对16384取余
  • 余数作为插槽,寻找插槽所在实例即可

如何将同一类数据固定的保存在同一个Redis实例?

  • 这一类数据使用相同的有效部分,例如key都以{typeId}为前缀

1.5.3 集群伸缩

redis-cli --cluster提供了很多操作集群的命令,可以通过下面方式查看:

image-20210725160138290

比如,添加节点的命令:

image-20210725160448139

1.5.3.1.需求分析

需求:向集群中添加一个新的master节点,并向其中存储 num = 10

  • 启动一个新的redis实例,端口为7004
  • 添加7004到之前的集群,并作为一个master节点
  • 给7004节点分配插槽,使得num这个key可以存储到7004实例

这里需要两个新的功能:

  • 添加一个节点到集群中
  • 将部分插槽分配到新插槽

1.5.3.2创建新的redis实例

创建一个文件夹:

sh
mkdir 7004

拷贝配置文件:

sh
cp redis.conf /7004

修改配置文件:

sh
sed /s/6379/7004/g 7004/redis.conf

启动

sh
redis-server 7004/redis.conf

1.5.3.3.添加新节点到redis

添加节点的语法如下:

image-20210725160448139

执行命令:

sh
redis-cli --cluster add-node  192.168.134.128:7004 192.168.134.128:7001

通过命令查看集群状态:

sh
redis-cli -p 7001 cluster nodes

如图,7004加入了集群,并且默认是一个master节点:

image-20210725161007099

但是,可以看到7004节点的插槽数量为0,因此没有任何数据可以存储到7004上

1.5.3.4.转移插槽

我们要将num存储到7004节点,因此需要先看看num的插槽是多少:

image-20210725161241793

如上图所示,num的插槽为2765.

我们可以将0~3000的插槽从7001转移到7004,命令格式如下:

image-20210725161401925

具体命令如下:

建立连接:

image-20210725161506241

得到下面的反馈:

image-20210725161540841

询问要移动多少个插槽,我们计划是3000个:

新的问题来了:

image-20210725161637152

那个node来接收这些插槽??

显然是7004,那么7004节点的id是多少呢?

image-20210725161731738

复制这个id,然后拷贝到刚才的控制台后:

image-20210725161817642

这里询问,你的插槽是从哪里移动过来的?

  • all:代表全部,也就是三个节点各转移一部分
  • 具体的id:目标节点的id
  • done:没有了

这里我们要从7001获取,因此填写7001的id:

image-20210725162030478

填完后,点击done,这样插槽转移就准备好了:

image-20210725162101228

确认要转移吗?输入yes:

然后,通过命令查看结果:

image-20210725162145497

可以看到:

image-20210725162224058

目的达成。

1.5.4 故障转移

集群初识状态是这样的:

image-20210727161152065

其中7001、7002、7003都是master,我们计划让7002宕机。

1.5.4.1.自动故障转移

当集群中有一个master宕机会发生什么呢?

直接停止一个redis实例,例如7002:

sh
redis-cli -p 7002 shutdown

1)首先是该实例与其它实例失去连接

2)然后是疑似宕机:

image-20210725162319490

3)最后是确定下线,自动提升一个slave为新的master:

image-20210725162408979

4)当7002再次启动,就会变为一个slave节点了:

image-20210727160803386

1.5.4.2.手动故障转移

利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。其流程如下:

image-20210725162441407

这种failover命令可以指定三种模式:

  • 缺省:默认的流程,如图1~6歩
  • force:省略了对offset的一致性校验
  • takeover:直接执行第5歩,忽略数据一致性、忽略master状态和其它master的意见

案例需求:在7002这个slave节点执行手动故障转移,重新夺回master地位

步骤如下:

1)利用redis-cli连接7002这个节点

2)执行cluster failover命令

如图:

image-20210727160037766

效果:

image-20210727161152065

1.5.5 RedisTemplate访问分片集群

RedisTemplate底层同样基于lettuce实现了分片集群的支持,而使用的步骤与哨兵模式基本一致:

1)引入redis的starter依赖

2)配置分片集群地址

3)配置读写分离

与哨兵模式相比,其中只有分片集群的配置方式略有差异,如下:

yaml
spring:
  redis:
    cluster:
      nodes:
        - 192.168.134.128:7001
        - 192.168.134.128:7002
        - 192.168.134.128:7003
        - 192.168.134.128:8001
        - 192.168.134.128:8002
        - 192.168.134.128:8003