[TOC] #### 1. 前言 --- 在 [第15讲缓存穿透](https://www.itqaq.com/index/764.html) 的时候提到过 “布隆过滤器”,当时只是一笔带过,这一讲把它讲透 能干嘛 ? 用于判断一个元素是否 “可能存在” 或 “一定不存在” + 不存在:100% 准确 + 可能存在:有小概率误判 听起来有点奇怪 ?往下看你就懂了 原理:本质是一个位数组 + 多个哈希函数 打个比方 你有一排 100 个格子,每次来一个客人,用三种不同的方法算出三个格子编号,在那三个格子里放一颗红豆 下次来一个新客人,再用同样三种方法算出三个格子 如果三个格子里都有红豆,你说 “这个人可能来过” 如果有一个格子没有红豆,你说 “这个人一定没来过” 为什么 “可能” 而不是 “一定” ? 因为之前其它客人放的红豆,可能恰好占了这三个格子,这就是误判的来源 #### 2. Redis 中怎么用 --- 需要安装 RedisBloom 模块(Redis Stack 自带) 创建布隆过滤器: ```bash bf.reserve user_filter 0.01 1000000 ``` 0.01 = 1% 误判率,1000000 = 预计存 100 万元素 添加元素: ```bash bf.add user_filter user:1001 ``` 查询: ```bash bf.exists user_filter user:1001 # 1=可能存在 bf.exists user_filter user:9999999 # 0=一定不存在 ``` #### 3. 防穿透实战 --- 99% 的无效请求在布隆过滤器就被挡住了,Redis 和 MySQL 都不用碰 ```python def get_user(user_id): # 布隆过滤器判断 if not redis.execute_command("BF.EXISTS", "user_filter", f"user:{user_id}"): return None # 一定不存在,直接返回 # 正常查缓存和 DB cached = redis.get(f"user:{user_id}") if cached: return json.loads(cached) # ... ``` #### 4. 局限性 --- 不能删除:一个格子里的红豆可能被多个元素共用,你拿走一个会影响其他判断 需要预热:启动时要把已有的数据加载进去 有误判:说 “可能存在” 不一定真存在,但对缓存穿透来说只是多查一次 DB,不影响正确性 #### 5. 本文小结 --- 小总结: + 位数组 + 多个哈希函数 + 说 “不存在” 100% 准确,说"可能存在"有误判 + Redis 用 RedisBloom 模块 + 核心用途:防缓存穿透 + 不能删除,需要预热