恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Redis性能优化实战:从大Key、热Key到持久化与连接池的完整排查指南

  • 首页
  • 资讯中心
  • /
  • Redis性能优化实战:从大Key、热Key到持久化与连接池的完整排查指南

相关资讯

陕西GogoAI自助健身小程序分销营销模块搭建 2026/10/16 12:08:05
陕西GogoAI自助健身小程序核销功能开发解析 2026/10/16 12:08:05
西安GogoAI健身系统开发流程,需求调研到上线部署 2026/10/16 12:08:05

最新资讯

需求工程实战:面谈与原型如何配合挖掘真实需求
火星交会任务轨道计算:从二体模型到Lambert转移与差分修正
Star Rat 3.1远控源码深度剖析:通信加密与二次开发实战
Argyll在Windows下生成显示器ICC配置文件的实战指南
C++作用域解析运算符:::化解变量隐藏与多态调用困局
管式土壤墒情监测仪:从介电常数到智慧灌溉的关键技术解析

今日推荐

Java八种基本类型深度解析:从内存布局到实战选型
基础:常用快捷键——IDEA、VS Code、PyCharm 与 Linux 终端效率速查
解决ultraedit下verilog .v文件中文注释乱码:把编码配置改到TaoToken辅助排查

本周热门

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

Redis性能优化实战:从大Key、热Key到持久化与连接池的完整排查指南

发布时间:2026/10/16 12:08:05
Redis性能优化实战:从大Key、热Key到持久化与连接池的完整排查指南 Redis用着用着突然从稳定的亚毫秒延迟变成几十毫秒甚至超时这种事我遇到太多次了。很多人的第一反应是加内存、加服务器但真正排查下来大部分性能问题都不是资源不够而是业务用法、配置参数和运维细节上出了问题。这篇文章不是教科书式的原理堆砌而是把我这些年折腾Redis性能优化的真实经验整理出来覆盖从大Key、热Key、持久化策略到客户端连接池、Pipeline、慢查询排查的完整链路适合正在维护Redis实例的开发者、运维同学也适合那些刚接手一个卡顿Redis实例、不知道从哪里下手的同学。内容以实践为主我会把每个优化方案背后的为什么讲清楚同时附上可以直接抄作业的命令和配置。1. 先搞清楚Redis到底可能卡在哪很多朋友一上来就问Redis变慢了怎么办这个问题其实没法直接回答因为变慢只是现象原因可能分布在完全不同的层面。根据我的经验大部分Redis性能问题都能归到四个层面当中。1.1 从一次线上故障说起先讲一个真实的案例方便大家理解排查思路。某公司的Redis实例每天上午10点到11点会出现明显的延迟尖刺平时平均0.5毫秒的读写延迟这段时间会飙升到80毫秒以上甚至偶尔报超时。最初团队以为是机器负载高连续加了两次内存问题一点没改善。后来我们用redis-cli --latency -h 实例地址 -p 6379 -i 1持续监控发现延迟尖刺是有节奏的每隔一段时间出现一次。再配合INFO命令查看latest_fork_usec参数发现每次延迟尖刺都跟着一次后台持久化任务的fork过程。顺着这个线索往下查定位到这个实例的RDB保存策略配置得太激进加上当时的业务流量本身就在上午有个高峰期每次fork都会造成一次较大的内存页复制开销把整个实例的响应拖慢了。这个案例想说明的是排查Redis性能问题第一步不是优化而是定位。如果连慢在哪个环节都没搞清楚做的很多优化都是白费力气。而定位的核心手段就是我后面会详细讲的慢查询日志、延迟监控、INFO命令这几板斧。1.2 性能排查的四个维度Redis是一个单线程模型处理命令的服务端程序指命令执行环节但一个请求从客户端发出到收到响应中间要经过网络传输、排队等待、命令执行、内存分配等多个环节。任何一个环节出问题表现都是变慢。根据我的经验可以把排查维度分成四个客户端与网络层连接数过多、连接池配置不合理、网络抖动、频繁新建连接。这一层的问题通常表现为所有命令都变慢包括最简单的PING。命令执行层慢查询、大Key操作、复杂命令如KEYS、SMEMBERS、ZRANGE大范围取值、阻塞命令如BLPOP、BRPOPLPUSH。这一层的问题通常表现为某个业务接口特别慢但PING正常。持久化与系统层RDB fork耗时、AOF刷盘阻塞、内存碎片过高、内存淘汰触发、Swap使用。这一层的问题表现为延迟周期性抖动。架构设计层单实例容量过大、热点Key过于集中、数据倾斜、分片不均。这一层的问题表现为整个集群或某个分片节点性能不均。后面几个大章我会围绕这四个维度逐个展开每个维度都给出识别手段和优化方案。记住一个原则从现象倒推从指标定位先别急着改配置。2. 最容易踩的坑大Key、热Key与慢命令这一章是全篇的精华因为根据我的观察日常生产环境里遇到的Redis性能问题十有七八都跟大Key和热Key有关。尤其在高并发场景下这两个问题的破坏力会成倍放大。2.1 大Key的危害与识别方法所谓大Key并不仅仅指字符串类型的大value还包括Hash、List、Set、ZSet等集合类型中元素数量过多、单个元素过大或整体内存占用偏高的key。一个包含几十万个元素的List或者一个value达到几MB的字符串都算大Key。大Key的危害主要有三个读写阻塞获取一个大Key需要遍历大量元素导致单次命令执行时间过长阻塞后续所有命令。网络拥塞一个大Key的value可能是几MB甚至几十MB每次读取都意味着巨大的网络传输开销容易把带宽打满。内存不均在集群模式下一个大Key会让某个分片的内存远高于其他分片造成数据倾斜。识别大Key最常用的方法就是用官方的redis-cli --bigkeys命令扫库。这个命令会以采样方式遍历键空间统计出各类数据类型中体积最大的几个key。注意它是采样扫描不是全量精确统计所以更适合快速摸底。如果想精确判断某个具体的key有多大用MEMORY USAGE key命令 MEMORY USAGE user:12345:cart (integer) 20480不过这个命令在key很大的时候本身也可能有性能开销生产环境建议在低峰期使用。还有一个我自己常用的方式后台用脚本定期扫描线上实例的key结合DEBUG OBJECT key命令查看序列化长度 DEBUG OBJECT user:12345:cart Value at:0x7f8b8c0e05a0 refcount:1 encoding:listpack serializedlength:18432 lru:12345 lru_seconds_idle:100看到serializedlength很大基本就可以判定是大Key。2.1.1 大Key的拆分方案找到大Key之后怎么处理直接删除会阻塞线上服务所以要分情况处理。对于集合类型的大Key可以在业务层做拆分。比如一个电商的购物车用户维度是user:12345:cart如果一个人购物车里放了几千件商品极端情况可以考虑拆成多个key按时间或者按商品类目做分段。比如拆成user:12345:cart:202501、user:12345:cart:202506这样的月份分桶读取时用多的聚合逻辑从多个分桶合并写入时根据当前时间落到对应的分桶。对于需要删除的大Key在Redis 4.0以上版本优先使用异步删除命令 UNLINK user:12345:cart (integer) 1UNLINK会先将key从键空间中摘除然后以异步方式释放内存不会阻塞主线程。如果用的是老版本Redis即使是用DEL也要分批次删除集合中的部分元素不要一次性全删。具体做法是用SSCAN、HSCAN、ZSCAN配合SREM、HDEL、ZREM分批清理。提醒在确认大Key可以删除之前先看看有没有业务还在读取。我见过不止一次开发把大Key删了第二天业务方怒气冲冲找过来因为那个key是另一个系统的数据源。2.2 热Key的识别与拆分方案热Key是指被大量请求同时命中的某个key。典型场景比如秒杀商品的库存key、微博热搜榜的key、某个爆款文章的点赞数key。单个key的访问QPS可能达到每秒几万甚至更高。热Key的危害比大Key更隐蔽因为它平时看起来很正常数据量不大但一旦流量集中到某个节点整个Redis实例的CPU会瞬间飙升其他所有命令都被拖慢。在集群模式下热Key还会造成某个分片过载而其他分片很空闲。识别热Key有几个办法在Redis 7.0及以上版本可以开启redis-cli --hotkeys命令底层依赖object freq信息它会统计访问频率最高的key。$ redis-cli --hotkeys # Scanning the entire keyspace to find hot keys as well as # related sizes...老版本Redis可以用MONITOR命令临时抓取一段时间内所有命令统计哪些key被频繁访问。但MONITOR会显著影响性能生产环境慎用建议只在低峰期短暂开启。更靠谱的方式是在客户端侧做统计。我给公司做的方案就是在封装好的Redis客户端工具类里对key做一次本地计数器采集5分钟内的访问分布再把TOP N上报到监控系统。这样完全不影响Redis服务端性能还能准确地感知热Key的实时变化。热Key的拆分思路和大Key不太一样。大Key是纵向拆细热Key是横向扩散。常见的做法加随机后缀把一个热Key复制成多个副本比如库存key从stock:1001拆成stock:1001:0到stock:1001:9十个副本请求随机落到其中一个副本上写操作时分摊到不同副本读操作任意读一个副本即可。注意这个方案要求业务可以容忍一定的数据不一致或者做写操作时全副本写入。本地缓存把热Key缓存到应用进程内设置一个很短的过期时间比如1到3秒由应用层自己管理缓存失效和更新。这是目前最推荐的做法因为Redis能承受的QPS再高也不如本地内存快。秒杀场景下用户请求先打到本地缓存真正落到Redis的请求量就被削掉了一个数量级。读写分离如果你的业务是一个热Key读多写少可以把读流量拆分到从节点。2.3 慢命令清单与替代方案Redis官方文档里标注为时间复杂度为O(N)的命令如果使用不当都是性能杀手。我从实战角度整理了一份高危命令清单排查慢查询时记得对照检查命令风险场景推荐替代方案KEYS pattern全库遍历所有key数据量大时直接卡死实例SCAN命令分批遍历或者维护key索引SMEMBERS key返回Set全部成员集合很大时阻塞明显SSCAN分批获取或按业务需求拆分SetHGETALL keyHash字段过多时同样存在阻塞风险HSCAN分批获取业务上兜底处理ZRANGE key 0 -1获取有序集合全量数据数据量大时慎用ZRANGEBYSCORE按范围查或LIMIT限制条数LRANGE key 0 -1获取List全量数据按范围分批获取不要让一个请求拉全量DEL key删除超大集合时阻塞主线程改用UNLINKRedis 4.0FLUSHALL / FLUSHDB清空库时瞬间产生海量内存释放I/O4.0以上版本使用ASYNC选项FLUSHALL ASYNCBLPOP / BRPOP阻塞式弹出阻塞期间该连接不能执行其他命令若非必须改用非阻塞版本加定时轮询补充一个很常见的优化案例原来业务用KEYS user:*去模糊匹配用户缓存数据量上来之后每次执行都会扫描整个键空间线上经常报警。后来我建议用SCAN 0 MATCH user:* COUNT 100分批迭代同时在业务写入时同步维护一个用户ID索引集合zset:user:index查询时先从索引取ID再逐个查key。实测慢查询数量下降了95%以上。还有一个容易忽略的点很多慢查询并不是命令本身慢而是因为客户端一次请求携带了过大的批量数据。比如有人一次性用MSET写入几万个字段或者一次性传入一个大对象的JSON序列化结果。这种请求即使单个命令执行时间不长网络传输和内存分配的压力也会传导到服务端。3. 持久化与内存配置被低估的性能杀手这一章聊的是Redis自身运行机制对性能的影响。很多开发者把Redis当纯缓存用随便配一下持久化就不管了结果到了数据量大或者流量高峰期Redis自己内部的fork、刷盘、内存淘汰机制反而成了最大的瓶颈。3.1 RDB与AOF的取舍Redis持久化有RDB和AOF两种方式它们的性能特征差异很大我需要把取舍逻辑讲清楚。RDB快照按配置的时间间隔生成全量数据快照。生成快照时要fork一个子进程子进程负责写文件父进程继续处理命令。这个fork过程在数据量大时会比较耗时因为虽然使用了操作系统的写时复制Copy On Write机制但fork瞬间需要复制父进程的页表数据量越大页表越大fork耗时越长。我见过一个40GB数据的实例fork一次耗时接近1秒期间所有命令都在等待。优化RDB的策略根据业务可以接受的丢失窗口调大save参数。比如原来每5分钟保存一次可以改成每15分钟一次减少fork频率。开启rdbcompression no如果CPU压力大而磁盘空间充足因为压缩会消耗大量CPU。尽量让RDB文件落到不同的物理磁盘避免和业务读写争抢同一个磁盘I/O。stop-writes-on-bgsave-error这个参数建议保持默认的yes这个配置可以在RDB写失败时让Redis停止写入避免主从数据差距拉到无法容忍的程度但是带来的影响就是业务写入会全部报错。适合能快速感知并处理故障的运维体系不够成熟的团队建议改为no防止线上大面积写入失败。AOF追加写入记录每一个写操作。性能关键在appendfsync参数的配置有三个选项always每次写命令都调用fsync最安全但最慢生产环境很少用。everysec每秒执行一次fsync兼顾性能和可靠性大多数场景的推荐选择。no由操作系统决定什么时候刷盘性能最高但异常断电时可能丢失较多数据。如果开启AOF后发现偶尔有延迟尖刺排查一下是不是磁盘负载过高导致每秒一次的fsync阻塞了主线程。可以看日志里有没有Asynchronous AOF fsync is taking too long这类告警。我的建议是如果Redis只是纯缓存可以不开持久化如果必须持久化优先RDB AOF everysec的组合拳不要用always模式除非你的业务完全无法容忍任何数据丢失。3.2 内存碎片与哈希编码优化Redis内存分配用的是系统内存分配器jemalloc它在频繁操作和大量过期key释放之后会产生内存碎片。内存碎片率可以通过INFO memory查看 INFO memory # Memory used_memory:1024000000 used_memory_human:1024.00M used_memory_rss:1536000000 used_memory_rss_human:1536.00M mem_fragmentation_ratio:1.50mem_fragmentation_ratioused_memory_rss / used_memory。正常情况下这个值在1.0到1.5之间都算合理。如果超过1.5说明内存碎片比较严重额外占用了大量物理内存。如果这个值小于1说明部分内存被换到了Swap上性能会急剧下降这是更危险的情况。处理碎片有三个办法开启自动内存碎片整理功能4.0以上版本配置activedefrag yes。注意这个功能本身会占用CPU资源适合低峰期使用。定时在低峰期执行memory purge只对jemalloc有效回收空闲页。备份数据后重启Redis实例这是终极手段让内存分配器重新整理布局。重启前务必确认实例是主节点还是从节点以及切换方案。另外还有一个容易被忽略的点小对象编码优化。Redis内部对Hash、List、Set、ZSet等类型做了小对象压缩编码。比如Hash对象在字段数量少且每个字段值短时会使用ziplist编码而不是hashtable编码能节省大量内存。这个效果可以通过CONFIG GET hash-max-ziplist-entries查看默认阈值。如果业务上字段数通常不超过几十个建议保持默认阈值不要把它调得过大因为ziplist编码虽然省内存但在更新元素时如果触发转换会有额外的扩容和重写开销。3.3 maxmemory与淘汰策略的力学原理当一个Redis实例达到maxmemory限制后如果配置了maxmemory-policyRedis会执行内存淘汰策略。很多人对淘汰策略的选择比较随意实际上这里的选择直接影响线上性能。maxmemory-policy常见的几个选项noeviction默认策略内存满了之后不淘汰任何key写命令直接返回错误。适合严禁丢数据的场景。allkeys-lru从所有key里按LRU最近最少使用淘汰。适合缓存场景。volatile-lru只在设置了过期时间的key中按LRU淘汰。适合同时有缓存数据和持久化数据的混合场景。allkeys-random随机淘汰所有key适合所有key被访问概率均等的场景。volatile-ttl在设置了过期时间的key中优先淘汰剩余存活时间最短的key。我推荐缓存类业务用allkeys-lru。但要说一个坑LRU算法在Redis里是近似实现通过采样默认采样5个key来近似判断哪些key最久没访问。如果实例里key数量特别多访问热点又很集中建议把采样的数量调大 CONFIG SET maxmemory-samples 10采样的数量越大越接近真正的LRU语义但淘汰时消耗的CPU也会越高。10个采样通常是性价比不错的折中。如果内存淘汰发生后线上依然频繁出现延迟抖动要重点检查一个现象大量设置了相同过期时间的key在同一时刻集中过期。比如一批缓存key都设置了600秒过期间隔上线时间又一致那么每隔10分钟就会有一波过期风暴。这会导致Redis在短时间内疯狂释放内存CPU和I/O瞬间拉高。解决方式很简单在设置过期时间时引入随机偏移SET cache:user:12345 value EX 600 # 优化为 SET cache:user:12345 value EX 600 random(0, 60)另外Redis 4.0以上版本提供了lazyfree-lazy-expire yes配置开启后过期key的内存释放会改为异步能明显减轻过期风暴对主线程的阻塞。这个配置我建议在流量较大的实例上直接开启。4. 客户端与网络层从连接池到Pipeline说句得罪人的话很多Redis性能问题压根不是Redis服务端的问题而是客户端用错了。每次请求新建连接、连接数过多导致文件描述符耗尽、小命令频繁交互都会让整个系统的吞吐量上不去。这一章重点讲客户端侧的优化技巧。4.1 连接池配置的常见误区Redis服务端处理单个命令很快但如果有大量连接在同时请求线程调度和上下文切换的开销就会成为瓶颈。一个空转的连接本身消耗不大但连接数从几百涨到几千时CPU消耗会明显上升。所以第一件要做的事是使用连接池复用长连接避免每次请求新建连接。几乎所有主流语言的Redis客户端库都提供了连接池能力。以Java的Lettuce客户端为例我建议的初始配置思路maxTotal不要盲目调大连接数够用就行。可以根据Peak QPS和单个连接的处理能力估算。如果每条命令平均耗时0.5ms单个连接的极限大约是2000 QPS那么10000 QPS的业务流量大概需要5到10个连接留出一定余量设成20个就足够了。maxIdle跟maxTotal一致或略低保持池子稳定。minIdle建议设置成能应对突发流量洪峰的数值避免瞬间大量请求触发连接重建。maxWait获取连接的超时时间不建议太长否则请求会排队堆积一般200到500毫秒即可。testOnBorrow如果对连接的健康检查要求高可以开启但会多一次PING命令的开销性能敏感的实例建议关闭改用后台定期探测。连接池还有一个常见问题空闲连接被服务端超时回收后客户端还在使用导致偶发性命令失败。所以在客户端设置合理的timeout之外也要关注Redis服务端的timeout配置。服务端timeout是指空闲连接的关闭时间默认是0表示不关闭如果被设成了300秒那么连接空闲超过300秒就会被服务端关闭。客户端的连接池最好开启空闲连接检测把空闲连接主动清理掉。4.2 Pipeline与批量操作的正确姿势很多人用Redis时习惯一条一条地发命令高并发场景下每条命令的网络往返时间RTT累加起来会非常可观。尤其是跨机房调用一次RTT可能就有5到10毫秒循环执行100条命令光网络等待就要500到1000毫秒。Pipeline管道技术可以一次性批量发送多条命令减少网络往返次数。但Pipeline也不是随便就能用好的有几个细节要特别注意Pipeline会占用一条连接在Pipeline执行期间这条连接不能处理其他请求所以Pipeline的批大小要适度。我一般建议每个批次控制在100到500条命令之间具体取决于命令复杂度。Pipeline不是事务执行过程中如果有其他客户端穿插写入Pipeline中的命令可能不会连续执行。如果需要原子性依然要用MULTI/EXEC或者Lua脚本。Pipeline批量操作时如果一批命令里有一条执行失败不会影响其他命令执行所以业务上要做好结果校验。如果业务场景是一次请求需要执行多条Redis命令优先尝试把逻辑合并成Lua脚本。Lua脚本在Redis服务端执行天然是原子的还省掉了多次网络往返。比如扣库存这个场景用Lua脚本可以同时完成检查库存、扣减数量、记录操作日志整个流程只需要一次网络交互。-- 扣库存Lua脚本 local key KEYS[1] local decrBy tonumber(ARGV[1]) local current tonumber(redis.call(GET, key)) if not current or current decrBy then return -1 end redis.call(DECRBY, key, decrBy) return current - decrBy用EVAL命令执行这段脚本服务端会加载脚本并原子执行。实测下来原本10条命令的流程合并为一次命令后接口性能提升了4倍以上。4.3 合理使用读写分离与多实例读写分离的核心思路把读流量从主节点分散到从节点。但要注意Redis主从复制是异步的从节点数据可能比主节点旧几毫秒甚至更久。如果业务对强一致有要求比如读到用户刚提交的数据就不能走从节点。读写分离的前提是业务上可以容忍短时间的数据不一致。读流量远大于写流量。有多个从节点可以分担读压力。部署上在客户端侧做读写分离的规则区分把写操作和强一致读操作路由到主节点把弱一致读操作路由到从节点。不要在主从节点之间做自动故障转移的逻辑那是Sentinel或者集群管理器该做的事。如果单实例的CPU已经长期高于80%即使在做了热Key拆分、慢命令优化之后还是撑不住那就要考虑架构层面的横向扩展。两个方向集群模式Redis Cluster数据自动分片到多个主节点每个主节点可以有从节点。注意热点Key在cluster模式下依然会造成数据倾斜需要结合前面讲的本地缓存方案。多实例部署同一个业务按一定的维度用户ID、店铺ID分片到多个Redis实例。这个方案比较灵活但在客户端要多一层路由逻辑。我遇到过一个案例某系统把所有的session数据都放到了同一个Redis实例上用户量增长后这个实例的CPU经常打到90%以上。后来按用户ID取模拆到4个Redis实例上每个实例的CPU直接降到了30%以下。多实例部署虽然要维护的节点变多了但在Redis Cluster还不够成熟的业务场景下往往是最简单有效的横向扩展手段。5. 性能排查工具与监控指标线上故障的照妖镜优化做得再多如果没有一套完善的排查工具和指标意识线上出了问题还是两眼一抹黑。这一章把我日常排查性能问题最常用的工具和指标整理成清单每个工具的使用场景、命令格式、关键输出都写清楚。5.1 慢查询日志与Redis Latency MonitorRedis自带慢查询日志功能它记录的是命令执行耗时超过阈值的情况默认是不开启的。建议在配置文件中设置slowlog-log-slower-than 10000 slowlog-max-len 128slowlog-log-slower-than的单位是微秒10000即10毫秒。生产环境建议设成10001毫秒因为Redis命令的正常耗时应该在微秒级别超过1毫秒就值得关注了。如果设得太低慢查询日志可能被刷屏可根据实际情况调整。查看慢查询日志 SLOWLOG GET 100 SLOWLOG LEN SLOWLOG RESETSLOWLOG GET 100会返回最近100条慢查询记录内容包括命令执行的时间戳、耗时、命令参数等。SLOWLOG RESET用于清空慢查询日志建议每次排查完一个周期后清空一次方便下一轮观察。Redis Latency Monitor是另外一个好用的内置监控工具通过CONFIG SET latency-monitor-threshold 100开启它会记录超过指定毫秒数的延迟事件 CONFIG SET latency-monitor-threshold 100 LATENCY LATEST LATENCY HISTORY command LATENCY RESETLATENCY LATEST会列出最近触发的延迟事件类型和延迟峰值包括fork、expire-cycle、eviction-cycle、aof-write-pending-fsync等。比如看到fork事件的延迟高就说明RDB持久化的fork耗时过长需要调整save参数或者减少单实例数据量。5.2 INFO命令的关键指标速查INFO命令的输出非常多但排查性能问题时我只看几个关键字段输出段字段关注原因Serveruptime_in_seconds实例运行时长如果刚重启过数据加载和缓存预热可能影响性能Memoryused_memory_rss/used_memory计算内存碎片率以及判断是否用了SwapMemorymem_fragmentation_ratio超过1.5需要处理碎片小于1需要排查SwapMemoryevicted_keys如果持续增长说明内存不足淘汰策略触发频繁Statstotal_commands_processed每秒处理命令数与instantaneous_ops_per_sec对照看负载Statsexpired_keys如果出现周期性激增需要检查过期时间是否集中Persistencerdb_bgsave_in_progress是否正在进行RDB保存配合latest_fork_usec确认fork耗时Persistenceaof_pending_bio_fsyncAOF后台fsync队列如果数值持续增长说明刷盘跟不上写入Clientsconnected_clients连接数突增往往是延迟升高的前兆Replicationmaster_repl_offset/slave_repl_offset主从复制差距差距过大会导致从节点数据严重滞后每次排查性能问题前先抓一组INFO all的快照保存下来隔几分钟再抓一组对比关键字段的变化趋势比看单个时刻的值更能说明问题。5.3 redis-cli与第三方工具实测除了内置命令我强烈建议把这几个mysql-cli的变体命令用起来# 实时延迟采样 redis-cli --latency -h 127.0.0.1 -p 6379 # 延迟历史分布 redis-cli --latency-history -h 127.0.0.1 -p 6379 -i 2 # 周期内最大延迟 redis-cli --latency-dist -h 127.0.0.1 -p 6379--latency会在终端持续输出平均延迟和最大延迟对于判断当前是否正在发生延迟问题非常直观。--latency-dist以柱状图形式展示延迟分布能看出延迟主要集中在哪个区间对分析延迟尖刺非常有帮助。第三方工具方面我用得比较多的是redis-rdb-tools可以离线解析RDB文件分析key的内存占用、过期时间分布、前缀统计等最适合做全量体检不会影响线上实例。redis_exporter配合监控平台使用可以把Redis的指标持续采集并展示设置告警规则。我建议重点监控的指标包括内存碎片率、慢查询数量、命令处理速率、连接数、主从复制偏移量差距。还有一个小技巧用redis-cli --stat持续输出实时状态。它会以每秒一次的频率输出内存、连接数、每秒命令数、命中率等关键指标线上问题定位时比反复执行INFO要高效得多。6. 常见问题速查表与排查流程实操到了这一章我把前面所有的经验浓缩成一份可以直接对照使用的速查表和一个标准排查流程。排查问题的时候建议对着这个清单逐步打钩而不是凭感觉乱试。6.1 常见性能问题的症状与解决方案速查症状可能原因排查手段解决方案所有命令延迟全线升高网络问题、连接数过高、实例负载过高、磁盘I/O阻塞--latency、INFO clients、查看系统负载检查网络链路优化连接池横向扩容仅部分命令变慢慢查询、大Key、复杂命令SLOWLOG、--bigkeys、MEMORY USAGE优化命令用法拆分大Key改用异步删除延迟周期性抖动RDB fork、AOF刷盘、过期风暴LATENCY LATEST、INFO persistence调整持久化策略开启lazyfree过期时间加随机偏差CPU利用率高但吞吐量低热Key、复杂计算命令、内存碎片整理--hotkeys、MONITOR低峰短开热Key拆分、本地缓存、调整activedefrag时段内存持续增长且淘汰频繁maxmemory不足、大Key堆积INFO memory、evicted_keys调大内存优化淘汰策略清理大Key主从数据严重不一致主节点写入压力大、网络拥塞INFO replication中的偏移量差值优化主节点写入检查网络考虑架构拆分重启后性能恢复但慢慢又变慢内存碎片、热点数据不均衡观察mem_fragmentation_ratio曲线定期清理碎片调整业务层key设计这张表不是万能的但它覆盖了我生产中遇到的大部分问题场景。如果症状不在表里那就要靠后面的标准化流程来兜底。6.2 一套我长期使用的排查流程每次接到Redis性能告警我会按下面的流程走已经被验证过很多次可以帮你在最短时间内定位问题根因。第一步确认现象范围。先看是哪个业务方反馈变慢是所有操作都慢还是只有某些特定指令慢。用redis-cli --latency做一个1分钟的采样记录平均延迟和最大延迟。同时问一下业务方这个变慢是突发的还是持续了有一段时间如果持续已久可能是容量规划问题如果刚刚突发多半跟最近的变更有关。第二步抓服务端指标。执行INFO all记录快照重点关注used_memory、mem_fragmentation_ratio、total_commands_processed、expired_keys、latest_fork_usec、evicted_keys这几个值。隔5分钟再看一次对比变化量。如果evicted_keys在涨说明内存淘汰正在频繁触发如果latest_fork_usec很大说明持久化fork是元凶。第三步查慢查询。执行SLOWLOG GET 50看最近的慢查询都有什么命令、什么key、耗时多少。如果慢查询集中在几个key上那基本上可以锁定大Key或热Key问题。注意SLOWLOG记录的是命令执行耗时超过阈值的情况但如果是网络延迟导致的慢慢查询日志里是看不到的所以第二步的延迟测试不能省。第四步查客户端侧。如果服务端一切正常那问题多半在客户端。看客户端连接池是否有大量连接创建/销毁、是否有长时间GC停顿、是否有跨机房的RTT过高。有时候问题根本不在Redis而是应用服务器自身的Full GC导致的我们却一直在Redis这边瞎忙活。第五步做验证性优化。根据前面的结论选择一个风险最低的优化方案先落地。比如调整某个命令用法、删除某个大Key、调整持久化配置然后持续观察延迟和吞吐量。每次只改一个变量不要同时改多个否则无法判断是哪个改动起了作用。6.3 一些值得长期坚持的运维习惯这篇文章最后我想分享几个在实际运维中总结出来的习惯算不上什么高深技术但长期坚持下来能减少很多不必要的线上事故。日常巡检的习惯。每周至少用redis-cli --bigkeys和redis-cli --hotkeys做一次轻量级巡检配合INFO memory记录数据趋势。不用等出了问题再排查很多大Key和热Key在规模还没爆掉之前就能提前发现。说实话这个习惯帮我避免过至少三次线上事故。变更管理要做。所有涉及Redis的变更包括配置调整、客户端代码升级、持久化策略修改都需要先在低峰期做一个轮次的验证确认无异常后再推向全量。特别是如果项目里有人建议把maxmemory-policy从默认的noeviction修改成allkeys-lru一定先想想会不会有需要长期保留的数据被误淘汰评估清楚了再动。预留性能余量。内存使用率不要等到90%以上才扩容CPU使用率不要等到长期80%以上才优化。Redis的优势就是快一旦资源使用率偏高延迟和抖动就会明显起来。在生产环境里我给团队定的红线是内存使用率不超过70%CPU峰值不超过60%慢查询数每天为0大Key数量为0。超过这些红线就要主动安排优化而不是等出故障再救火。从业务设计层面减少对Redis的依赖。这可能是最能体现经验的地方。很多时候Redis性能问题并不是Redis不够强而是业务把太多的计算和存储压力都放到了Redis上。比如无脑把数据库的行数据整份塞进Redis导致缓存占用过大、淘汰频繁又比如在Redis里做复杂的聚合计算这些逻辑用数据库或者应用层做会更合适。合理设计缓存粒度、缓存过期策略、读写比例让Redis做它最擅长的事性能问题自然少了一半。Redis性能优化是一条需要持续迭代的路没有一劳永逸的方案。但只要掌握了定位问题的思路、熟练使用排查工具、理解每个配置项背后的代价就能在性能问题刚冒头的时候把它按下去。希望这篇总结能成为你排查Redis性能问题时的趁手工具下次再遇到Redis突然变慢的告警先深呼吸按流程一步步来。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号