Redis是典型的单线程(命令处理部分)内存数据库,正常情况下CPU占用并不高。一旦发现Redis实例的CPU使用率持续在90%以上,或者相比历史水位有明显抬升,往往意味着存在不合理的命令使用、异常的访问模式或者数据结构设计问题。排查这类问题不能靠猜,需要一套系统性的定位方法,从现象出发逐步缩小范围,最终找到根因。下面结合实际线上排查经验,整理一套完整的排查思路。

一、先确认CPU消耗的来源:进程级定位
排查的第一步是确认高CPU到底是Redis本身造成的,还是同机部署的其他进程拖累。用top命令按CPU排序,观察redis-server进程的实际占用。如果CPU高的是其他进程,说明是资源竞争问题,与Redis本身无关,可以考虑隔离部署或调整资源配额。
如果确认是redis-server进程自身CPU高,还需要区分是用户态CPU(us)还是系统态CPU(sy)。用户态高通常是命令执行、数据操作过多导致;系统态高则可能与频繁的网络中断、内存页面交换、fork子进程有关。观察命令如下:
top -p $(pidof redis-server) # 关注 %CPU、TIME+ 的增长速度 vmstat 1 # cs 列过大说明上下文切换频繁,si/so 非零说明发生了 swap pidstat -t -p $(pidof redis-server) 1 # 查看Redis内部各线程的CPU分布
如果Redis开启了RDB或AOF持久化,fork操作会带来短暂的CPU尖峰,这种情况属于瞬时现象,通常几秒内恢复。但如果发现CPU长期高位运行且与fork时间点吻合频繁,就要检查持久化策略是否合理,比如避免在高峰期触发bgsave。
二、排查慢查询与危险命令
CPU高最常见的原因是执行了复杂度高的命令。Redis是单线程处理命令的,一条慢命令不仅吃CPU,还会阻塞后续所有请求。优先检查慢查询日志,确认是否有O(N)甚至O(N^2)复杂度的命令在执行。
# 查看慢查询日志(阈值由 slowlog-log-slower-than 控制,单位微秒) SLOWLOG GET 20 # 查看慢查询条数 SLOWLOG LEN # 重置慢查询日志 SLOWLOG RESET
重点关注的危险命令包括:KEYS *这种全量扫描、SMEMBERS读取大集合、HGETALL读取大Hash、ZRANGE不带LIMIT地拉取大范围数据、LRANGE全量读取大列表,以及SORT、SINTER作用于大集合等。这些命令的共同特点是操作的数据量不受控,一次命令可能遍历几十万甚至上百万个元素。
建议把慢查询阈值适当调低,比如设置为10毫秒,这样能捕捉到更多可疑命令。对于生产环境,务必通过rename-command把KEYS、FLUSHALL这类高危命令禁用或重命名,从制度上杜绝误用。如果确实需要扫描键,用SCAN代替KEYS,配合COUNT参数分批迭代,避免单次阻塞过久。
另外可以用redis-cli --bigkeys或者开源工具分析是否存在超大key。一个包含几百万元素的Hash,即使业务只是偶尔访问,每次HGETALL都是一次CPU灾难。大key的治理方向是拆分:把大Hash按字段哈希拆成多个小Hash,或者改用渐进式读取。
三、分析热key与QPS压力
如果慢查询日志里没有明显异常,但CPU依然高,那就要看命令总量和热key分布。单实例Redis的极限QPS通常在8万到10万左右,如果业务流量增长导致QPS逼近极限,CPU高就是纯粹的压力问题,需要扩容或集群化。
# 实时查看命令执行统计 INFO commandstats # 关注 ops/sec 指标 INFO stats # 4.0以上版本可以用redis-cli的热key探测(需开启LFU策略) redis-cli --hotkeys
热key问题指的是某个或某几个key承担了绝大部分访问量,比如热门商品详情、爆款活动的计数器。即使总QPS不高,单key每秒几万次GET也会造成CPU压力,并且在集群模式下导致数据倾斜,单分片CPU打满而其他分片空闲。
热key的解决方案主要有三类:一是本地缓存,在应用层用内存缓存或Guava Cache挡住大部分读请求,只让少量请求穿透到Redis;二是热key复制,把同一个key写到多个分片,读请求随机打散;三是业务侧优化,比如把高频读改为读写合并、批量操作,用MGET、Pipeline减少网络往返次数,降低单条命令的处理开销。
同时检查客户端是否存在滥用短连接、没有开启连接池、频繁创建销毁连接的情况,这些都会额外消耗CPU。开启Pipeline能显著降低每条命令的固定开销,批量场景下吞吐可以提升数倍。
四、从数据结构与系统层面做优化
确认根因之后,优化可以从多个层面入手。数据结构层面,遵循正确的选型原则:存储少量字段用Hash而不是用多个String,因为Redis对小Hash有ziplist压缩编码,内存和CPU开销都更小。可以通过hash-max-ziplist-entries等参数调整编码阈值,让更多小对象走紧凑编码路径。
系统层面,确认是否开启透明大页THP,THP会导致fork时复制开销剧增,建议关闭。检查是否发生swap,内存交换会让每次访问都变慢,CPU反而可能因为等待而表现为异常。确认网卡是否有软中断集中问题,多队列网卡配合RPS可以把网络中断分散到多个CPU核心。
架构层面,读多写少的场景可以增加从节点做读写分离,把读流量分散出去。数据量增长到单机瓶颈时,迁移到Cluster模式做水平分片,但要注意设计好hash tag,避免分片倾斜。对于纯缓存场景,考虑开启maxmemory并设置合理的淘汰策略,控制实例规模在合理范围。
最后建立一个常态化的监控体系:对CPU使用率、QPS、慢查询数量、连接数、内存碎片率设置分级告警,保留历史数据用于容量规划。排查问题时的思路可以总结为:先看进程确认来源,再看慢日志找元凶,然后分析热key和QPS判断容量,最后从命令优化、数据结构、架构分层落地优化。按这个流程走一遍,绝大多数Redis CPU高问题都能定位并解决。
Redis CPU高Redis性能优化Redis排查修改时间:2026-09-08 22:29:08