Redis

Redis 分片完整详解

·9 分钟阅读·3331 字
📋 目录

Redis 分片完整详解

核心概念 Redis 分片通过槽位映射将数据分布到多个节点,支持在线扩缩容,解决单机内存瓶颈。

1. 什么是Redis分片

分片(Sharding)就是把海量数据拆分到多个独立Redis主从节点,解决单机内存、CPU、网络上限瓶颈,实现水平扩容。
两类分片方案:

  1. 客户端分片(手工分片,已淘汰)
  2. Redis Cluster 官方哈希槽分片(生产标准内置分片)

2. 为什么需要分片(单机瓶颈)

单机Redis有硬性上限:

  1. 内存上限:单实例内存最大百GB,超大缓存/存储放不下;
  2. 性能上限:单CPU单核执行命令,百万QPS无法承载;
  3. 持久化瓶颈:RDB/AOF刷盘、主从同步消耗IO,单机容易阻塞;
  4. 故障风险:单节点宕机全量业务不可用。

分片后:数据分散多台机器,压力分摊,可无限横向加节点扩容。

3. 方案1:客户端手工分片(一致性哈希分片)

3.1. 原理

客户端本地通过哈希算法计算key归属节点,直接直连对应Redis实例。

3.1.1. 普通取模分片(缺陷巨大)

公式:slot = hash(key) % N,N=节点总数

  • 节点增减,绝大多数key哈希结果改变,数据全量迁移,业务雪崩。

3.1.2. 一致性哈希分片(解决扩容痛点)

  1. 构建0~2³²环形哈希环;
  2. 节点IP哈希映射到环上点位;
  3. key哈希后顺时针找最近节点存储;
  4. 新增/删除节点仅影响一小段区间key,迁移量极小。
    可增加虚拟节点,均衡数据分布,避免数据倾斜。

3.2. 架构与优缺点

架构:客户端计算路由 → 直连对应Redis主从,无中间代理
✅ 优点:无中间层转发,性能高、延迟低;
❌ 缺点:

  1. 客户端要自己实现哈希、扩容迁移逻辑,开发成本高;
  2. 不支持跨节点多key操作(mget/事务/哈希标签无原生支持);
  3. 节点故障、迁移全靠业务代码处理,无自动故障转移;
  4. 运维复杂,无统一集群管控工具;
    适用:早期老项目,新项目统一使用Redis Cluster。

4. 方案2:Redis Cluster 哈希槽分片(官方内置,主流)

4.1. 核心基础:16384 固定哈希槽

Redis Cluster 固定划分 0 ~ 16383 共16384个slot(哈希槽),所有数据key映射到这16384个槽。

4.1.1. key→slot计算逻辑

CRC16(key) % 16384
  1. 对key做CRC16哈希得到16位数值;
  2. 对16384取模,得到0~16383唯一槽位;
  3. 每个Master主节点分配一部分连续/离散槽,key永久存在对应槽的主节点。

4.1.2. 哈希标签 {tag} 强制同槽(跨key操作必备)

默认多key落在不同槽无法执行事务、mset、管道;
用大括号固定计算哈希的部分,保证一组key同槽:

user:{1000}:name
user:{1000}:age
# 仅对{1000}计算CRC16,两个key必然同一个slot,支持事务

4.2. 集群分片架构(3主3从最小标准)

  1. 每个Master持有一部分slot,负责对应槽读写;
  2. 每个Master配套至少1个Replica从库,主从复制做高可用;
  3. 集群节点互相通信(Gossip协议),同步槽分配、节点上下线、故障信息;
  4. 内置故障自动切换:某分片主宕机,投票提升从库为新主,接管对应slot。

4.3. Gossip 集群通信机制

集群节点每100ms互相发送PING/PONG消息,携带元数据:

  • 各节点ID、IP、端口;
  • 当前每个节点负责的slot范围;
  • 节点健康状态、主从关系;
    作用:客户端任意连接任意节点,都能拿到完整槽路由表。

4.4. 完整读写流程

  1. 客户端连接任意集群节点,发送 set k1 v1
  2. 节点计算k1的slot,判断是否归自己管理:
  • 归属本机:直接执行命令返回结果;
  • 不属于本机:返回MOVED重定向,携带目标主节点地址;
  1. 客户端缓存槽-节点映射表,下次直接直连目标节点(-c集群模式自动跳转);
  2. 写入仅允许Master执行,从库只读同步数据。

4.4.1. ASK重定向(槽迁移中间状态)

当执行--cluster rebalance迁移槽时,槽一半数据在源主、一半在目标主;
访问未迁移完成的key会返回ASK,临时跳转目标节点,迁移完成后永久MOVED。

4.5. 分片扩容/缩容(槽迁移)

4.5.1. 扩容:新增Master分片

  1. 启动新空Master节点加入集群;
  2. 使用 redis-cli --cluster rebalance 自动均衡迁移部分slot到新节点;
  3. 迁移过程增量同步数据,业务不中断,性能轻微抖动。

4.5.2. 缩容:下线分片

  1. 先把该节点所有slot全部迁移到其他Master;
  2. 无槽后执行节点删除,下线实例。

4.6. Cluster分片限制(开发必避坑)

  1. 跨slot多key命令不支持
    mset/mget、multi事务、lpush多个不同槽key直接报错;
    解决方案:哈希标签{tag}分组同槽key。
  2. 仅支持db0,不支持多数据库db1/db2;
  3. keys *、flushdb会遍历所有分片,线上严禁频繁执行;
  4. 槽迁移过程中对应key短暂性能下降;
  5. 不支持大跨分片聚合统计,需要业务层聚合。

5. 方案3:代理中间件分片(Twemproxy / Redis Proxy)

5.1. 原理

中间件统一接收客户端请求,内部实现哈希分片转发到对应Redis节点,对业务透明。
代表:Twemproxy(推特)、Codis(国内)

5.2. 优缺点

✅ 优点:业务无感知,不用改造客户端代码,兼容单机Redis语法;
❌ 缺点:多一层转发增加延迟,代理单点故障,扩缩容需要重启代理。
现在新项目基本淘汰,优先Redis Cluster。

6. 三种分片方案对比

分片方案路由实现跨key事务故障转移扩容成本适用场景
客户端一致性哈希业务代码不支持,需手动tag代码自行处理中等,需迁移逻辑老旧存量项目
Proxy代理Codis/Twemproxy中间件转发不支持代理层管控高,重启代理零改造老旧业务
Redis Cluster哈希槽集群内置16384槽仅同slot支持内置自动切换低,在线迁移槽互联网主流生产标准

7. Redis Cluster分片生产最佳实践

  1. 分片数量规划
    单分片内存控制10~30GB,超过扩容分片;单分片避免超过50G,主从同步、RDB阻塞风险高。
  2. 数据均衡
    新增节点执行rebalance均衡槽,避免单分片数据倾斜;热点key用哈希标签打散。
  3. 高可用标配
    每个分片至少1从,机器交叉部署主从,避免单机宕机丢失多个分片。
  4. 扩容规范
    业务低峰期迁移槽,减少QPS抖动;迁移期间监控分片内存、CPU。
  5. 开发规范
    批量操作使用哈希标签聚合同槽key;禁止跨分片批量mget;大统计业务上层分片聚合。
  6. 监控核心指标
    各分片内存、槽分配均衡度、槽迁移事件、主从同步偏移、集群state状态(ok/fail)。

8. 面试核心总结

  1. Redis分片三大方案:客户端一致性哈希、代理Codis、Redis Cluster哈希槽;
  2. Cluster核心:固定16384个slot,CRC16(key)%16384计算槽位;
  3. 哈希标签{tag}让多key落在同一槽,实现事务、批量操作;
  4. Gossip协议同步集群元数据,MOVED永久重定向、ASK迁移临时重定向;
  5. 扩容本质是在线迁移slot,业务无停机;
  6. 限制:跨槽多key命令不支持、仅db0;
  7. 每个分片独立主从,集群内置自动故障切换,是当前企业标准分片方案。

关联文档