26人参与 • 2026-07-28 • Redis
两种判定标准:
redis 是单线程执行命令,所有操作串行,大 key 操作直接阻塞主线程:
hgetall、lrange 0 -1、zrange 0 -1 会一次性遍历数万元素,cpu 打满,后续所有读写请求排队超时。redis 4.0+ 内置命令,分批次扫描,不会阻塞主线程
# 扫描整个库,输出top大key redis-cli --bigkeys
输出会区分 string/list/hash/zset,给出每个类型最大 key、元素数量、占用空间。
# 选择db1,匹配user开头的key,分段扫描 redis-cli -n 1 --bigkeys --pattern "user*"
rdb-tools 工具解析 rdb 文件,导出全部 key 大小报表,适合生产集群。
监控指标:
问题:缓存全量对象、大文本、完整列表数据
将单个大 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使用snappy/gzip压缩 value,大幅降低体积;避免 java 原生序列化(体积极大),改用 protostuff/json 压缩。
列表数据不要一次性存入,按分页 key 存储:
goods_list:page1 goods_list:page2
问题:单 hash 存上万条 field,hgetall 直接阻塞
原 key:product:info 存储十万商品信息 分片拆分 n 个 hash:
product:info:0 product:info:1 # 分片规则:商品id % 10
每个 hash 仅几千条 field,hgetall 无压力。
业务代码绝对不要全量读取 hash,使用游标分批拉取,不会阻塞 redis:
# 游标0开始,每次取100条 hscan product:info 0 count 100
高频访问字段单独拆分小 hash,低频大字段存入独立 key。
问题:生产者速度远大于消费者,list 堆积几十万数据,lrange 0 -1、批量删除阻塞
拆分多个 list,生产者轮询写入,多消费者并行消费,分散数据量
msg_queue:0 msg_queue:1 msg_queue:2
业务允许的前提下,队列超过阈值时丢弃旧数据,避免无限堆积。
stream 支持消费组、ack 确认,不会出现 list 堆积后大量删除阻塞问题,替代 list 做消息队列。
zrange 0 -1全量拉取,分页zrange start end直接 del big_key 会阻塞主线程,分两种安全删除方式:
循环分批删除少量元素,每次操作耗时极短,不阻塞
# hash分批删除field hscan big_hash 0 count 100 hdel big_hash field1 field2 ... # list从尾部批量弹出 lpop big_list 50
使用unlink替代del:
del:同步删除,立即释放内存,阻塞主线程unlink:异步删除,主线程仅标记 key,后台子线程回收内存,无阻塞unlink big_string_key
hgetall/lrange 0 -1/zrange 0 -1全量读取--bigkeys脚本,超过阈值触发告警很多人混淆两者:
以上就是redis大key问题的完整解决方案的详细内容,更多关于redis大key问题解决的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论