缓存一致性

  系统程序处理时,缓存作为DB的一道屏障,可以防止大量请求达到数据库,造成压力过大,还可以提高查询效率。

image.png

  • 问题 并发情况下,会导致数据不一致情况。缓存中和DB中的数据存在差异,原因是因为DB中数据发生变化,需要同步更新缓存中的数据,这时更新缓存数据有可能失败。
  • 解决方案
  1. 先更新缓存,后更新数据库 问题:两个更新线程更新同一条数据,A更新缓存,B更新缓存,B更新数据库,A更新数据库。显然缓存中的数据是脏数据。
  2. 先更新数据库,后更新缓存 问题:同样在两条更新线程中,出现顺序不一致,导致缓存中出现脏数据。
  3. 先更新数据库,后删除缓存 问题:1、更新数据后,在还没有删除缓存之前,有条读的线程,会导致读线程的数据为脏数据,但是后续的线程,读取缓存DB的新值。 2、缓存失效,A先读取DB值,B更新数据库,B删除缓存,A将旧值写入缓存中。
  4. 先删除缓存,后更新数据库 问题:A先删除缓存,B查询发现缓存失效,B缓存旧值,A更新数据库,缓存B的脏数据。
  • 结论 所以在并发情况下,操作数据库和缓存总会有顺序,一旦顺序不一致就会导致脏数据的情况。 1、缓存删除还是更新? 而且更新缓存会导致不必要的开销,比如更新一个库中的数据,但是缓存中是多个库中共同计算的结果,这是更新缓存就需要重新计算一遍。如果在查询不是很频繁的时候,这次计算是多余的。 2、先写库,还是先写缓存? 先删除缓存,后写库,这样就算后面写库失败了,缓存也是null,不会导致脏数据。如果先写库,后面更新缓存失败,缓存中的数据为脏数据。

如何解决先删缓存,后更新库带来的脏数据问题和缓存更新失败问题? 1、对数据库和缓存操作做同步,性能有损失。使用分布式锁 2、 双删,A更新数据库,A删除缓存,A.sleep(1000),A删除缓存

更新失败使用MQ来实现重试,订阅数据库binlog日志或者使用框架的拦截器订阅写操作。

Spring Cache

大概回顾一下Spring cache 的用法

  • @Cacheable 用于方法配置,根据方法参数对结果缓存

属性

解释

value

缓存的名称

key

缓存的key写法按照SpEL预发,默认使用方法名+参数组合

condition

缓存的条件,SpEl表达式

  • @CachePut 用于更新数据,每次都会执行,并将结果缓存
  • @CacheEvict 用于删除数据,将缓存数据删除 多了两个属性

属性

解释

allEntries

是否清空所有缓存,默认false

beforeInvocation

true:方法执行前删除,默认false方法执行后删除

  • @Caching 多个注解嵌套使用,例如
@Caching(put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.name")
})
public User save(User user) {}

Spring默认是先写库,后写缓存,可以通过beforeInvocation指定。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 缓存

      缓存就是将系统或者程序需要的数据存在内存中,以便快速访问,不用重新创建新的实例。减少系统开销提高系统效率。

    OPice
  • Idea 突然打不开了

    1、下载压缩包解压后得到jetbrains-agent.jar 2、启动IDEA,试用(Evaluate for free)进入IDE 3、

    OPice
  • Idea 数据库和redis界面化使用

    Idea 工具是java开发程序员的必备利器,这一个工具几乎可以涵盖所有工具场景。 除了idea自带的工具之外,还支持插件化。

    OPice
  • 缓存穿透,缓存击穿,缓存雪崩的内容和解决方案

    每次想到缓存的概念时就会想到下面这张结构图,缓存主要解决的是中央处理器与内存之间速度不匹配出来的问题。

    后端Coder
  • 缓存的Cache Aside模式

    codecraft
  • Guava CacheBuilder使用说明 原

    CacheBuilder是Guava用于创建LoadingCache、Cache实例的构建类。可以使用下面的方法来创建一个Cache实例。

    随风溜达的向日葵
  • Web缓存教程

     这是一篇针对网站站长、Web开发者与运营维护人员有关缓存Cache的教程。Web缓存是指存在多个Web服务器和客户端之间的缓存,将对请求的响应保存复制拷贝,比...

    lyb-geek
  • Google 出的 Guava 是个什么鬼?

    我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Google 大牛们是如何设计的。

    纯洁的微笑
  • 一个线上缓存异常

      最近线上应用发现了一个问题,系统启动构建缓存会出现缓存数据为空的情况,仔细分析整个流程 ,开始以为是代码疏忽导致bug,后来在仔细分析整个流程发现是由于a缓...

    杉枫
  • mybatis 详解(九)------ 一级缓存、二级缓存

      上一章节,我们讲解了通过mybatis的懒加载来提高查询效率,那么除了懒加载,还有什么方法能提高查询效率呢?这就是我们本章讲的缓存。   本篇源码下载链接:...

    IT可乐

扫码关注云+社区

领取腾讯云代金券