1.缓存穿透
2.缓存雪崩
3.缓存击穿
4.缓存和实际数据库不一致
以上四个问题是常见的使用缓存的问题,个人其实十分厌恶缓存穿透和缓存击穿这两个总结的名字,非要把很简单的现象用两个听上去差不多的名词代替,搞的人特别容易混淆,但是很多人说也没办法,只能找个记忆的方法。
缓存穿透
定义
缓存穿透是指大量请求了一定不存在的数据,数据库里没有,也不会有写回到缓存的操作,缓存失去了存在的意义(像透明化了一样)。
解决方案
1.加一层布隆过滤器,这在之前的博客有提到过,布隆过滤器可以在比较低的代价下,过滤一定不存在的情况。
2.还是放进缓存,设置一个较短的过期时间。
缓存击穿
定义
缓存击穿指一个热点key在过期之后,并发请求就落到db上了。
解决方案
简单粗暴,设置永不过期。
缓存雪崩
定义
缓存雪崩和击穿有一点点类似,而雪崩是指一批热点key失效,并发请求就落到db上。
解决方案
1.简单粗暴,设置永不过期,但是考虑到量大,可行性有待验证。
2.分散过期时间,给过期时间加上随机值。
数据库压力有一个比较好的思路就是事前事中事后的解决方案。
这个等研究一下再做探讨。//todo
缓存和实际数据库不一致
定义
就是缓存里的值和数据库不一样,导致有脏数据
产生原因
假设:现有A、B两个线程,都想对数据进行修改,A先将db改成1,B后将db改成2,mysql下innodb的行锁能保证AB的操作一定是又先后顺序的,但是,写会缓存的时候,由于无法保证网络传输的先后顺序,B的数据包先到达缓存中间件,从而将缓存改成2,A后到,将值改成1,那么此时缓存中是1,而db内的数据是2,造成了数据不一致的情况,
核心问题是:写缓存的时候无法保证乱序后,结果一致
解决方法
“先更新DB,后删除缓存”:先updateDB,后删除缓存,在下一次get的时候再从db里拿,再写回缓存。 删除操作能够保证,无论先后的执行顺序,导致结果是一致的。