Redis 布隆过滤器是什么?如何用于缓存穿透防护?
简化版
布隆过滤器是一种用多个哈希函数和位数组判断“元素可能存在或一定不存在”的概率数据结构。它能用很小内存拦截大量不存在 key,常用于缓存穿透防护;缺点是有误判、通常不支持精确删除,不能替代数据库。
详细版
布隆过滤器的逻辑是:
- 添加元素时,用多个哈希函数算出多个位置,把对应 bit 置 1。
- 查询元素时,也算出多个位置。
- 如果有任意 bit 为 0,元素一定不存在。
- 如果所有 bit 都为 1,元素可能存在。
用于缓存穿透时,请求先查布隆过滤器。如果判断一定不存在,直接拒绝或返回空;如果可能存在,再查缓存和数据库。
它适合商品 ID、用户 ID、文章 ID 这类大量合法 key 判断。误判率要通过容量和错误率设计,不能无限塞数据。
完整版教学
一、缓存穿透为什么需要布隆过滤器
缓存穿透指请求访问大量不存在的数据,缓存没有,数据库也没有,导致请求持续打到数据库。攻击者如果构造随机 ID,普通缓存很难命中。
布隆过滤器放在缓存前面,用来判断 key 是否属于“可能存在的集合”。不存在的 key 在这里就能被拦下。
记忆钩子:布隆过滤器不是证明“有”,而是快速证明“没有”。
二、位数组和多个哈希函数怎么工作
布隆过滤器维护一个 bit 数组和 k 个哈希函数。插入元素时,k 个哈希函数会给出 k 个位置,把这些 bit 置为 1。
bit array: 0 0 0 0 0 0 0 0 0 0
add A -> hash1=2, hash2=5, hash3=8
bit array: 0 0 1 0 0 1 0 0 1 0
查询 B 时,如果 hash 出来的某个位置是 0,说明 B 一定没插入过。因为如果插入过,对应位置一定会被置 1。
三、为什么会有误判
多个元素可能把同一些 bit 置为 1。查询一个从未插入的元素时,它的 k 个位置可能刚好都被其他元素置 1,于是布隆过滤器会判断“可能存在”。
假设 bit 数组很小,只放 10 个 bit,却插入很多元素,bit 很快几乎全变成 1,误判率就会升高。容量越接近设计上限,误判越明显。
一定不存在:只要有一个 bit = 0
可能存在:所有 bit = 1,但可能是别人撞出来的
所以布隆过滤器回答的是概率问题,不是精确集合。
四、容量和误判率要提前设计
使用布隆过滤器前要估算元素数量和可接受误判率。比如预计 1000 万商品 ID,能接受 1% 误判,就按这个规模初始化。
如果实际塞入 5000 万元素,误判率会明显高于预期。很多线上问题不是布隆过滤器原理错,而是容量估算和扩容策略没设计。
| 参数 | 含义 |
|---|---|
| expected insertions | 预计插入数量 |
| false positive rate | 可接受误判率 |
| bit array size | 位数组大小 |
| hash functions | 哈希函数数量 |
五、如何接入缓存穿透链路
典型读链路是先过布隆过滤器,再查 Redis 缓存,最后查数据库。
请求 key
|
Bloom 判断一定不存在 -> 直接返回空
|
可能存在 -> 查缓存 -> 未命中查 DB -> 回填缓存
数据库新增合法 ID 后,也要把 ID 加入布隆过滤器。否则新数据可能被误拦,出现“数据库有但过滤器说没有”的问题。
六、布隆过滤器和缓存空值怎么配合
缓存空值也能防穿透:数据库查不到时,把空结果短 TTL 写入缓存。布隆过滤器更适合挡大量明显非法 key。
| 方案 | 优点 | 缺点 |
|---|---|---|
| 缓存空值 | 简单,适合偶发不存在 | 大量随机 key 会占缓存 |
| 布隆过滤器 | 内存省,挡随机攻击 | 有误判,需维护集合 |
| 参数校验 | 成本最低 | 只能挡格式非法 |
工程中常组合使用:参数校验先挡一层,布隆过滤器挡不存在 ID,缓存空值兜底少量漏网请求。
七、删除和更新有什么坑
普通布隆过滤器不支持精确删除。因为一个 bit 可能被多个元素共享,删除某个元素时把 bit 置 0,会误伤其他元素。
如果业务需要删除,可以考虑计数布隆过滤器,但内存成本更高;或者允许删除后短期仍判断可能存在,让请求继续查缓存/数据库。
普通 Bloom:省内存,不好删
Counting Bloom:可删除,内存更大
面试时要说清楚:布隆过滤器用于“挡不存在”,误判只会放过一部分请求,不应错误拦截真实存在的数据。
八、常见误区与追问
- 误区:布隆过滤器判断存在就是一定存在。 它只能说可能存在,存在误判。
- 误区:布隆过滤器可以随便删除元素。 普通布隆过滤器不支持精确删除,删除可能误伤。
- 误区:用了布隆过滤器就不用缓存空值。 二者解决的侧重点不同,常组合使用。
- 追问:误判会造成什么后果? 一些不存在 key 会继续打到缓存或数据库,但不会误拦真实存在 key。
- 追问:新增数据如何同步过滤器? 写数据库成功后同步或异步加入过滤器,注意失败补偿。
- 追问:容量超了怎么办? 误判率升高,需要重建、更大容量或可扩展布隆过滤器方案。
九、加强记忆
记住“有 0 必无,全 1 可能有”。这就是布隆过滤器最核心的判断规则。
回答缓存穿透时,把参数校验、布隆过滤器、缓存空值、限流降级串起来,才是完整防护链路。