Redis大Key问题的完整解决方案

 更新时间:2026年07月28日 08:49:27   作者:阿宇的技术日志  
Redis大key问题困扰你吗,本文详解大key的判定标准、致命影响,并提供从定位到优化、安全删除的全套方案,学会分片拆分、异步删除等技巧,让你的Redis告别阻塞和内存溢出,性能提升看得见,需要的朋友可以参考下

一、什么是大 Key

两种判定标准:

  1. 数据体积大:字符串 value 超过 10KB;集合类 (List/Hash/Set/ZSet) 元素总量超 1 万、总大小超 100KB
  2. 操作耗时久:单次命令遍历大量元素,阻塞主线程

常见大 key 类型

  • String:超大文本、序列化全量对象、整表缓存
  • Hash:单 hash 存储上万条业务数据(如用户全部标签塞一个 hash)
  • List:消息队列堆积几十万未消费数据
  • ZSet:排行榜一次性存储全量用户数据

二、大 key 带来的致命问题

Redis 是单线程执行命令,所有操作串行,大 key 操作直接阻塞主线程:

  1. 命令阻塞,服务雪崩 删除大 Hash/List、hgetalllrange 0 -1zrange 0 -1 会一次性遍历数万元素,CPU 打满,后续所有读写请求排队超时。
  2. 内存瞬间抖动,触发 OOM 删除大 key 时,Redis 会一次性回收大量内存,内存分配器出现卡顿;若开启持久化,RDB/AOF 重写时拷贝大 key,内存占用翻倍,容器 / 服务器内存溢出宕机。
  3. 集群槽位迁移卡死 Redis Cluster 集群迁移 slot 时,会完整拷贝 key,大 key 迁移耗时数十秒,集群迁移超时失败,槽位不稳定。
  4. 网络流量突增 客户端一次性读取超大 value,网卡瞬间打满,挤压其他正常请求。

三、如何定位大 key

1. 线上在线扫描(不阻塞,推荐)

Redis 4.0+ 内置命令,分批次扫描,不会阻塞主线程

# 扫描整个库,输出top大key
redis-cli --bigkeys

输出会区分 String/List/Hash/ZSet,给出每个类型最大 key、元素数量、占用空间。

2. 精准扫描指定库 / 筛选 key 前缀

# 选择db1,匹配user开头的key,分段扫描
redis-cli -n 1 --bigkeys --pattern "user*"

3. 离线 RDB 分析(超大集群避免线上扫描)

rdb-tools 工具解析 RDB 文件,导出全部 key 大小报表,适合生产集群。

4. 监控实时识别

监控指标:

  • 慢查询日志(slowlog):大量耗时超过 100ms 的命令,大概率操作大 key
  • Redis 内存监控:内存毛刺式上涨下跌
  • 集群迁移 slot 耗时指标

四、大 key 优化方案(分场景)

场景 1:String 大 key(超长字符串)

问题:缓存全量对象、大文本、完整列表数据

优化 1:分片拆分(推荐)

将单个大 key 拆分成多个小 key 例:存储 id=1000 用户详情

# 原大key(禁止)
user_info:1000 = {id:1000,name:xx,addr:xx,tag:[...]}
# 拆分多个小String
user_info:1000:name = 张三
user_info:1000:addr = 北京市xxx
# 列表标签单独拆分Hash存储
user_tag:1000 hash

优化 2:压缩序列化

使用Snappy/Gzip压缩 value,大幅降低体积;避免 Java 原生序列化(体积极大),改用 Protostuff/JSON 压缩。

优化 3:分页存储,不缓存全量

列表数据不要一次性存入,按分页 key 存储:

goods_list:page1
goods_list:page2

场景 2:Hash 大 key(最常见业务坑)

问题:单 Hash 存上万条 field,hgetall 直接阻塞

方案 1:Hash 分片(Hash 拆分)

原 key:product:info 存储十万商品信息 分片拆分 N 个 hash:

product:info:0
product:info:1
# 分片规则:商品id % 10

每个 Hash 仅几千条 field,hgetall 无压力。

方案 2:禁止 hgetall,使用 hscan 迭代遍历

业务代码绝对不要全量读取 Hash,使用游标分批拉取,不会阻塞 Redis:

# 游标0开始,每次取100条
hscan product:info 0 count 100

方案 3:冷热分离

高频访问字段单独拆分小 Hash,低频大字段存入独立 key。

场景 3:List 大 key(消息队列堆积)

问题:生产者速度远大于消费者,List 堆积几十万数据,lrange 0 -1、批量删除阻塞

优化 1:分片队列

拆分多个 List,生产者轮询写入,多消费者并行消费,分散数据量

msg_queue:0
msg_queue:1
msg_queue:2

优化 2:限制队列长度,设置丢弃策略

业务允许的前提下,队列超过阈值时丢弃旧数据,避免无限堆积。

优化 3:改用专业队列(Redis Stream)

Stream 支持消费组、ack 确认,不会出现 List 堆积后大量删除阻塞问题,替代 List 做消息队列。

场景 4:ZSet/Set 大 key(排行榜、标签集合)

  1. 排行榜分片:按区间拆分多个 ZSet(0-1000、1000-2000)
  2. 禁止zrange 0 -1全量拉取,分页zrange start end
  3. 超大标签集合拆分多 Set,求交集时客户端合并结果

五、大 key 安全删除方案(重中之重)

直接 del big_key 会阻塞主线程,分两种安全删除方式:

1. 集合类大 key(Hash/List/Set/ZSet):分段删除

循环分批删除少量元素,每次操作耗时极短,不阻塞

# Hash分批删除field
hscan big_hash 0 count 100
hdel big_hash field1 field2 ...
# List从尾部批量弹出
lpop big_list 50

2. String 超大 key:异步非阻塞删除(Redis 6+)

使用unlink替代del

  • del:同步删除,立即释放内存,阻塞主线程
  • unlink:异步删除,主线程仅标记 key,后台子线程回收内存,无阻塞
unlink big_string_key

六、线上预防规范(开发约束)

  1. 编码规范:
    • 禁止单 Hash/List 存储超过 1000 条元素
    • 禁止使用hgetall/lrange 0 -1/zrange 0 -1全量读取
    • 列表、排行榜强制分页存储、分页查询
  2. 监控告警:
    • 定时执行--bigkeys脚本,超过阈值触发告警
    • 慢查询日志持续监控,捕获大 key 耗时命令
  3. 集群规范: Redis Cluster 环境严格规避大 key,迁移 slot 极易集群故障;分片是集群最优解。
  4. 过期策略: 大 key 不要设置统一过期时间,打散过期时间,避免大批量同时过期产生内存雪崩。

七、补充:大 key 与热 key 区别

很多人混淆两者:

  • 大 key:数据体积大,问题是阻塞、内存、迁移卡顿
  • 热 key:访问 QPS 极高(每秒几万次请求),问题是 CPU、缓存击穿、集群流量倾斜 优化方案完全独立,分开处理。

以上就是Redis大Key问题的完整解决方案的详细内容,更多关于Redis大Key问题解决的资料请关注脚本之家其它相关文章!

相关文章

  • Redis主从复制操作和配置详情

    Redis主从复制操作和配置详情

    这篇文章主要介绍了Redis主从复制操作和配置详情,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Redis简易延时队列的实现示例

    Redis简易延时队列的实现示例

    在实际的业务场景中,经常会遇到需要延时处理的业务,本文就来介绍有下Redis简易延时队列的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • Redis中LRU算法和LFU算法的区别小结

    Redis中LRU算法和LFU算法的区别小结

    在Redis中,LRU算法和LFU算法是两种常用的缓存淘汰算法,它们可以帮助我们优化缓存性能,本文主要介绍了Redis中LRU算法和LFU算法的区别,感兴趣的可以了解一下
    2023-12-12
  • Redis 缓存击穿问题及解决方案

    Redis 缓存击穿问题及解决方案

    缓存击穿是指在高并发环境下,大量请求同时访问缓存中不存在的数据,导致这些请求穿透到数据库,本文主要介绍了Redis缓存击穿问题及解决方案
    2023-12-12
  • Redis主从集群切换数据丢失的解决方案

    Redis主从集群切换数据丢失的解决方案

    这篇文章主要介绍了Redis主从集群切换数据丢失的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Redis在实际开发中的运用场景解读

    Redis在实际开发中的运用场景解读

    Redis是一款基于内存的键-值型NoSQL数据库,适用于快速数据读写场景,如分布式系统缓存、数据高速读写业务、分布式锁、数据共享和ID自增序列等
    2025-12-12
  • Redis全文搜索教程之创建索引并关联源数据的教程

    Redis全文搜索教程之创建索引并关联源数据的教程

    RediSearch提供了一种简单快速的方法对 hash 或者 json 类型数据的任何字段建立二级索引,然后就可以对被索引的 hash 或者 json 类型数据字段进行搜索和聚合操作,这篇文章主要介绍了Redis全文搜索教程之创建索引并关联源数据,需要的朋友可以参考下
    2023-12-12
  • 如何查看redis服务的版本

    如何查看redis服务的版本

    这篇文章主要介绍了如何查看redis服务的版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Redisson分布式限流的实现原理分析

    Redisson分布式限流的实现原理分析

    这篇文章主要介绍了Redisson分布式限流的实现原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Redis RESP 协议实现实例详解

    Redis RESP 协议实现实例详解

    这篇文章主要为大家介绍了Redis RESP 协议实现实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09

最新评论