1. 课程导入与问题界定
在开始讨论任何治理手段之前,我们需要先把问题说清楚。很多团队在遇到Redis性能抖动或数据库压力飙升时,第一反应是“加机器”或“加缓存”,但如果没有准确界定问题类型,扩容往往只是把故障推迟几分钟。本章的目标是建立一张全课的问题地图:分清热点数据与缓存穿透这两类高频问题的定义、典型表现、业务影响,以及它们各自对应的治理方向。
一、两类问题的本质区别
热点数据指的是在短时间内被大量请求集中访问的少量键。它的本质是访问量分布极度不均:可能全站有上千万个键,但某一秒内80%的请求都打在同一个键上。典型场景包括:秒杀商品的库存键、明星突发热点事件的详情键、大促期间某个爆款SKU的价格键。热点键本身是存在且有效的,问题出在访问它的流量太大,超过了单个Redis分片或单个节点的处理能力。
缓存穿透指的是请求查询的数据在缓存和数据库中都不存在。每次这类请求都会绕过缓存直接打到数据库,如果被恶意利用或程序逻辑有缺陷,就会形成持续的高并发无效查询。它的本质是查询目标不存在,缓存无法形成有效拦截。典型场景包括:用不存在的用户ID反复查询、爬虫遍历不存在的商品编号、攻击者构造随机ID压测接口。
两者的关键差异可以用一句话概括:热点是“有数据但访问太集中”,穿透是“没数据但请求不断来”。前者考验的是单点承载与流量分散能力,后者考验的是无效请求的拦截与快速失败能力。
二、为什么必须区分这两类问题
区分热点与穿透,直接决定了治理手段的选择。如果误把热点当穿透处理,比如给热点键加空值缓存或布隆过滤器,不仅无效,还会浪费内存和计算资源;反过来,如果误把穿透当热点处理,比如给不存在的键做本地缓存或键拆分,同样无法阻止无效请求持续打到数据库。
更隐蔽的情况是两者同时发生。例如大促期间,某个爆款商品是热点键,同时攻击者用大量不存在的商品ID发起穿透请求。此时系统既面临单点热点压力,又面临数据库无效查询压力,需要同时启用两类治理策略。因此,建立清晰的问题分类意识,是后续所有治理工作的前提。
三、业务影响的量化视角
为了更直观地理解两类问题的破坏力,我们可以从三个维度观察:
- 响应时间:热点键导致单分片延迟从1ms升至50ms以上;穿透导致数据库查询从5ms升至200ms以上,且随并发量线性恶化。
- 吞吐量:热点键使单分片QPS达到瓶颈后不再增长,整体吞吐受限于最慢分片;穿透使数据库连接池耗尽后,所有查询排队等待。
- 可用性:热点问题通常表现为局部性能下降,穿透问题若持续升级,可能直接导致数据库不可用,进而引发全站故障。
注意:热点和穿透都不是“缓存本身的问题”,而是访问模式与缓存策略不匹配的问题。Redis作为缓存层,其设计假设是访问分布相对均匀、查询目标大概率存在。当这两个假设被打破时,问题就会暴露。
四、全课问题地图与治理目标
基于以上界定,本课程将围绕两条主线展开:热点数据治理线和缓存穿透治理线。每条线都遵循“探测→拦截→分散→兜底”的递进逻辑。
热点线的治理目标是:将集中访问分散到多个节点或本地缓存,使单点压力可控,同时保证数据一致性在可接受范围内。穿透线的治理目标是:在请求到达数据库之前完成无效拦截,使数据库只处理真实存在的查询。
两条线最终汇聚到一个共同目标:让Redis和数据库各自处理其最擅长的请求,避免任何一层被异常流量击穿。后续章节将分别深入热点探测算法、本地缓存实现、布隆过滤器参数设计、空值缓存TTL策略、限流熔断配置等具体技术手段,并给出可落地的代码示例和参数建议。
学习建议:在阅读后续章节时,请始终带着两个问题:这个手段解决的是“访问集中”还是“查询不存在”?它适用于读多写少还是读写均衡场景?只有把手段和问题类型对应起来,才能在实际系统中做出正确选择。
本章建立了全课的问题地图。接下来,我们将从热点数据的探测开始,逐步展开每一类问题的具体治理方案。