Redis穿透本身不显慢,但会导致数据库雪崩、慢SQL激增;APM因未开启Spring Cache插件或未打点,常缺失redis.command节点,仅见jdbc.execute耗时飙升,结合db.connection.active持续95%以上可精准识别穿透。

Redis穿透导致的性能瓶颈,APM工具本身无法直接“发现穿透”,但能帮你快速锁定它引发的下游连锁反应——比如数据库雪崩、线程阻塞、慢SQL激增。关键不是看Redis本身是否被穿透,而是看穿透后谁扛不住了。
为什么redisCache.get()在APM里不显示慢,但整体接口却超时?
APM(如elastic-apm或华为云APM)默认只采集出站调用,redisCache.get()这类封装在框架里的缓存操作,若未显式开启Spring Cache插件或未打点,APM会把它当作普通Java方法,不记录耗时或失败状态。结果就是:Redis已大量miss、后端DB被打满,但APM链路图里Redis节点“一片空白”或只有毫秒级虚影。
- 检查你的APM Agent是否启用
spring-cache插件(elastic-apm需配置enable_experimental_instrumentations: true并加apm-spring-cloud-starter) - 确认缓存层是否用了
@Cacheable且key生成逻辑没出错(如参数为null导致所有请求命中同一key,看似命中率高,实则穿透) - 对比
http.request耗时和jdbc.execute耗时:若后者飙升而前者无Redis调用记录,大概率是缓存层被绕过或失效
slowlog get查不到慢命令,但APM里jdbc.execute全是2s+?
这恰恰是Redis穿透的典型信号:缓存没起作用,请求全落到DB。APM里看不到Redis慢命令,是因为根本没发给Redis——或者发了但返回null,业务代码直接查库。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 在APM的“慢URL”列表里,筛选出高耗时接口,下钻查看其调用栈:如果调用链里缺少
redis.command节点,只有jdbc.execute和http.client,说明缓存未命中或未执行 - 检查业务代码中是否有类似
if (cache == null) { loadFromDb(); }逻辑,且cache判空未考虑缓存击穿(如布隆过滤器缺失、空值未缓存) - 用
redis-cli --scan --pattern "user:*"验证key是否存在;再用client list观察连接数是否稳定——穿透时Redis连接数往往偏低(因为请求没到它那)
APM告警里redis.connected_clients正常,但db.connection.active持续95%以上
这个指标组合比单独看Redis更危险。它说明流量没卡在Redis,而是畅通无阻地冲进了数据库——穿透已发生,且DB正在成为瓶颈。
- 立即在APM中按“错误率+响应时间”双维度筛选服务,定位哪个接口的DB调用量突增(注意看
jdbc.url是否集中指向某张表) - 检查该接口对应的Redis key命名规则:是否含动态ID(如
user:12345),而恶意请求构造了海量不存在ID(如user:999999999),触发穿透 - 不要只依赖
info stats里的keyspace_hits/keyspace_misses——应用层可能做了二次判断(如空对象缓存1分钟),这些miss不会体现在Redis原生命中率里
真正容易被忽略的点:APM采样率默认是0.1或1%,低频穿透请求可能直接被丢弃,导致链路图里“什么都没发生”。务必在问题复现期临时调高transaction_sample_rate至1.0,并配合slowlog-log-slower-than 1000(单位微秒)抓取所有Redis命令,交叉验证。穿透不是Redis的问题,而是缓存策略和APM可观测性覆盖之间的断层。


















