Redis集群模式与哨兵模式详解

Redis 集群模式与哨兵模式详解

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

1. Redis 哨兵模式(Sentinel Mode)

1.1 原理介绍

Redis Sentinel 是 Redis 的高可用性解决方案,它提供以下功能:

  • 监控(Monitoring):Sentinel 会持续检查主服务器和从服务器是否正常运行
  • 通知(Notification):当被监控的 Redis 实例出现问题时,Sentinel 可以通过 API 向管理员或其他应用程序发送通知
  • 自动故障转移(Automatic failover):当主服务器不能正常工作时,Sentinel 会开始一次自动故障转移操作,将一个从服务器升级为新的主服务器,并让其他从服务器开始复制新的主服务器(哨兵会自动将恢复的原主节点降级为从节点,使其追随新选举的主节点
  • 配置提供者(Configuration provider):客户端连接 Sentinel 获取当前 Redis 主节点的地址

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

1.2 哨兵模式工作原理

Redis Sentinel 的工作原理如下:

  1. 主节点监控:哨兵节点通过配置文件指定要监控的主节点,自动发现关联的从节点
  2. 多哨兵协作:多个哨兵节点协同工作,通过投票机制判断主节点是否失效
  3. 故障检测:当主节点在指定时间内没有回复PING,则认为它主观下线,多个哨兵确认后认定为客观下线
  4. 故障转移:从剩余的从节点中选举一个新的主节点,并更新其他从节点的复制目标

1.3 主从复制实现机制

Redis 主从复制是实现高可用的基础,其实现机制如下:

复制ID(replication ID)和偏移量(offset)验证:从库连接主库时会携带自己的replication ID和offset,主库通过比较这些信息判断是否需要进行全量同步,主库将自己的replid和offset发送给从库,使从库保存这些信息。

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

1. 全量同步(同步):

  • 从服务器向主服务器发送 SYNC/PSYNC 命令,请求同步数据。
  • 主服务器收到命令后,开始执行 BGSAVE 命令,在后台生成一个 RDB 文件。
  • 主服务器将生成的 RDB 文件发送给从服务器,在这个过程中,主服务器会将新的写命令缓存在内存中。
  • 从服务器接收到 RDB 文件后,会清空自己的数据库,然后加载 RDB 文件到内存中。
  • 主服务器将缓存的写命令发送给从服务器,从服务器执行这些命令,以保证数据的一致性。

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

全量同步主要在以下情况下使用:

  • 从服务器首次连接主服务器:当从服务器第一次建立与主服务器的连接时(建立长连接),必须进行全量同步以获取完整的数据副本
  • 主从复制中断时间过长:当主从连接断开时间超过repl-backlog-size缓冲区容量时(即偏移量(offset)不在缓冲区),主服务器无法提供增量同步所需的数据,此时会触发全量同步
  • 从服务器重启后数据不一致:如果从服务器重启后无法确定主服务器的复制进度,或者主从数据差异过大时,会触发全量同步
  • 主服务器重启后:当主服务器重启后,如果从服务器无法识别主服务器的runid,也会触发全量同步

2. 增量同步(异步):
在全量同步完成后,主服务器会将新的写命令异步地发送给从服务器。主服务器会将写命令追加到自己的复制积压缓冲区中,并将这些命令发送给从服务器。从服务器接收到这些命令后,会异步地执行它们。
在增量同步阶段,主服务器不会等待从服务器的确认,就会继续处理新的写命令。因此,从服务器的数据可能会稍微落后于主服务器,但这种延迟通常是非常小的。

增量同步主要在以下情况下使用:

  • 主从连接短暂中断后恢复:当网络问题导致主从连接短暂中断,且中断期间的数据变更仍在repl-backlog缓冲区中时(即偏移量(offset)在缓冲区),会使用增量同步
  • 主从复制正常运行期间:在主从复制稳定运行期间,主服务器会持续将写命令通过增量方式同步给从服务器
  • 从服务器重新连接主服务器:当从服务器重新连接主服务器时,如果主从数据差异较小且repl-backlog缓冲区未覆盖相关数据,会使用增量同步

3. 心跳检测

  • 主从节点通过心跳机制维持连接
  • 定期发送 ping/pong 消息检测连接状态

1.4 配置示例

主节点配置

#  监听端口
port 6379

# 设置密码认证
requirepass your_master_password

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

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

# 后台运行
daemonize yes

从节点配置

# 监听端口
port 6380

# 指定主节点地址和端口(主从复制配置)
slaveof 127.0.0.1 6379

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

# 从节点密码
requirepass your_slave_password

# 允许所有IP连接
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

1.5 Spring Boot 配置

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

2. Redis 集群模式(Cluster Mode)

2.1 原理介绍

Redis Cluster 是 Redis 的分布式解决方案,它具备以下特点:

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

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

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

  1. 内置高可用性

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

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

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

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

2.3 自动分配主从节点机制

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

  1. 节点角色分配

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

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

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

2.4 数据分片机制

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

  1. 哈希槽划分:整个集群被划分为 16384 个哈希槽(0-16383)
  2. 键到槽映射:每个 key 通过 CRC16 算法计算哈希值,然后对 16384 取模得到槽位号
slot = CRC16(key) % 16384
  1. 槽位分配:这些槽位会均匀分布在不同的主节点上
    示例分配:
    3主节点:约5461槽/节点(如0-5460,5461-10921,10922-16383)
    4主节点:4096槽/节点
    5主节点:3276槽/节点(余4槽分配给前4节点)

Hash Tag 机制

当 key 包含 {} 时,只有花括号内的部分会被用于哈希计算,这称为 hash tag 机制:

  • user:1000:profileuser:1000:settings 会映射到不同槽位
  • {user:1000}:profile{user:1000}:settings 会映射到相同槽位

这样可以保证相关数据存储在同一节点上,支持多键操作。

2.5 集群模式工作原理

Redis Cluster 的工作原理如下:

  1. 节点发现:通过 MEET 消息发现新节点
  2. 槽位分配:通过 CLUSTER ADDSLOTS 命令分配槽位
  3. 状态同步:节点间通过 Gossip 协议交换集群状态(IP、端口、运行ID、槽位信息),所有节点(包括主节点和从节点)都会参与Gossip协议。
  4. 请求路由:节点收到请求后,如果槽位不属于自己,则返回MOVED重定向
  5. 故障检测:通过PING/PONG消息检测节点状态
  6. 故障转移:从节点检测到主节点失效后发起选举,成为新的主节点

2.6 配置示例

节点配置

# 节点监听端口
port 7000

# 开启集群模式
cluster-enabled yes

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

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

# 节点间是否允许执行故障转移
cluster-slave-no-failover no

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

# 设置密码认证
requirepass your_cluster_password

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

# 允许所有IP连接
bind 0.0.0.0

# 后台运行
daemonize yes

2.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

2.8 Spring Boot 配置

spring:
  redis:
    # 集群模式配置
    cluster:
      # 集群节点地址列表
      nodes:
        - 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
      # 最大重定向次数
      max-redirects: 3
    # Redis密码
    password: your_cluster_password
    # 连接超时时间
    timeout: 2000ms

3. 两种模式对比

特性 哨兵模式 集群模式
数据分片 不支持 支持(16384个哈希槽)
扩展性 垂直扩展 水平扩展
高可用 需要哨兵实现 内置高可用机制
主从管理 哨兵自动管理 集群自动管理
客户端复杂度 简单 需要支持集群协议
多键操作 支持 仅支持同一槽位
事务支持 完全支持 仅支持同一节点
最小节点数 1主1从+3哨兵=5个 3主3从=6个
适用场景 数据量小,需要高可用 数据量大,需要分片

4. 总结

Redis 的哨兵模式和集群模式都是为了解决高可用性问题而设计的,但它们适用于不同的场景:

  1. 哨兵模式适用于数据量不大,但需要高可用性的场景。它通过监控和自动故障转移来保证服务的连续性,需要额外的哨兵组件来实现高可用。

  2. 集群模式适用于数据量大,需要水平扩展的场景。它不仅提供了高可用性,还通过数据分片实现了水平扩展。集群模式内置了高可用机制,不需要额外的哨兵组件,主从节点关系在创建时自动分配和管理。

Redis哨兵模式和集群模式在主从复制的基本机制上是相似的,都基于相同的复制原理和同步协议,都使用PSYNC/PSYNC2协议,都支持全量和增量同步,都通过主从复制实现数据冗余

选择哪种模式主要取决于数据量大小、性能要求和系统复杂度等因素。集群模式因为其内置的高可用性和自动主从管理机制,更适合现代分布式应用的需求。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容