Redis 主从、哨兵与集群模式详解

Redis 是一个高性能的键值存储系统,广泛应用于缓存、消息队列等场景。为了提高 Redis 的可用性扩展性,Redis 提供了三种主要的高可用方案:主从模式哨兵模式集群模式。本文将详细介绍这三种模式的工作原理、配置方法和适用场景。

1. Redis 主从模式(Master-Slave)

1.1 原理介绍

主从模式是 Redis 最基础的高可用方案,通过读写分离数据备份提高系统的可用性和读取吞吐量。

核心特点:

  • 读写分离:主节点(Master)处理写请求,从节点(Slave)处理读请求
  • 数据备份:从节点实时同步主节点数据,实现数据冗余
  • 一主多从:一个主节点可以配置多个从节点

1.2 主从复制实现机制

复制ID和偏移量

  • replication ID:主库的 replication ID 就是自身 runid,是Redis服务启动时自动生成的40位随机字符串;从库只负责记录并保存主库的 replication ID,自身 runid 不参与主从同步协商
  • 复制偏移量(offset):主库每执行一个写命令,会将命令追加到复制积压缓冲区,同时复制偏移量(offset)递增;从库同步执行完写命令后,也会更新自己的复制偏移量,用于标识已同步的数据位置
  • 从库连接携带信息:从库建立或重连主库时,会携带已记录的主库 replication ID自身已同步的复制偏移量 offset;主库通过比对 replication ID 是否匹配offset 是否在复制积压缓冲区范围内,判断执行全量同步还是增量同步

SYNC vs PSYNC

命令 说明
SYNC 全量同步,无论从节点之前是否同步过,每次都会重新生成 RDB 快照并传输全部数据(Redis 2.8 之前的旧机制)
PSYNC 支持部分重同步,通过复制偏移量和备份 ID 判断,仅传输断线期间的增量数据(Redis 2.8+ 默认方式)

全量同步(同步)

  1. 从服务器向主服务器发送 PSYNC 命令,请求同步数据
  2. 主服务器收到命令后,执行 BGSAVE 命令,在后台生成 RDB 文件
  3. 主服务器将 RDB 文件发送给从服务器,同时将新的写命令缓存在内存中
  4. 从服务器接收到 RDB 文件后,清空自己的数据库,然后加载 RDB 文件到内存中
  5. 主服务器将缓存的写命令发送给从服务器,从服务器执行这些命令,保证数据一致性

注意:在全量同步阶段,从服务器会等待主服务器发送 RDB 文件和缓存的写命令,这个过程是同步的,从服务器在加载 RDB 文件和执行缓存命令时,无法处理客户端的请求。

触发全量同步的场景:

  • 从服务器首次连接主服务器:必须进行全量同步以获取完整的数据副本
  • 主从复制中断时间过长:当断开时间超过 repl-backlog-size 缓冲区容量时,触发全量同步
  • 主服务器重启:主服务器重启后自身 runid(复制ID) 变更,从库重连时携带旧的主库复制ID,主库无法匹配识别,触发全量同步

注意:从服务器重启仅自身 runid 变化,不影响复制协商,只要主库复制ID未变偏移量仍在复制积压缓冲区范围内,依旧可以走增量同步,不会触发全量同步

增量同步(异步)

全量同步完成后,主从关系建立,从节点不再发送 PSYNC 命令。增量同步阶段,主节点主动持续推送写命令给从节点,从节点不主动请求数据。

复制积压缓冲区特点:

  • 主库统一管理:主库维护一个复制积压缓冲区所有从库共享该缓冲区
  • 大小可调整:通过 repl-backlog-size 参数配置,默认 1MB,建议根据主库写命令频率和从库处理能力调整
  • 环形缓冲区:采用环形设计,缓冲区满后新数据覆盖最旧数据
  • 增量同步条件:只有当从节点的偏移量仍在缓冲区范围内,才能增量同步;若偏移量被覆盖,主库直接推送缓冲区中的后续命令,从库会跳过丢失的命令,导致数据丢失但最终与主库保持当前数据一致

重要提醒正常连接时也可能发生丢数据,不只是断开重连才丢。当从库处理速度较慢(如网络延迟、从库负载高等),即使连接正常,从库上报的 offset 也可能被新命令覆盖,导致丢段但不触发全量,主从最终一致但历史操作丢失,只有下次全量复制时才会补充。因此平时要合理设置 repl-backlog-size,避免正常复制过程中因缓冲区过小导致数据丢失。

触发增量同步的场景:

  • 全量同步结束后自动进入无需额外协商
  • 主从复制正常运行期间,主服务器持续将写命令同步给从服务器
  • 主从连接短暂中断后恢复,且中断期间的数据变更仍在 repl-backlog 缓冲区

心跳检测

全量同步完成后,从节点通过心跳机制与主节点保持连接:

心跳消息:

  • 从节点发送 PING默认每秒一次),携带自身当前的复制偏移量
  • 主节点响应 PONG,仅表示连接正常,不携带偏移量信息

重要结论:

  • 偏移量单向传递:只有从 → 主,主节点不会反向发送自己的偏移量给从节点
  • 心跳是同步的依据:主库在正常运行时会主动推送新命令,但推送的前提和依据,完全来自从库每秒心跳上报的偏移量;没有心跳,主库既不知道推到哪,也不知道从库缺了啥
  • 主节点判断并推送:主节点根据从节点汇报的偏移量,自行判断从节点缺了哪些命令,然后主动推送过去,从节点不请求数据

增量同步流程:

主节点执行写命令
        ↓
命令追加到 repl-backlog 缓冲区
        ↓
主节点根据从节点汇报的 偏移量 判断缺失数据
        ↓
主节点 主动推送 缺失的命令给从节点
        ↓
从节点接收并执行命令,更新偏移量

注意PSYNC 命令只在建立复制关系或重连时发送一次,由主节点根据 replication IDoffset 决定是全量同步还是增量同步全量同步结束后自动进入增量同步阶段无需额外协商

1.3 配置示例

主节点配置

# 监听端口
port 6379

# 设置密码认证
requirepass your_master_password

# 连接主节点时的密码(用于主从复制)
masterauth your_master_password

# 允许所有IP连接(生产环境建议指定具体IP)
bind 0.0.0.0

# 后台运行
daemonize yes

从节点配置

# 监听端口
port 6380

# 指定主节点地址和端口(主从复制配置,Redis 5.0+ 推荐使用 replicaof)
replicaof 127.0.0.1 6379

# 连接主节点时使用的密码
masterauth your_master_password

# 从节点密码
requirepass your_slave_password

# 允许所有IP连接
bind 0.0.0.0

# 后台运行
daemonize yes

1.4 Spring Boot 配置

配置方式:手动写死主节点和从节点地址
读写控制:客户端代码自己控制写主、读从

spring:
  redis:
    password: your_master_password
    database: 0
    master:
      host: 127.0.0.1
      port: 6379
    slaves:
      hosts: 127.0.0.1:6380,127.0.0.1:6381  # 多从节点
@Configuration
public class RedisConfig {

    @Value("${spring.redis.master.host}")
    private String masterHost;

    @Value("${spring.redis.master.port}")
    private int masterPort;

    @Value("${spring.redis.slaves.hosts}")
    private String slaves;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.database}")
    private int database;

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        // 主节点
        RedisStandaloneConfiguration master = new RedisStandaloneConfiguration(masterHost, masterPort);
        master.setPassword(password);
        master.setDatabase(database);

        // 从节点列表
        List<RedisStandaloneConfiguration> slavesList = Arrays.stream(slaves.split(","))
                .map(s -> {
                    String[] hp = s.split(":");
                    RedisStandaloneConfiguration c = new RedisStandaloneConfiguration(hp[0], Integer.parseInt(hp[1]));
                    c.setPassword(password);
                    c.setDatabase(database);
                    return c;
                }).toList();

        // 关键:创建主从拓扑
        MasterSlaveConnectionFactory factory = new MasterSlaveConnectionFactory(master, slavesList);
        factory.setReadFrom(ReadFrom.REPLICA_PREFERRED); // 现在才真正生效!
        return factory;
    }
}

1.5 主从模式优缺点

优点 缺点
配置简单,易于上手 主节点是单点,故障后需要人工干预(重启主节点/将从节点升级为主节点等等)
实现读写分离,提高读取吞吐量 主从同步时数据可能短暂不一致
数据冗余,提高数据安全性 无法自动实现故障转移
适合数据量小的场景 垂直扩展受单机硬件限制

2. Redis 哨兵模式(Sentinel Mode)

2.1 原理介绍

哨兵模式是基于主从模式的高可用方案,通过部署多个哨兵(Sentinel)进程来监控主从节点的运行状态,并在主节点故障时自动完成故障转移

核心功能:

  • 监控(Monitoring):Sentinel 持续检查主服务器和从服务器是否正常运行
  • 通知(Notification):当被监控的 Redis 实例出现问题时,Sentinel 通过 API 向管理员发送通知
  • 自动故障转移(Automatic Failover):当主服务器不能正常工作时,Sentinel 自动将一个从服务器升级为新的主服务器,并让其他从服务器开始复制新的主服务器
  • 配置提供者(Configuration Provider):客户端连接 Sentinel 获取当前 Redis 主节点的地址

哨兵模式本质上是一个运行在特殊模式下的 Redis 进程,用于监控主从结构中的各个实例。通常建议至少部署 3 个哨兵实例以确保高可用性。

2.2 哨兵模式工作原理

  1. 主节点监控:哨兵节点通过配置文件指定要监控的主节点,自动发现关联的从节点
  2. 哨兵互相发现:哨兵彼此不靠配置,靠主库上的 Pub/Sub 频道(__sentinel__:hello)互相发现,通过定期发布消息来感知其他哨兵的存在
  3. 多哨兵协作:多个哨兵节点协同工作,通过投票机制判断主节点是否失效
  4. 故障检测:当主节点在指定时间内没有回复 PING,则认为它主观下线,达到 quorum 配置值的多个哨兵确认后认定为客观下线
  5. 故障转移:从剩余的从节点中选举一个新的主节点,并更新其他从节点的复制目标

2.3 故障转移详解

主观下线(SDown)
    ↓
多个哨兵确认(达到 quorum)
    ↓
客观下线(ODown)
    ↓
哨兵投票选举leader
    ↓
选举从节点成为新主节点
    ↓
更新从节点复制目标
    ↓
旧主节点降级为从节点

故障转移过程:

  1. 当主节点被认定为客观下线后,所有监视该主节点的哨兵进行投票
  2. 被选为 leader 的哨兵负责执行故障转移
  3. 从所有从节点中选举一个成为新的主节点(选举规则:优先级 > 偏移量 > runid
  4. leader 哨兵让其他从节点去复制新的主节点
  5. 哨兵自动将恢复的原主节点降级为从节点,使其追随新选举的主节点

2.4 配置示例

主节点配置

port 6379
requirepass your_master_password
masterauth your_master_password
bind 0.0.0.0
daemonize yes

从节点配置

port 6380
slaveof 127.0.0.1 6379
masterauth your_master_password
requirepass your_slave_password
bind 0.0.0.0
daemonize yes

哨兵配置

# 哨兵监听端口
port 26379

# 监控的主节点名称、IP、端口和法定人数
# 格式:sentinel monitor <mastername> <ip> <port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2

# 主节点密码认证
sentinel auth-pass mymaster your_master_password

# 判断主节点主观下线的毫秒数
sentinel down-after-milliseconds mymaster 5000

# 故障转移时,同时进行复制的从节点数量
sentinel parallel-syncs mymaster 1

# 故障转移超时时间(毫秒)
sentinel failover-timeout mymaster 10000

# 允许所有IP连接
bind 0.0.0.0

# 后台运行
daemonize yes

2.5 Spring Boot 配置

配置方式:只写2~3个哨兵种子节点
读写控制:客户端问哨兵拿主节点写主;自动发现所有从节点读从

spring:
  redis:
    # 哨兵模式配置
    sentinel:
      # 主节点名称
      master: mymaster
      # 哨兵节点列表
      nodes:
        - 127.0.0.1:26379
        - 127.0.0.1:26380
        - 127.0.0.1:26381
    # Redis密码
    password: your_master_password
    # 连接超时时间
    timeout: 2000ms
    # 数据库索引(默认0)
    database: 0
    # Lettuce配置(读写分离)
    lettuce:
      client-options:
        read-from: REPLICA_PREFERRED # 优先从从节点读

2.6 哨兵模式优缺点

优点 缺点
自动故障转移,无需人工干预 不支持数据分片,所有数据存储在主节点
客户端无需知道主节点地址,通过哨兵获取 故障转移期间可能出现短时不可用
每个哨兵节点都可以提供故障转移能力 仍然基于主从复制,数据同步存在延迟
适合数据量不大但需要高可用的场景 最小需要 5 个节点(1主1从+3哨兵)

3. Redis 集群模式(Cluster Mode)

3.1 原理介绍

集群模式是 Redis 的分布式解决方案,通过数据分片高可用机制实现水平扩展和故障转移。

核心特点:

  • 数据分片:数据自动分片到多个节点上,每个节点负责一部分哈希槽(hash slot)
  • 高可用性:每个主节点可以有多个从节点,实现主从复制和自动故障转移
  • 去中心化:集群中的每个节点都保存着整个集群的状态信息,没有中心节点
  • 客户端路由:客户端可以连接任意节点,节点会将请求重定向到正确的节点

3.2 为什么集群模式不需要哨兵

Redis Cluster 与哨兵模式相比,具有以下关键差异,因此不需要额外的哨兵组件

  1. 内置高可用性

    • Redis Cluster 本身已经内置了故障检测自动故障转移机制
    • 每个节点都参与集群状态的维护和故障检测
    • 不需要外部组件来监控节点状态
  2. 去中心化架构

    • 集群中的每个节点都保存完整的集群状态信息
    • 节点之间通过 Gossip 协议交换状态信息
    • 没有单点故障问题
  3. 自动主从管理

    • 集群在创建时就配置了主从关系
    • 当主节点失效时,相关从节点会自动进行故障转移
    • 整个过程由集群内部协议处理,无需外部干预
  4. 分布式决策

    • 故障检测和主从切换由集群内多数节点共同决定
    • 避免了哨兵模式中可能出现的网络分区问题

故障转移机制详解

Redis Cluster 的故障转移流程如下:

主观下线(PFAIL)
    ↓
超过半数主节点确认
    ↓
客观下线(FAIL)
    ↓
从节点发起选举
    ↓
主节点投票
    ↓
获得超过半数票的从节点成为新主节点
阶段 发起者 参与者 说明
主观下线(PFAIL) 任何节点(主/从) - 节点通过 PING 检测到某节点超时未响应,标记为 PFAIL(Possible Fail)
客观下线(FAIL) 发现 PFAIL 的节点 主节点投票 超过半数主节点认为某主节点下线时,将其标记为 FAIL
选举发起 从节点 - 从节点发现主节点被标记为 FAIL 后,发起选举请求
投票选举 - 主节点投票 主节点投票,获得超过半数票的从节点成为新的主节点

关键点:

  • 所有节点都参与集群状态维护和故障检测(通过 Gossip 协议交换状态)
  • 主观下线:任何节点都可以标记
  • 客观下线:只有主节点有投票权
  • 选举发起从节点发起选举请求
  • 投票:只有主节点参与投票

为什么主节点数量必须 ≥ 3?

"超过半数"的硬性要求是基于 Raft 协议 的分布式一致性原则,不可配置。这直接决定了主节点数量必须 ≥ 3。

假设只有 2 个主节点:

主节点 状态 投票权
M1 ❌ 宕机 无法投票
M2 ✅ 正常 1 票
  • 总票数:2 票
  • M2 的票数:1 票(50%)
  • 需要超过半数:> 1 票,即至少 2 票
  • 结果:选举失败,无法选出新主节点 ❌

集群是否可用? 取决于 cluster-require-full-coverage 配置:

配置值 结果
yes(默认) 集群完全不可用,任何请求都返回错误
no 部分可用,M1 负责的槽位不可用,M2 负责的槽位仍可正常服务

不同主节点数量的容错能力:

主节点数 挂掉 1 个后 剩余票数 需要票数(> N/2) 能否选举 最大容错节点数
2 1 个 1 票 > 1(需 2 票) ❌ 不能 0
3 2 个 2 票 > 1.5(需 2 票) ✅ 能 1
5 4 个 4 票 > 2.5(需 3 票) ✅ 能 2
7 6 个 6 票 > 3.5(需 4 票) ✅ 能 3

结论

  • 主节点数量必须是奇数(3、5、7...),因为偶数并不能提高容错能力
  • 3 个主节点可容忍 1 个节点故障
  • 5 个主节点可容忍 2 个节点故障
  • 生产环境推荐 3 个主节点,足以满足大多数场景的高可用需求

3.3 自动分配主从节点机制

Redis Cluster 在创建时会自动分配主从节点关系:

  1. 节点角色分配

    • 在创建集群时,通过 --cluster-replicas 参数指定每个主节点的从节点数量
    • 系统自动将节点分为主节点和从节点
  2. 槽位分配

    • 16384 个哈希槽被均匀分配给主节点
    • 每个从节点知道自己对应的主节点
  3. 故障转移机制

    • 当主节点失效时,其从节点会通过选举产生新的主节点
    • 其他从节点会更新复制目标到新的主节点

3.4 数据分片机制

Redis Cluster 采用哈希槽机制实现数据分片:

  1. 哈希槽划分:整个集群被划分为 16384 个哈希槽(0-16383)
  2. 键到槽映射:每个 key 通过 CRC16 算法计算哈希值,然后对 16384 取模得到槽位号
slot = CRC16(key) % 16384
  1. 槽位分配:这些槽位会均匀分布在不同的主节点上

槽位分配示例:

主节点数 槽位分配
3主 0-5460 (5461槽), 5461-10921 (5461槽), 10922-16383 (5462槽)
4主 0-4095 (4096槽), 4096-8191 (4096槽), 8192-12287 (4096槽), 12288-16383 (4096槽)
6主 0-2730 (2731槽), 2731-5461 (2731槽), 5462-8192 (2731槽), 8193-10922 (2730槽), 10923-13653 (2731槽), 13654-16383 (2730槽)

注意:16384 无法被 3 和 6 整除,因此槽位分配会有 1-2 个槽的差异。

Hash Tag 机制

当 key 包含 {} 时,只有花括号内的部分会被用于哈希计算:

  • user:1000:profileuser:1000:settings不同槽位
  • {user:1000}:profile{user:1000}:settings相同槽位

应用场景: 保证相关数据存储在同一节点上,支持多键操作(如 MGET {user:1000}:profile {user:1000}:settings

3.5 集群模式工作原理

  1. 节点发现:通过 MEET 消息发现新节点
  2. 槽位分配:通过 CLUSTER ADDSLOTS 命令分配槽位
  3. 状态同步:节点间通过 Gossip 协议交换集群状态(IP、端口、运行ID、槽位信息)
  4. 请求路由
    • 节点存储映射:每个节点都存储完整的哈希槽与节点的对应关系
    • 客户端缓存映射:客户端也会缓存一份哈希槽映射关系,负责将请求直接发送到正确的节点
    • MOVED 重定向:当集群扩容/缩容导致客户端缓存的旧映射失效,请求发送到错误的节点时,节点会返回 MOVED 重定向,客户端据此更新映射关系并重新发送请求到正确的节点
  5. 故障检测:通过 PING/PONG 消息检测节点状态
  6. 故障转移:从节点检测到主节点失效后发起选举,成为新的主节点

3.6 客户端类型

Redis 集群客户端分为智能客户端非智能客户端两种类型:

类型 特点 性能
非智能客户端 不缓存槽位映射,每次请求可能需要重定向 较低,多次网络往返
智能客户端 缓存槽位映射,直接将请求发送到正确节点 较高,减少重定向次数

智能客户端工作流程

  1. 初始化:启动时从集群节点获取完整的槽位映射关系
  2. 本地缓存:缓存哈希槽与节点的对应关系
  3. 直接路由:根据缓存的映射,直接将请求发送到正确的节点
  4. 自动更新:收到 MOVEDASK 响应时,自动更新本地缓存

Spring Boot 客户端

Spring Boot 默认使用 Lettuce 作为 Redis 客户端(也可选择 Jedis),这两种客户端在集群模式下默认都是智能客户端

  • Lettuce:基于 Netty 的异步客户端,支持连接池,默认智能路由
  • Jedis:传统同步客户端,支持连接池,默认智能路由
spring:
  redis:
    cluster:
      nodes: 127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002
      max-redirects: 3
    # Lettuce 连接池配置(可选)
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0

3.7 集群创建命令

# 创建集群(3主3从,每个主节点1个从节点)
redis-cli --cluster create 127.0.0.1:7000 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 --cluster-replicas 1

3.8 配置示例

节点配置

# 节点监听端口
port 7000

# 开启集群模式
cluster-enabled yes

# 集群配置文件(自动生成和维护)
cluster-config-file nodes-7000.conf

# 节点间通信超时时间(毫秒)
cluster-node-timeout 15000

# 是否要求所有槽位都被覆盖才提供服务
cluster-require-full-coverage no

# 设置密码认证
requirepass your_cluster_password

# 连接主节点时的密码(用于主从复制)
masterauth your_cluster_password

# 允许所有IP连接
bind 0.0.0.0

# 后台运行
daemonize yes

3.9 Spring Boot 配置

配置方式:只写2~3个集群种子节点
读写控制:客户端自动拉取全集群拓扑,写主节点、读从节点自动路由

spring:
  redis:
    # 集群模式配置
    cluster:
      # 集群节点地址列表(只需写2~3个种子节点)
      nodes:
        - 127.0.0.1:7000
        - 127.0.0.1:7001
        - 127.0.0.1:7002
      # 最大重定向次数
      max-redirects: 3
    # Redis密码
    password: your_cluster_password
    # 连接超时时间
    timeout: 2000ms
    # Lettuce配置(读写分离)
    lettuce:
      client-options:
        read-from: REPLICA_PREFERRED # 优先从从节点读

3.10 集群模式优缺点

优点 缺点
支持数据分片,实现水平扩展 多键操作受限,仅支持同一槽位
内置高可用,无需额外组件 客户端需要支持集群协议
每个节点都参与集群管理,无单点故障 事务支持仅限同一节点
适合数据量大,需要分片+高可用的场景 最小需要 6 个节点(3主3从)

多键操作限制详解

集群模式下,不同类型的操作对跨槽的处理方式不同:

操作类型 跨槽支持 说明
普通批量命令(MGET/MSET/DEL) ❌ 必须同槽 跨槽直接报错:CROSSSLOT Keys in request don't hash to the same slot
Hash Tag ✅ 强制同槽 使用 {key} 确保相关 key 在同一槽位,性能最好
Pipeline ⚠️ 可跨槽 客户端自动处理重定向,性能较差,无原子性保证
Lua 脚本 / 事务 ❌ 必须同槽 与普通批量命令相同,必须在同一个节点上执行

Hash Tag 示例:

# ❌ 报错:user:100 和 user:200 可能不在同一槽位
MGET user:100 user:200

# ✅ 正常:{user} 决定槽位,profile 和 settings 都在同一槽位
MGET {user}:profile {user}:settings

选择建议:

  • 性能优先:使用 Hash Tag 确保同槽
  • 开发便利性:可以使用 Pipeline,但需注意性能损耗
  • 强一致性:Lua 脚本和事务必须同槽

3.11 数据倾斜问题

现象

热点槽、热点大 Key、热点读/写集中在单节点,导致节点 CPU / 内存 / 网卡打满,集群负载失衡。

成因

成因 说明
固定 HashTag 过度使用同一个 HashTag,导致大量 key 集中在一个槽位
业务分区键单一 业务设计时只用一个字段做 hash,无法分散到不同节点
冷热数据未分离 热点数据和冷数据混在一起,热点数据占用大量资源
大 Key 集中 单个 key 的 value 特别大,导致该节点负载过高

优化方案

1. 打散热点 Key

  • 增加随机后缀:将热点 key 拆分为多个副本,分散到不同槽位
    hot:user:100 → hot:user:100:0, hot:user:100:1, hot:user:100:2
    
  • 结合 HashTag:使用 HashTag 确保同槽操作
    {user:100}:profile:{0}, {user:100}:profile:{1}, {user:100}:profile:{2}
    

2. 拆分大 Key

类型 优化方法
大 Hash 拆分为多个小 Hash,使用 HashTag 确保同槽
大 List 拆分为多个 List,按范围或 hash 分桶
大 Set 按数据类型或时间维度分桶

3. 冷热分离

  • 热点数据放 Redis:频繁访问的数据保持在 Redis
  • 冷数据落库:不常访问的数据定期持久化到数据库
  • 本地缓存兜底:读多写少场景,使用本地缓存(如 Caffeine、Guava Cache)减轻 Redis 压力

4. 监控告警

监控项 告警阈值建议
槽位负载 单槽 key 数量超过平均值 200%
Key 大小 单个 key 超过 10MB
节点 CPU 节点 CPU 使用率超过 80%
节点内存 节点内存使用率超过 80%

监控命令:

# 查看各节点 key 数量
redis-cli --cluster info 127.0.0.1:7000

# 查看槽位分布
redis-cli --cluster check 127.0.0.1:7000

# 扫描大 key(Redis 4.0+)
redis-cli --bigkeys -i 0.1

4. 三种模式对比

特性 主从模式 哨兵模式 集群模式
数据分片 不支持 不支持 支持(16384个哈希槽)
扩展性 垂直扩展 垂直扩展 水平扩展
高可用 无(需要人工干预) 自动故障转移 自动故障转移
主从管理 手动配置 哨兵自动管理 集群自动管理
客户端复杂度 简单 简单 需要支持集群协议
多键操作 完全支持 完全支持 仅支持同一槽位
事务支持 完全支持 完全支持 仅限同一节点
最小节点数 2个(1主1从) 5个(1主1从+3哨兵) 6个(3主3从)
适用场景 数据量小,基础读写分离 数据量小,需要高可用 数据量大,需要分片+高可用

核心区别总结

模式 配置方式 读写控制 核心特点
主从模式 手动写死主从节点地址 客户端代码自己控制写主、读从 Redis 只负责数据同步,不负责路由和故障转移
哨兵模式 只写2~3个哨兵种子节点 客户端问哨兵拿主节点写主;自动发现所有从节点读从 哨兵负责故障转移、主从切换
集群模式 只写2~3个集群种子节点 客户端自动拉取全集群拓扑,写主节点、读从节点自动路由 分片 + 高可用,自带故障转移

一句话口诀:

主从自己写,哨兵找主从,集群全自动。


5. 总结

Redis 的三种高可用模式适用于不同的场景:

  1. 主从模式:适用于数据量不大,只需要读写分离数据备份的场景。配置简单,但主节点故障需要人工干预。

  2. 哨兵模式:在主从模式基础上增加了自动故障转移功能,适用于数据量不大但需要高可用的场景。缺点是不支持数据分片。

  3. 集群模式:通过数据分片实现水平扩展,同时具备高可用机制,适用于数据量大、需要分片和分片内高可用的现代分布式应用。

重要结论:

  • 哨兵模式和集群模式在主从复制的基本机制上是相似的,都基于 PSYNC2 协议,都支持全量和增量同步
  • 集群模式内置了高可用机制,不需要额外的哨兵组件
  • 选择哪种模式主要取决于数据量大小性能要求系统复杂度等因素

推荐:

  • 小规模应用(数据量 < 10GB):使用哨兵模式
  • 大规模应用(数据量 > 10GB):使用集群模式
  • 集群模式因为其内置的高可用性和自动主从管理机制,更适合现代分布式应用的需求。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容