Redis INFO commandstats 如何定位单命令 CPU 异常:calls、usec_per_call 与采样边界
来源:17golang原创
时间:2026-08-29 17:37:15 135浏览 收藏
线上 Redis 的 CPU 曲线突然抬头时,直接盯着 instantaneous_ops_per_sec 往往只能看到“忙”,看不出是哪条命令把 CPU 吃掉了。更稳妥的办法是连续采两次 INFO commandstats,用 calls 增量确认调用量,再结合 usec_per_call 和失败计数判断是调用变多、单次变重,还是请求已经在命令层被拒绝。
定位单命令 CPU 异常,不要只按累计值排序;至少比较同一窗口里的 calls 增量、usec 增量和失败计数,并把结果与业务流量变化对齐。
calls说明命令真正进入执行的次数,不能直接等同于客户端发起次数。usec_per_call是累计 CPU 微秒的平均值,必须和采样窗口、调用量一起看。rejected_calls与failed_calls能帮助区分容量拒绝和执行失败。- Redis 7 起部分命令统计会拆到子命令,比较历史数据时要先确认统计粒度。
先把 Redis CPU 异常拆成三个问题
同样是 CPU 上升,处理方式可能完全不同:请求量变大属于容量问题,某条命令的平均 CPU 变高更像数据规模或参数变化,failed_calls 上升则要回到调用方检查参数和数据类型。第一步不是重启 Redis,而是把“忙在哪里”固定下来。
redis-cli INFO stats
redis-cli INFO commandstats
INFO 的执行复杂度是 O(1),但返回整段统计;排查时优先请求 commandstats,减少人工阅读范围。示例中的一行可能是:
cmdstat_hget:calls=18420,usec=92100,usec_per_call=5.00,rejected_calls=0,failed_calls=2
这行只能说明从 Redis 进程启动或统计重置以来的累计情况,不能单凭 5 微秒断言当前请求一定快。
用两次快照判断调用变多还是单次变重
把第一次快照记为 A,间隔一段真实业务时间后记为 B。对同一个 cmdstat_* 项分别计算 Δcalls = B.calls - A.calls 与 Δusec = B.usec - A.usec,窗口平均 CPU 约为 Δusec / Δcalls。如果 calls 增长很快而平均值稳定,优先看流量或重试;如果 calls 增长不大但平均值显著抬高,再查 key 大小、参数范围和数据结构。

实际记录时至少保留时间戳、命令名、calls、usec、usec_per_call 和业务请求量。不要把不同重启周期的累计值直接相减,也不要在采样中间执行会重置统计的操作后继续拼接窗口。
| 观察结果 | 更可能的方向 | 下一步 |
|---|---|---|
| Δcalls 大,平均 CPU 稳定 | 调用量、重试或流量上升 | 对齐客户端请求数与重试计数 |
| Δcalls 小,Δusec 明显变大 | 单次命令成本上升 | 核对 key 体积、成员数量和参数 |
| failed_calls 上升 | 命令执行失败 | 检查数据类型、参数与调用方日志 |
| rejected_calls 上升 | 命令被拒绝 | 检查资源保护、客户端限流和实例状态 |
把 commandstats 字段和业务症状对上
calls 是到达命令执行层的次数,usec 是该命令累计消耗的 CPU 微秒,usec_per_call 是平均值。它们回答的是 Redis 进程内部的成本,不包含客户端排队、网络往返或连接池等待。
failed_calls 和 rejected_calls 不要混为一谈:前者表示执行过程失败,后者表示请求在执行前被拒绝。两者都为零也不代表业务正确,只能说明这两个统计项没有记录到异常。

Redis 7 及之后,某些命令会按子命令分别统计。例如 ACL 相关调用可能出现带子命令的统计键。做版本升级前后的对比时,先确认 cmdstat_* 的命名粒度发生了什么变化,否则很容易把“统计拆分”误判成“调用突然减少”。
三个容易误判的采样边界
累计平均值不是当前 P99
usec_per_call 是累计平均 CPU,不是端到端延迟,也不是 P99。它适合发现趋势和做同窗口比较;长时间运行后,早期的轻请求仍会稀释最近的重请求。
空窗口不能下结论
如果两次采样之间 Δcalls 为零,就不要计算平均值,更不能用旧的累计 usec_per_call 代替本窗口结果。延长观察窗口或等待该命令再次出现即可。
统计粒度变化要单独记录
升级 Redis、切换代理或改变客户端命令组合后,命令名和子命令统计可能发生变化。排查记录中应同时保存 Redis 版本、采样命令和完整的相关 cmdstat_* 行。
从定位到修复的最小闭环
先保存两次原始输出,再做差分;接着把异常命令和业务接口、key 模式、参数范围对应起来。若是 calls 增长,先处理调用放大、重试和批量策略;若是单次成本变高,优先限制单请求处理的数据规模。修改后用同样的采样窗口复测,确认 Δusec / Δcalls 回落,同时检查失败计数没有被转移到另一条命令。
这里别急着把 usec_per_call 当成唯一告警阈值。不同命令、不同数据集的正常成本差别很大,告警更适合使用“同命令基线 + calls 增量 + CPU 总量”的组合条件。
相关问题
为什么 calls 和客户端请求数对不上?
客户端可能在连接池、代理或重试层重复发起请求,而 commandstats 统计的是到达 Redis 命令执行层的调用;还要考虑事务、脚本和子命令统计粒度。
usec_per_call 高就一定是慢查询吗?
不一定。它是 Redis 进程内的平均 CPU 消耗,不等同于完整请求延迟;网络、排队和客户端等待需要结合其他指标核对。
什么时候应该清零统计再观察?
只有在你能接受丢失累计基线、并且已保存原始快照时才考虑重置。多数线上排查优先用两次快照做差,避免影响其他审计记录。
总结
Redis INFO commandstats 最有价值的不是给出一个漂亮的排序,而是把 CPU 异常拆成可验证的差分:调用量是否增加,单次 CPU 是否变重,执行失败或拒绝是否同步上升。固定采样窗口、保留原始字段、核对版本粒度,才能让修复后的复测结果真正可比较。
-
117 收藏
-
426 收藏
-
171 收藏
-
113 收藏
-
195 收藏
-
189 收藏
-
192 收藏
-
351 收藏
-
数据库 · Redis | 3小时前 | Redis · hash · 数据生命周期 · 缓存过期 · Redis 7.4 · redis Hash HEXPIRE HPTTL 字段过期 Redis 7.4450 收藏
-
409 收藏
-
122 收藏
-
数据库 · Redis | 7小时前 | Redis · 消息队列 · Stream · 消费组 · 重试 · XAUTOCLAIM · redis streams XPENDING XAUTOCLAIM PEL pending JUSTID501 收藏
-
474 收藏
-
500 收藏
-
327 收藏
-
数据库 · Redis | 9小时前 | Redis · 集群 · 命令解析 · 排障 · redis COMMAND GETKEYSANDFLAGS COMMAND GETKEYS 集群路由 键位分析353 收藏
-
112 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习