SLOWLOG GET 是排查 Redis CPU 飙高的首要命令,返回每条记录的 ID、时间戳、耗时(微秒)、命令及参数;需结合 execution_time、command 和 arguments 识别高开销命令(如 KEYS *、HGETALL),并注意 slowlog-log-slower-than 默认 10ms 阈值可能漏判,建议按需调至 5ms。

查 slowlog get 看哪些命令在吃 CPU
Redis 是单线程,CPU 飙高必然是某个或某类命令执行耗时太长、频率太高。直接执行 slowlog get 20,重点看三列:execution_time(单位微秒)、command、arguments。
常见高 CPU 命令按数据类型归类:
-
KEYS *(String/通用):O(n) 全库扫描,10 万 key 就可能卡主线程 300ms+ -
HGETALL(Hash):哈希字段超 5000 个时,平均耗时直线上升;HSCAN替代更安全 -
SMEMBERS(Set)、LRANGE biglist 0 -1(List)、ZRANGE bigzset 0 -1 WITHSCORES(ZSet):全量拉取,元素数 >1 万就危险 -
SINTER/SUNION(Set)、ZUNIONSTORE(ZSet):多集合运算,复杂度常为 O(n+m),数据量叠加后极易超时
注意:slowlog-log-slower-than 默认是 10000(10ms),若业务对延迟敏感,可临时设为 5000:config set slowlog-log-slower-than 5000,但别长期开着,避免日志膨胀。
用 info commandstats 分析各类型命令的平均开销
info commandstats 输出里,每个 cmdstat_XXX 行含 calls、usec、usec_per_call。真正要盯的是 usec_per_call —— 它反映该命令的“真实体重”。
比如发现 cmdstat_hgetall: calls=124892, usec=2548920100, usec_per_call=20407(20.4ms/次),说明 HGETALL 已成瓶颈,不是调用次数多,而是每次都很重。
对比不同数据类型的典型值(仅供参考):
-
GET/SET:通常 -
HGET(单字段):~200–500μs;HGETALL(万级字段):常 >10ms -
LPUSH/LPOP:轻量,但若 List 长度达百万级,LINDEX或LRANGE会陡增 -
ZADD(小 zset):~300μs;ZRANK在大 zset 上可能 >5ms
如果 usec_per_call 异常高,且对应命令集中在某类结构(如全是 HGETALL),基本可锁定是 Hash 设计问题:字段过多、未做分片、或本该用 String 存却用了 Hash。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
区分是“大 Key”还是“热 Key”导致的 CPU 压力
大 Key 和热 Key 表象相似(CPU 高、QPS 不一定高),但根因和处理方式完全不同:
-
大 Key 特征:slowlog 里有单条命令耗时极长(如
HGETALL user:1001耗时 380ms),redis-cli --bigkeys能扫出;value 大小常 >10KB,甚至 MB 级 -
热 Key 特征:slowlog 里命令本身不慢(
GET hot_user:123平均 0.8ms),但调用频次极高(每秒数千次),redis-cli --hotkeys可识别(需 Redis ≥4.0 +maxmemory-policy启用 LFU)
关键区别在于:--bigkeys 查的是「体积」,--hotkeys 查的是「访问密度」。两者可能共存(一个 5MB 的热 Hash),但排查顺序建议先 slowlog → 再 commandstats → 最后用 --bigkeys 或 --hotkeys 定向验证。
注意:--hotkeys 在 noeviction 策略下无效;--bigkeys 扫描期间会阻塞主线程,生产环境慎用,优先在低峰期跑。
警惕客户端行为引发的隐性 CPU 消耗
有些 CPU 飙高跟命令本身无关,而是客户端使用方式触发了 Redis 内部高频操作:
-
短连接滥用:每次请求都新建/关闭连接,
freeClient中的listSearchKey会频繁触发,perf 可见其 CPU 占比反超readQueryFromClient -
无意义的高频探活:客户端每秒发几十次
PING,虽单次快,但累积打断事件循环,尤其在连接数多时 -
未用 Pipeline 却发大量小命令:比如循环 1000 次
GET key:i,网络往返 + 解析开销远高于一次pipeline GET key:1 ... GET key:1000 - Lua 脚本内嵌复杂逻辑:如在 EVAL 里做遍历、正则匹配、多次 KEYS,脚本执行时间超 100ms 就足以拖垮 CPU
这类问题不会出现在 slowlog(因为单条命令快),但 info clients 里的 connected_clients 和 client_longest_output_list 可辅助判断连接质量;client list 中看 cmd 列是否集中于 ping 或 auth,再结合 addr 定位异常客户端 IP。
真正难缠的 CPU 问题,往往藏在“命令不慢但太密”或“连接太碎但太多”这种组合里。别只盯着 slowlog,commandstats 和 client list 才是照出客户端真相的镜子。

















