跳到主要内容

缓存穿透

2025年01月05日
柏拉文
越努力,越幸运

一、认识


缓存穿透 是指请求的数据既不在缓存中,也不在数据库中 (请求的数据根本不存在),导致请求直接穿透缓存访问数据库,导致后端数据库压力剧增。通常是恶意攻击或查询不存在的 key

二、定位


我们收集指定接口总调用数、Redis 缓存层 命中数、存储层命中数在一定时间范围内的数据,我们就可以定位到是否有这 缓存穿透

三、解决


3.1 缓存空值

对于数据库中不存在的数据,将其对应的结果(如 null 或特定标记)写入缓存,并设置短暂过期时间。示例:SET key "null" EX 60

3.2 参数校验

在业务逻辑中对输入参数进行校验,过滤掉非法或异常请求。

3.3 布隆过滤器(Bloom Filter)拦截

布隆过滤器(Bloom Filter 是一种空间高效的概率数据结构,用可以快速判断某个元素是否在集合中。

布隆过滤器(Bloom Filter)特点: 1. 空间高效,节省内存: 相比于存储整个集合的数据,布隆过滤器只需要存储一段位数组,大大降低了内存占用; 2. 速度快, 速度快: 插入和查询操作都具有常数时间复杂度(O(1)), 利用 Redis 的高并发性能,可以在内存中快速进行布隆过滤器的插入和查询操作。3. 概率误判, 布隆过滤器允许出现 假阳性(false positives,即可能会判断某个不存在的元素为存在,但不会出现 假阴性(false negatives),即判断一个存在的元素为不存在。另外, 布隆过滤器(Bloom Filter 一旦设置好后不支持删除单个元素(计数布隆过滤器可以部分解决该问题,但复杂度会增加)。

布隆过滤器(Bloom Filter)原理: 布隆过滤器使用一个 位数组(Bit Array 和多个哈希函数。当一个元素插入时,使用所有哈希函数计算该元素的多个哈希值,并将位数组中对应的位置设置为 1;查询时,使用相同的哈希函数计算哈希值,如果所有对应位置都是 1,则判断该元素可能存在,否则一定不存在。参数: m 个二进制向量, n 个预备数据, khash 函数。影响误差率的因素有两个: m/n比率 越大, 误差率可能越低; hash 函数个数, 函数越多, 误差率也会越低。

因此, 我们可以在缓存层之前增加 布隆过滤器, 在访问数据库之前,通过布隆过滤器判断请求的数据是否存在。如果判断不存在,则直接返回,减少对数据库的压力。