Skip to content

Redis 性能瓶颈时如何处理? ​

  • 标签:后端、Redis

🏛 业务架构师 ​

Redis 瓶颈处理我按定位→分类→治理的标准流程讲:

第一步:定位瓶颈类型(别急着加机器)

  • 慢日志(slowlog)+ latency 命令看慢命令;
  • info 的 instantaneous_ops、内存碎片率、持久化耗时(rdb_last_bgsave_status);
  • 机器层面:CPU 单核打满(Redis 是单核消费)、网络带宽、swap。

第二步:按根因分类治理

  • 慢命令/误用:keys *、smembers 十万大集合、复杂 Lua——换命令(scan 替代 keys、sscan 分页)、砍需求。多数"Redis 慢"其实是用法错;
  • bigkey:拆分(大 hash 按字段分段)、改结构、异步删除(UNLINK);
  • 热点 key:本地缓存(Caffeine)挡一层、key 加后缀打散多副本读;
  • 内存瓶颈:过期策略与淘汰策略核查、冷数据分析下线、结构优化(JSON 大 value 改 hash 分字段);
  • 持久化拖累:fork 停顿(内存太大)、AOF 刷盘策略权衡——缓存场景可放宽换性能,计数场景要保数据,按业务分级;
  • 网络/CPU 真 到顶:读写分离(从库扛读)、按业务垂直拆实例(成本最低的扩容)、最后才集群分片。

第三步:机制化预防:慢命令监控告警、bigkey 定期扫描(redis-cli --bigkeys)、容量水位线(70% 告警)、新需求评审时过"Redis 用法清单"。

核心观点:Redis 性能问题八成是使用方式问题,两成才是容量问题——先治用法(免费),再谈扩容(花钱),顺序反了就是拿预算补贴坏设计。

🏗 系统架构师 ​

Redis 性能瓶颈治理我按"定位 → 分类 → 处置"的标准排查路径答:

先定位(数据说话):

  • redis-cli --latency、SLOWLOG GET 看慢命令;INFO 看 instantaneous_ops、mem_fragmentation、latest_fork_usec;LATENCY HISTORY 定延迟尖刺;
  • bigkey 扫描(--bigkeys / rdb 分析)、hotkey 分析(--hotkeys 或客户端埋点)。

瓶颈分类与处置:

  1. 慢命令阻塞单线程:keys *、smembers 大集合、复杂 Lua → 换 scan、拆分、禁用;删除用 UNLINK;只读大操作放从库或用副本专门分析;
  2. big key:value 数十 MB 级 → 拆分(大 hash 按 field 哈希分片)、压缩、改设计;
  3. hot key:单 key QPS 十万级打满单分片 → 本地缓存(Caffeine 二级缓存)+ key 加随机后缀多副本分担读;
  4. 内存与持久化:内存到 swap、fork 耗时(RDB/AOF rewrite fork 毫秒到秒级尖刺)→ 控制实例 10GB 内、关透明大页、no-appendfsync-on-rewrite、换 SSD;
  5. 网络/CPU:带宽打满、连接数暴涨 → pipeline/批量、连接池收敛、拆集群;
  6. 达到单机上限:QPS 10 万常态 → 读写分离、Cluster 水平扩容,或前置本地缓存把 90% 读拦在进程内。

架构原则:Redis 优化优先级永远是"减少打到 Redis 的量(本地缓存)> 消除阻塞(bigkey/慢命令)> 扩容",加机器是最后一步。

💻 全栈开发专家 ​

我的排查 SOP,按顺序走:

1. 定位现象:redis-cli info + 慢日志:

bash
SLOWLOG GET 20                # 慢命令
redis-cli --latency           # 网络延迟基线
info commandstats             # 哪类命令耗时长(usec_per_call)

2. 常见瓶颈与对策:

  • 慢命令/bigkey:keys *、大集合 HGETALL/SMEMBERS、LRANGE 0 -1。换 SCAN/HSCAN 游标、拆 key;redis-cli --bigkeys 抽查 + RDB 离线分析。
  • CPU 单核打满:QPS 顶到单线程上限或 value 大导致协议处理重。6.0+ 开 io-threads;根治是 Cluster 水平扩分片,读写分离只救读。
  • 持久化抖动:大内存实例 fork 卡顿(info stats 的 latest_fork_usec)。控制单实例内存(10GB 内)、关 THP、必要时换 SSD。
  • 内存打满触发淘汰/阻塞:evicted_keys 增长、mem_fragmentation_ratio 异常 → 扩容或开 activedefrag。
  • 网络/网卡:大 value 高频读把带宽打满(netstat/监控看包量),压缩 value、就近部署。
  • 主从复制风暴:repl-backlog 溢出反复全量同步,调大 repl-backlog-size。

3. 兜底原则:Redis 出问题先保 DB 不被打穿——客户端限流 + 熔断降级(返回默认值),别让"缓存故障"升级成"全站故障"。