排查缓存键设计漏洞需从生成逻辑、生命周期、分布特征三方面主动体检:检查键输入是否校验(防非法构造)、空结果是否缓存(防穿透)、大量键是否设置相同过期时间(防雪崩)。

排查缓存键设计中的穿透与雪崩漏洞,关键不是等出问题再救火,而是从键的生成逻辑、生命周期、分布特征三方面主动“体检”。很多故障表面是Redis或DB扛不住,根子在缓存键本身就没设计好防御性。
看键是否存在“非法构造”风险——防穿透的第一道门
穿透本质是无效请求绕过缓存直击数据库,而源头往往在键本身缺乏校验和过滤。
-
检查键的输入来源是否可控:比如
product:{id}中的id是前端传入?是否做过格式校验(如长度、字符集、数字范围)?未校验的字符串ID极易被遍历或随机拼接,形成穿透流量。 -
确认空结果是否写入缓存:查数据库返回
null或空集合时,代码是否执行了SET key "" EX 60这类空值缓存?漏掉这步,同一个无效ID反复请求就会持续穿透。 - 评估是否适合加布隆过滤器:若业务中存在明确的“全量有效ID集合”(如商品库、用户表主键),且更新频率不高(每天增量
看键的过期时间是否“扎堆”——防雪崩的底线意识
雪崩常源于大量key在同一秒内集体失效,而罪魁往往是人为设置的“整齐划一”的TTL。
-
扫描所有缓存写入点:搜索代码中所有
setex、expire、set(..., ex=3600)等调用,重点看是否对不同数据类型(如商品、订单、用户)使用了相同固定值(如全部设为3600秒)。 -
检查是否有“批量刷新”逻辑:比如定时任务统一重刷商品缓存,并给所有key设置相同过期时间。这种操作必须加随机偏移,例如
TTL = 3600 + random(0, 600),把集中过期打散到10分钟窗口内。 - 识别高危场景:缓存重建依赖外部接口(如调第三方API拉取配置)、或依赖数据库慢查询的key,一旦失败又没降级,容易引发连锁雪崩。这类key应单独设置更长TTL或启用本地缓存兜底。
看键的热度与失效是否“单点失控”——间接识别击穿隐患
虽然击穿针对单个热点key,但它的暴露往往反映键设计缺乏冗余保护。排查时可顺带关注:
-
统计TOP 100 key的QPS与TTL:用Redis的
INFO commandstats或监控平台查看哪些key访问量远超均值(如占总QPS 40%以上),再确认其TTL是否静态固定。这类key必须配互斥锁或逻辑过期方案。 -
检查key命名是否隐含热点倾向:比如
hot_topic:current、seckill:goods_1001这类明显服务高并发场景的key,不能只靠简单set/get,必须验证是否已有双层加载(先读缓存,miss则尝试加锁重建)逻辑。 - 验证缓存重建失败后的行为:当热点key过期后,重建线程抛异常或超时,是直接返回空/错误,还是保留旧值并延长TTL?后者能有效缓解击穿冲击,属于键设计的韧性考量。
不复杂但容易忽略:一次有效的键设计排查,不需要动全链路,只需聚焦“谁生成它、怎么过期、谁最常查它”三个问题,就能提前堵住大部分穿透与雪崩的口子。











