日常学习小结,不计内容、不计形式。
1、缓存穿透
造成原因
- 代码设置了错误的缓存key,导致请求都打在DB上。
- 接口被爬虫或恶意访问,造成大量空命中。
解决方案
- 缓存空对象:对直接访问DB返回的null,设置缓存(一定要设置过期时间,且时间不宜长)(缺点:可能会有大量无效缓存占用内存空间)。
- 布隆过滤器:在缓存层前面,将存在的key用布隆过滤器保存起来,当请求过来时先到过滤器中找一下,不存返回null,若key是整数组成,可以由bigmaps做不弄过滤器(缺点:可能会造成误判)。
2、缓存雪崩
造成原因
- 缓存节点故障:redis节点故障,导致大量请求直接访问DB。
- 同一时间大量缓存过期。
解决方案
- 搭建高可用redis架构,利用集群或者哨兵。
- 设置多级缓存,可以利用本地线程缓存做一级缓存,redis做二级缓存,同时,不同级别缓存设置过期时间要错开。
- 过期时间尽量随机,不要都设置相同。
3、缓存击穿
造成原因
- 高并发时,热点key失效。
- 高并发时,重建缓存耗时长。
解决方案
- 分布式互斥锁:同时只能有一个线程去重建线程,其他请求等待(缺点:可能会造成死锁或线程池阻塞)。
- 永不过期:不设置缓存的过期时间,另起线程去更新缓存(缺点:可能数据不一致)。