Redis 4.0+ 的 redis-cli --hotkeys 是最轻量安全的高频键筛查方式,但需先启用 volatile-lfu 或 allkeys-lfu 策略并预热5–10分钟;它基于LFU采样排序输出近期相对热度Top N,不阻塞但结果依赖统计积累。

用 redis-cli --hotkeys 快速筛出高频访问键
Redis 4.0+ 内置的 --hotkeys 是最轻量、最安全的起点,但它有硬性前提:必须开启 LFU(Least Frequently Used)淘汰策略,且需提前运行足够时间积累访问频次统计。
- 检查当前策略:
redis-cli config get maxmemory-policy,如果不是allkeys-lfu或volatile-lfu,--hotkeys会返回空或误导结果 - 临时启用(不影响数据):
redis-cli config set maxmemory-policy volatile-lfu,无需重启 - 执行检测:
redis-cli --hotkeys,它会扫描样本键并按 LFU 计数排序输出 Top N —— 注意这不是“每秒计数”,而是近期相对热度排名 - 该命令本身不阻塞,但依赖后台采样,若实例刚启动或流量低,结果可能为空或失真
用 MONITOR 捕获真实 QPS 级热点(慎用!)
当你要确认某个 key 是否真的在“每秒被成百上千次访问”,MONITOR 是唯一能拿到原始命令流的方式,但它不是监控手段,而是诊断手术刀。
- 生产环境禁用超过 10 秒:
redis-cli monitor | head -n 10000配合grep统计,例如redis-cli monitor | grep -o "get [^[:space:]]*" | sort | uniq -c | sort -nr | head -20 - 开销极大:每条命令都会复制一份日志到客户端,吞吐下降 30%+ 很常见,CPU 和网络带宽双吃紧
- 只适用于短时定位:比如活动开始后 5 秒内突增的 key,截取窗口越小,结论越准
- 注意协议解析陷阱:
MONITOR输出含多行 RESP 协议格式,直接grep get可能漏掉 pipeline 请求中的 key,建议用redis-faina这类专用解析工具
用 Lua 脚本 + ZSET 实现带时间窗口的访问计数
如果你需要精确知道“过去 60 秒内某 key 被访问了多少次”,就得自己搭轻量级统计层,核心是用 ZSET 存时间戳,靠 ZCARD 和 ZREMRANGEBYSCORE 维护滑动窗口。
- 每次访问 key 前,执行一段 Lua:
redis.call("zadd", "access:"..KEYS[1], ARGV[1], ARGV[2]); redis.call("zremrangebyscore", "access:"..KEYS[1], 0, ARGV[1]-60000); return redis.call("zcard", "access:"..KEYS[1]),其中ARGV[1]是毫秒时间戳,ARGV[2]是唯一请求 ID(防重复计数) - 统计时查
ZCARD access:hot_item_123就是最近 60 秒访问次数,比抽样更准 - 代价是每次访问多一次 Redis 写操作,QPS 上限会略降;同时
ZSET本身占内存,key 过多时需定期清理空ZSET - 别用
INCR替代:它无法自动过期旧计数,会导致数值持续累积失真
为什么不能只靠 KEYS * + 客户端遍历统计?
KEYS * 在数据量大时会阻塞 Redis 主线程,而客户端逐个调用 OBJECT FREQ 或 TTL 更是把压力从服务端转嫁到网络和客户端 CPU,完全违背“定位热点”的初衷。
-
KEYS *时间复杂度 O(N),100 万 key 可能卡主进程 2 秒以上,触发超时告警 -
OBJECT FREQ仅对 LFU 策略有效,且返回的是估算值(非精确计数),文档明确写 “not suitable for accurate counting” - 脚本里用
SCAN替代KEYS也不解决问题:SCAN 本身不提供访问频次,你仍得对每个 key 发起额外命令,总耗时翻倍 - 真正要做的,是区分场景——日常巡检用
--hotkeys,突发问题用MONITOR截流,长期监控就上 Prometheus +redis_exporter拉取instantaneous_ops_per_sec和 key-level 指标
实际部署时,最容易被忽略的是 LFU 策略的预热期:新上线的 Redis 实例即使配了 volatile-lfu,前几分钟的 --hotkeys 结果也基本不可信。得先让流量跑够 5–10 分钟,再看结果。










