[{"data":1,"prerenderedAt":407},["ShallowReactive",2],{"blog-ha-cache-penetration-breakdown":3},{"id":4,"title":5,"body":6,"category":394,"date":395,"description":396,"extension":397,"meta":398,"navigation":399,"path":400,"seo":401,"stem":402,"tags":403,"__hash__":406},"blog\u002Fblog\u002Fha-cache-penetration-breakdown.md","缓存穿透与缓存击穿：场景与解决方案",{"type":7,"value":8,"toc":366},"minimark",[9,13,26,31,38,42,55,58,69,73,80,83,94,97,108,112,116,124,128,136,139,143,156,159,167,171,179,183,187,195,198,210,214,222,225,229,241,245,253,257,312,316,319,346,349,353,359],[10,11,5],"h1",{"id":12},"缓存穿透与缓存击穿场景与解决方案",[14,15,16,17,21,22,25],"p",{},"在高并发系统里，缓存是保护数据库和提升延迟表现的关键组件。但当缓存层被异常流量或热点流量冲击时，常见问题主要有两个：",[18,19,20],"strong",{},"缓存穿透","与",[18,23,24],{},"缓存击穿","。这两个问题经常被混用，治理策略也容易配错。本文聚焦实战场景，给出可直接落地的处理方案。",[27,28,30],"h2",{"id":29},"一缓存穿透是什么","一、缓存穿透是什么",[14,32,33,34,37],{},"缓存穿透是指：请求的数据在缓存中不存在，在数据库中也不存在。",[35,36],"br",{},"\n如果系统不做防护，这类请求每次都会直接打到数据库。",[39,40,41],"h3",{"id":41},"典型场景",[43,44,45,49,52],"ul",{},[46,47,48],"li",{},"恶意请求随机 ID（如订单号、用户 ID），持续查询不存在的数据。",[46,50,51],{},"业务参数校验弱，允许大量非法 key 进入查询链路。",[46,53,54],{},"爬虫流量异常，触发海量无效查询。",[39,56,57],{"id":57},"风险",[43,59,60,63,66],{},[46,61,62],{},"数据库 QPS 被无效请求吞噬。",[46,64,65],{},"业务正常请求受影响，延迟抖动明显。",[46,67,68],{},"在峰值期可能引发雪崩式连锁故障。",[27,70,72],{"id":71},"二缓存击穿是什么","二、缓存击穿是什么",[14,74,75,76,79],{},"缓存击穿是指：某个",[18,77,78],{},"热点 key","在高并发下突然过期，大量并发请求同时回源数据库，形成瞬时冲击。",[39,81,41],{"id":82},"典型场景-1",[43,84,85,88,91],{},[46,86,87],{},"秒杀商品详情、热门活动页配置、高频用户信息等热点数据设置了固定 TTL。",[46,89,90],{},"同一时间点过期，导致大量请求并发回源。",[46,92,93],{},"热点 key 重建逻辑耗时较长，窗口期内数据库压力激增。",[39,95,57],{"id":96},"风险-1",[43,98,99,102,105],{},[46,100,101],{},"数据库或下游服务瞬时打满。",[46,103,104],{},"应用线程池阻塞，出现超时和级联失败。",[46,106,107],{},"热点请求成功率下降，影响核心链路转化。",[27,109,111],{"id":110},"三缓存穿透解决方案","三、缓存穿透解决方案",[39,113,115],{"id":114},"_1参数与权限前置校验","1）参数与权限前置校验",[43,117,118,121],{},[46,119,120],{},"对 ID 格式、长度、业务范围做强校验，不合法直接返回。",[46,122,123],{},"对高风险接口加签名校验或鉴权，减少恶意流量直达业务层。",[39,125,127],{"id":126},"_2布隆过滤器bloom-filter","2）布隆过滤器（Bloom Filter）",[43,129,130,133],{},[46,131,132],{},"在缓存前增加布隆过滤器，快速判断 key 是否“可能存在”。",[46,134,135],{},"对明显不存在的 key 直接拦截，避免穿透到数据库。",[14,137,138],{},"适用点：高并发读场景、数据集合相对稳定、可接受少量误判（误判存在但实际不存在）。",[39,140,142],{"id":141},"_3缓存空值negative-cache","3）缓存空值（Negative Cache）",[43,144,145,153],{},[46,146,147,148,152],{},"数据库查询为空时，也写入缓存（如写入 ",[149,150,151],"code",{},"NULL"," 标记，短 TTL）。",[46,154,155],{},"相同无效请求命中空值缓存，不再反复回源。",[14,157,158],{},"注意点：",[43,160,161,164],{},[46,162,163],{},"TTL 不宜过长，避免影响数据新增后的可见性。",[46,165,166],{},"对空值命中率做监控，识别异常流量模式。",[39,168,170],{"id":169},"_4限流与熔断","4）限流与熔断",[43,172,173,176],{},[46,174,175],{},"针对不存在 key 的请求增加单接口限流、IP 维度限流。",[46,177,178],{},"下游压力过高时启用熔断降级，保护核心服务可用性。",[27,180,182],{"id":181},"四缓存击穿解决方案","四、缓存击穿解决方案",[39,184,186],{"id":185},"_1热点-key-互斥重建singleflight-分布式锁","1）热点 key 互斥重建（SingleFlight \u002F 分布式锁）",[43,188,189,192],{},[46,190,191],{},"对热点 key 回源重建加互斥：同一时刻仅允许一个请求回源。",[46,193,194],{},"其他请求等待或返回旧值，避免并发打库。",[14,196,197],{},"工程实践：",[43,199,200,207],{},[46,201,202,203,206],{},"单机可用本地互斥（如 ",[149,204,205],{},"singleflight"," 思路）。",[46,208,209],{},"分布式场景可用 Redis 锁，但要控制锁超时和兜底逻辑。",[39,211,213],{"id":212},"_2逻辑过期-异步刷新","2）逻辑过期 + 异步刷新",[43,215,216,219],{},[46,217,218],{},"缓存值中存储逻辑过期时间，读到“过期”数据时先返回旧值。",[46,220,221],{},"后台异步触发刷新，避免同步请求阻塞和回源风暴。",[14,223,224],{},"适用点：对“短时间读到旧值”可容忍的业务（如推荐、榜单、详情页）。",[39,226,228],{"id":227},"_3ttl-随机化","3）TTL 随机化",[43,230,231,238],{},[46,232,233,234,237],{},"给同类 key 的 TTL 加随机抖动（如 ",[149,235,236],{},"baseTTL + random(0, x)","）。",[46,239,240],{},"避免大量 key 同时过期造成脉冲式回源。",[39,242,244],{"id":243},"_4热点预热","4）热点预热",[43,246,247,250],{},[46,248,249],{},"在活动开始前预加载热点数据到缓存。",[46,251,252],{},"对已识别热点提前刷新，减少首次请求回源。",[27,254,256],{"id":255},"五两类问题的对比速记","五、两类问题的对比速记",[258,259,260,275],"table",{},[261,262,263],"thead",{},[264,265,266,271,273],"tr",{},[267,268,270],"th",{"align":269},"left","维度",[267,272,20],{"align":269},[267,274,24],{"align":269},[276,277,278,290,301],"tbody",{},[264,279,280,284,287],{},[281,282,283],"td",{"align":269},"数据是否存在",[281,285,286],{"align":269},"缓存和数据库都不存在",[281,288,289],{"align":269},"数据存在，但热点 key 过期",[264,291,292,295,298],{},[281,293,294],{"align":269},"压力来源",[281,296,297],{"align":269},"大量无效请求",[281,299,300],{"align":269},"热点并发请求",[264,302,303,306,309],{},[281,304,305],{"align":269},"核心手段",[281,307,308],{"align":269},"布隆过滤器、空值缓存、强校验",[281,310,311],{"align":269},"互斥重建、逻辑过期、TTL 随机化",[27,313,315],{"id":314},"六推荐落地组合实战","六、推荐落地组合（实战）",[14,317,318],{},"对于电商\u002F资金等高并发场景，可采用分层策略：",[320,321,322,328,334,340],"ol",{},[46,323,324,327],{},[18,325,326],{},"入口层","：参数校验 + 风险限流。",[46,329,330,333],{},[18,331,332],{},"缓存层","：空值缓存 + TTL 随机化。",[46,335,336,339],{},[18,337,338],{},"热点层","：互斥重建（SingleFlight\u002F分布式锁）+ 异步刷新。",[46,341,342,345],{},[18,343,344],{},"观测层","：监控空值命中率、热点 key 回源次数、数据库慢查询与错误率。",[14,347,348],{},"这样可以同时解决“无效请求冲击”和“热点过期风暴”两类问题。",[27,350,352],{"id":351},"七结语","七、结语",[14,354,355,356,358],{},"缓存问题本质上不是“加个 Redis 就结束”，而是流量模型、数据模型与系统韧性的综合工程。",[35,357],{},"\n把缓存穿透和缓存击穿区分清楚，再按业务特征做组合治理，才能在高峰场景下稳定地保护核心链路。",[14,360,361],{},[362,363,365],"a",{"href":364},"\u002Fblog\u002F","返回博客列表",{"title":367,"searchDepth":368,"depth":368,"links":369},"",2,[370,375,379,385,391,392,393],{"id":29,"depth":368,"text":30,"children":371},[372,374],{"id":41,"depth":373,"text":41},3,{"id":57,"depth":373,"text":57},{"id":71,"depth":368,"text":72,"children":376},[377,378],{"id":82,"depth":373,"text":41},{"id":96,"depth":373,"text":57},{"id":110,"depth":368,"text":111,"children":380},[381,382,383,384],{"id":114,"depth":373,"text":115},{"id":126,"depth":373,"text":127},{"id":141,"depth":373,"text":142},{"id":169,"depth":373,"text":170},{"id":181,"depth":368,"text":182,"children":386},[387,388,389,390],{"id":185,"depth":373,"text":186},{"id":212,"depth":373,"text":213},{"id":227,"depth":373,"text":228},{"id":243,"depth":373,"text":244},{"id":255,"depth":368,"text":256},{"id":314,"depth":368,"text":315},{"id":351,"depth":368,"text":352},"高可用架构","2026-03-15","在高并发系统里，缓存是保护数据库和提升延迟表现的关键组件。但当缓存层被异常流量或热点流量冲击时，常见问题主要有两个：缓存穿透与缓存击穿。这两个问题经常被混用，治理策略也容易配错。本文聚焦实战场景，给出可直接落地的处理方案。","md",{},true,"\u002Fblog\u002Fha-cache-penetration-breakdown",{"title":5,"description":396},"blog\u002Fha-cache-penetration-breakdown",[404,24,20,405],"缓存","高可用","Wau3D-d6U-fSKPqQ1Pp0_w92OxnU5mFHt3HB5iKGD2o",1779959652932]