跳到主要内容

Redis 集群方案

问题

Redis 的三种集群方案是什么?Cluster 的哈希槽原理是什么?如何选择集群方案?

答案

一、三种方案概览

方案解决的问题特点
主从复制数据备份、读扩展手动故障转移
Sentinel 哨兵自动故障转移主从 + 监控 + 自动切换
Cluster数据分片 + 高可用分布式存储,扩展写能力

二、主从复制

复制过程

  1. 全量同步(首次连接)

    • 从库发送 PSYNC 命令
    • 主库 BGSAVE 生成 RDB 文件,发送给从库
    • 从库清空数据,加载 RDB
    • 主库将这期间的写命令发送给从库
  2. 增量同步(断线重连)

    • 主库维护复制积压缓冲区(repl_backlog)
    • 从库通过 offset 请求缺失的数据
    • 如果 offset 还在缓冲区内 → 增量同步
    • 如果 offset 已被覆盖 → 退化为全量同步

三、Sentinel 哨兵

故障转移流程

选择新主库的规则(按优先级):

  1. 排除不健康的从库
  2. 优先级最高(slave-priority 最小)
  3. 复制偏移量最大(数据最新)
  4. run_id 最小

四、Redis Cluster

Redis Cluster 是官方的分布式方案,支持 数据分片 + 高可用

哈希槽(Hash Slot)

Redis Cluster 将数据划分为 16384 个哈希槽

slot = CRC16(key) % 16384

每个节点负责一部分槽。扩容时只需迁移部分槽到新节点。

为什么是 16384 个槽?

Redis 作者的回答:

  1. 正常集群不超过 1000 个节点
  2. 16384 个槽的位图只需 2KB,节点间心跳包可以带上
  3. 65536 个槽需要 8KB,心跳包太大

Cluster 架构

请求路由

客户端请求任意节点:

  • 如果 key 在当前节点 → 直接处理
  • 如果 key 不在当前节点 → 返回 MOVED 重定向
客户端 → Node A: GET user:100
Node A → 客户端: MOVED 12345 Node C(说明 slot 12345 在 Node C)
客户端 → Node C: GET user:100
Node C → 客户端: "张三"

五、方案选型

场景推荐方案说明
数据量小,需要高可用Sentinel简单够用
数据量大,需要扩展Cluster官方分布式
只需读扩展主从复制最简单
缓存场景,允许少量丢失Sentinel / Cluster视数据量
持久化存储Cluster + AOF数据分片 + 持久化

常见面试问题

Q1: Redis Cluster 为什么不用一致性哈希?

答案
Redis Cluster 使用预分配哈希槽(而非一致性哈希环)的原因:

  1. 哈希槽方案更简单,CRC16 取模即可
  2. 数据迁移以槽为单位,更可控
  3. 不需要虚拟节点来解决数据倾斜
  4. 节点增减时,只需要迁移特定槽的数据

Q2: Cluster 模式下,多 key 操作有什么限制?

答案
Redis Cluster 要求多 key 操作(MGET、事务、Lua脚本)的所有 key 必须在 同一个槽 中。

解决方案:使用 Hash Tag,将相关的 key 放入同一槽:

# {user:100} 是 Hash Tag,只对 {} 内的部分计算 slot
SET {user:100}:name "张三"
SET {user:100}:age 25
MGET {user:100}:name {user:100}:age # 同一个 slot,可以执行

Q3: Sentinel 和 Cluster 可以混用吗?

答案
不需要。Redis Cluster 内置了故障检测和自动转移功能(通过 Gossip 协议),不需要额外的 Sentinel。Sentinel 适用于非 Cluster 的主从架构。


相关链接