redis-cli --bigkeys 扫描必须加 -i 参数,否则会持续占用主线程、阻塞请求;建议使用 -i 0.1(每处理100个key休眠0.1秒),并在从节点低峰期执行,配合 memory usage 验证真实内存占用。

redis-cli --bigkeys 扫描必须加 -i 参数
不加 -i 会导致扫描过程持续占用主线程,每轮 SCAN 都阻塞其他请求,线上集群根本扛不住。尤其当 keyspace 超过百万级时,redis-cli --bigkeys 默认行为会把整个数据库扫一遍,期间无法响应任何命令。
实操建议:
- 务必使用
-i 0.1(每处理100个key休眠0.1秒),或根据业务低峰期调整为-i 0.05 - 只在目标异常分片上执行,不要全集群并发跑;例如:
redis-cli -h 10.186.62.56 -p 6382 --bigkeys -i 0.1 - 注意输出里的百分比进度——如果卡在某个区间(如
[40.93%])不动,大概率是遇到一个真正的大Key正在被序列化,此时别中断,等它吐出结果
用 info memory + memory usage 定位真实内存开销
used_memory 只显示总用量,掩盖了单 key 占比。比如一个 bigk:0 占用 200MB,但 info keyspace 显示只有 19 万个 key,很容易误判为“数据量不大”。
关键动作是逐个验证可疑 key 的实际内存占用:
- 先用
--bigkeys输出的候选 key(如"bigk:0")做靶向检查 - 执行
memory usage bigk:0—— 这个命令返回的是精确字节数,不是估算值 - 对比
memory usage和strlen(String)或hlen(Hash)结果:若前者远大于后者,说明内部编码或碎片导致隐性开销
警惕 Hash/List 类型的“伪小Key”
一个 user:profile:123 看起来只是普通 key,但如果是 Hash 类型且存了 5000 个 field,每个 field value 平均 2KB,总内存就超 10MB。这种 Key 不会在 --bigkeys 的“Biggest hash”里排第一(因为按 field 数量排序),却实实在在拖垮节点。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
排查这类问题要换思路:
- 用
hscan user:profile:123 0 COUNT 1000抽样看 field 分布 - 对高频访问的 Hash/Sorted Set 类 key,加监控:定期执行
hlen+memory usage,设置阈值告警(如hlen > 2000且memory usage > 2_000_000) - 特别注意带通配符的 key 模式,比如
cache:*:items,容易在业务迭代中悄悄膨胀
集群模式下大Key迁移会放大问题
Redis Cluster 迁移 slot 时,是把整个 slot 下所有 key 搬过去。如果 slot 里混着一个 150MB 的 bigk:0,迁移过程不仅慢,还会让目标节点瞬间内存飙升——而你看到的“某分片内存异常高”,很可能就是刚完成迁移还没来得及淘汰旧数据。
这时不能只查当前 key,还要确认历史操作:
- 查
redis-cli -h xxx info cluster中的cluster_state和migration相关字段 - 翻最近 24 小时的运维操作记录,是否有人手动执行过
cluster setslot ... migrating - 用
redis-cli --cluster check验证 slot 分布一致性,避免因迁移中断导致部分 key 残留
真正棘手的不是发现大Key,而是它往往藏在业务逻辑深处——比如用户上传的原始图片 base64 编码后直接塞进 String,或者日志聚合结果没做分片就往 ZSet 里堆。这类 Key 很难靠阈值自动识别,得结合业务接口的响应耗时、客户端报错日志(如 READONLY You can't write against a read only replica 其实是主节点被 DEL 大Key卡住导致从库升主失败)交叉印证。

















