常见缓存策略精析 更新中 

缓存三兄弟 缓存穿透 是什么:大量请求查询数据库不存在的数据。缓存没有,持续击打数据库 防范方法: 缓存空值 数据库查不到也往缓存放一个空标记(TTL短,2分钟,该TTL过期了才能进行再次数据库查询) 下一次同样的id来了直接被挡住 优点:有效拦截大量穿透请求 缺点: 恶意攻击造成大量不同的不存在的key,缓存堆满无效数据,浪费内存 延迟了数据一致性,新数据必须等缓存过期 布隆过滤器(推荐) 启动时把所有合法id放入布隆过滤器; 布隆过滤器不给进就真的没有; 优点: 没有高内存占用风险 没有数据一致性风险 缺点: 有极小误判率 增删要维护。数据更新时,要同步更新布隆过滤器 接口层限流和校验 API网关或Controller层做拦截 参数校验、限流降级 互斥锁重建 互斥锁主要解决缓存击穿(热点key过期),但是在缓存空对象场景下,如果有大量并发请求一个不存在的key,可以使用锁 每次访问让一个线程去查DB,其他线程等待 大厂的实践 网关层 校验参数格式,IP限流(挡掉脚本攻击) 过滤器层 布隆过滤器 缓存层 缓存击穿 是什么:某个被疯狂访问的热点key,因为TTL一到,失效的一瞬间海量并发请求同时miss,同时到DB重建同一个key 防范方法: 互斥锁 只让第1个miss的线程去查DB 其他线程等一下再读缓存 高一致性:线程傻傻等待 低一致性:先给旧数据,下一次来查就是新的 逻辑过期 key永不物理过期,把过期时间存在value里面 如果发现逻辑上过期了,异步开个线程重建 当前请求先返回旧值 互斥锁的实现 如何搭建出正确的锁? v1:SETNX key 1 抢锁,DEL key 释放 SETNX=“不存在才设置成功”,天然互斥。但问题:抢到锁的线程崩了、DEL 没执行 → 锁永远不释放 → 死锁。 v2:给锁加过期间 崩了也能自动过期。但关键:必须用一条原子命令 SET key value NX EX 30。 陷阱:别写成 SETNX + 再 EXPIRE 两条——如果刚 SETNX 成功、还没 EXPIRE 就崩了,又变回 v1 的死锁。“抢锁"和"设过期"必须一步做完。 ...

2026-05-05 10:46:44 PM · 1 分钟