主题切换
缓存穿透
一、定义
查询数据库中不存在的数据,请求会绕过缓存,每次都直接访问数据库。大量恶意或非法空请求会持续冲击数据库,严重时将数据库压垮。
示例:传入商品id=-1、随机非法ID等,数据库无对应数据,缓存也无法写入有效内容,每次请求都会直达MySQL。
二、产生原因
- 恶意攻击:黑客使用不存在的ID发起大量请求。
- 业务异常:前端或接口传递负数ID、乱码、格式错误等非法参数。
三、主流解决方案
1. 缓存空值(实现最简单)
数据库查询不到数据时,在Redis中存入空标记,并设置较短的过期时间。后续相同请求直接命中缓存,不再访问数据库。 优点:开发成本低,上手简单。 缺点:大量非法Key会占用Redis内存,同时存在短暂数据不一致风险。
2. 布隆过滤器(生产环境常用)
项目启动时,将所有合法数据ID提前存入布隆过滤器。请求到达后先经过过滤器校验:判定数据不存在则直接拦截,不再访问Redis与数据库。 优点:拦截效果好,内存占用低。 缺点:存在极小概率误判,原生布隆过滤器不支持删除数据。
3. 接口参数校验
在接口层提前做规则校验,拦截负数ID、长度异常、格式乱码等非法请求。
四、三大缓存问题区分记忆
- 缓存穿透:查询数据库不存在的数据,缓存、数据库均无有效数据。
- 缓存击穿:单个热点Key过期,海量并发同时冲击数据库。
- 缓存雪崩:大批量Key同时过期,整体流量集中落库。
五、面试高频问题解析
问:什么是缓存穿透,如何产生?
答: 缓存穿透是请求查询数据库中不存在的数据,缓存始终无法命中,所有请求都会直达数据库。主要由恶意请求、业务传递非法参数两类原因造成。
问:解决缓存穿透常用方案有哪些,各自优缺点?
答: 一是缓存空值,实现简单,但会占用额外内存;二是布隆过滤器,拦截效率高,适合生产环境,存在轻微误判且无法删除数据;三是接口参数校验,从入口拦截非法请求。
问:缓存穿透、缓存击穿、缓存雪崩三者如何区分?
答: 穿透是查询不存在的数据;击穿是单个热点Key过期;雪崩是大批量Key同时过期,三者成因、表现与应对方案均不相同。