缓存穿透
问题:每次请求直接穿过缓存,回源到数据库中,每次请求都会到DB层,造成数据库负担过大.
方案:
- 采用bloom filter保存缓存过的key,在访问时过滤掉不存在的key,防止请求道DB.
- 如果数据库没有查询到数据,保存空对象到缓存层,设置较短的过期时间.
- 针对业务场景,对请求参数进行校验,防止非法请求击垮DB.
缓存击穿
问题:获取某一失效热点Key时,大量请求冲击数据库.
方案:
- 使用互斥锁,保证一条线程访问数据库,更新redis,其他线程等待或重试.
- 缓存数据快要过期的时候采用异步线程的方式提前更新缓存数据.
缓存雪崩
问题:多个key失效,造成DB负担过重宕机
方案:
- 使用互斥锁,保证一条线程访问数据库.
- key的失效时间在基础时间上再加上一个1~5分钟的随机值.
更新场景
- Cache Aside Pattern
image.png
失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。
命中:应用程序从cache中取数据,取到后返回。
更新:先把数据存到数据库中,成功后,再让缓存失效。
为什么是失效缓存而不是更新缓存?
并发写容易写覆盖造成脏数据问题,而如果失效缓存数据的话,可以保证下一次读请求回源到数据库将最新的数据载入到缓存中,避免脏数据的问题。
- Write/Read Through
Write/Read Through对调用方而言,缓存是作为整个的数据存储,而不用关系缓存后面的db,数据库的更新则是由缓存统一进行管理,对调用方而言只需要和缓存进行交互.
image.png