1.常用的缓存图如下:
高频查找某数据时,可以考虑使用redis缓存。当查找时,首先从redis中查找,如果已存在就直接从redis读取返回,如果redis中不存在,就从数据库中查找,再写入Redis中。
2.删除缓存而不是更新缓存,因为有并发性的问题
问题说明:线程1更新数据库,线程2更新数据库,线程2先更新缓存,线程1再更新缓存,此时就会导致缓存中的是旧的数据,数据库里是新的数据。并且在缓存失效时间内,都是读取的旧的数据。
解决办法:Cache Aside Pattern,简单说采用先写库,再删除缓存的方式。
3.不能使用先删除缓存,再写库的
问题说明,线程1删除了缓存,此时线程查询,会将数据库的值写入缓存,线程1进行更新,此时会发现缓存和数据库不一致。
下面是先操作数据库,再操作缓存,这种情况会有极短的不一致时间窗口。
4.缓存双删解决极端情况:
还有一种极端的情况,因为某些原因,写缓存再删除缓存之后,此时还是会导致缓存中是旧的数据,这个旧的数据要么等缓存过期,要么等下一次删缓存。
解决办法,缓存双删:线程1隔一段时间后,第二次删除缓存,这样避免了线程2的影响。
5.总结:
1)使用删除缓存的方式,而不是更新缓存的方式
2)先操作数据库,再操作缓存
参考:
1) bilibili 老齐300讲
2) 缓存和数据库一致性问题,看这篇就够了 (qq.com)