场景应用:如何保证缓存与数据库的双写一致性?

简介: 场景应用:如何保证缓存与数据库的双写一致性?

场景应用:如何保证缓存与数据库的双写一致性?


文章目录

如何保证缓存与数据库的双写一致性?

先记住结论:先更新数据库、再删除缓存是影响更小的方案

四种同步策略:

想要保证缓存与数据库的双写一致,一共有4种方式,即4种同步策略:

  1. 先更新缓存,再更新数据库;
  2. 先更新数据库,再更新缓存;
  3. 先删除缓存,再更新数据库;
  4. 先更新数据库,再删除缓存。

从这4种同步策略中,我们需要作出比较的是:

  1. 更新缓存与删除缓存哪种方式更合适?

先记住结论:删除缓存更适合

  1. 应该先操作数据库还是先操作缓存?

先记住结论:先操作数据库后操作缓存

下面我们来详细的探究一下:

同步策略探究

更新缓存还是删除缓存:

下面,我们来分析一下,应该采用更新缓存还是删除缓存的方式。

更新缓存

  • 优点:每次数据变化都及时更新缓存,所以查询时不容易出现未命中的情况。
  • 缺点:更新缓存的消耗比较大。如果数据需要经过复杂的计算再写入缓存,那么频繁的更新缓存,就会影响服务器的性能。如果是写入数据频繁的业务场景,那么可能频繁的更新缓存时,却没有业务读取该数据。

删除缓存

  • 优点:操作简单,无论更新操作是否复杂,都是将缓存中的数据直接删除。
  • 缺点:删除缓存后,下一次查询缓存会出现未命中,这时需要重新读取一次数据库。

从上面的比较来看,一般情况下,删除缓存是更优的方案。

先操作数据库还是缓存:

下面,我们再来分析一下,应该先操作数据库还是先操作缓存。

首先,我们将先删除缓存与先更新数据库,在出现失败时进行一个对比:

如上图,是先删除缓存再更新数据库,在出现失败时可能出现的问题:

  1. 进程A删除缓存成功;
  2. 进程A更新数据库失败;
  3. 进程B从缓存中读取数据;
  4. 由于缓存被删,进程B无法从缓存中得到数据,进而从数据库读取数据;
  5. 进程B从数据库成功获取数据,然后将数据更新到了缓存。

最终,缓存和数据库的数据是一致的,但B拿到的仍然是旧的数据。而我们的期望是二者数据一致,并且要都是新的数据。

如上图,是先更新数据库再删除缓存,在出现失败时可能出现的问题:

  1. 进程A更新数据库成功;
  2. 进程A删除缓存失败;
  3. 进程B读取缓存成功,由于缓存删除失败,所以进程B读取到的是旧的数据。

最终,缓存和数据库的数据是不一致的。

经过上面的比较,我们发现在出现失败的时候,是无法明确分辨出先删缓存和先更新数据库哪个方式更好,以为它们都存在问题。

后面我们会进一步对这两种方式进行比较,但是在这里我们先探讨一下,上述场景出现的问题,应该如何解决呢?

实际上,无论上面我们采用哪种方式去同步缓存与数据库,在第二步出现失败的时候,都建议采用重试机制解决,因为最终我们是要解决掉这个错误的。而为了避免重试机制影响主要业务的执行,一般建议重试机制采用异步的方式执行,如下图:

这里我们按照先更新数据库,再删除缓存的方式,来说明重试机制的主要步骤:

  1. 更新数据库成功;
  2. 删除缓存失败;
  3. 将此数据加入消息队列
  4. 业务代码消费这条消息;
  5. 业务代码根据这条消息的内容,发起重试机制,即从缓存中删除这条记录。

好了,下面我们再将先删缓存与先更新数据库,在没有出现失败时进行对比:

如上图,是先删除缓存再更新数据库,在没有出现失败时可能出现的问题:

  1. 进程A删除缓存成功;
  2. 进程B读取缓存失败;
  3. 进程B读取数据库成功,得到旧的数据;
  4. 进程B将旧的数据成功地更新到了缓存;
  5. 进程A将新的数据成功地更新到数据库。

可见,进程A的两步操作均成功,但由于存在并发,在这两步之间,进程B访问了缓存。最终结果是,缓存中存储了旧的数据,而数据库中存储了新的数据,二者数据不一致

如上图,是先更新数据库再删除缓存,再没有出现失败时可能出现的问题:

  1. 进程A更新数据库成功;
  2. 进程B读取缓存成功;
  3. 进程A更新缓存成功。

可见,最终缓存与数据库的数据是一致的,并且都是最新的数据。但进程B在这个过程里读到了旧的数据,可能还有其他进程也像进程B一样,在这两步之间读到了缓存中旧的数据,但因为这两步的执行速度会比较快,所以影响不大。对于这两步之后,其他进程再读取缓存数据的时候,就不会出现类似于进程B的问题了。

最终结论:

经过对比你会发现,先更新数据库、再删除缓存是影响更小的方案。如果第二步出现失败的情况,则可以采用重试机制解决问题。

补充:延时双删策略

上面我们提到,如果是先删缓存、再更新数据库,在没有出现失败时可能会导致数据的不一致。如果在实际的应用中,出于某些考虑我们需要选择这种方式,那有办法解决这个问题吗?

答案是有的,那就是采用延时双删的策略,延时双删的基本思路如下:

  1. 删除缓存;
  2. 更新数据库;
  3. sleep N毫秒;
  4. 再次删除缓存。

阻塞一段时间之后,再次删除缓存,就可以把这个过程中缓存中不一致的数据删除掉。而具体的时间,要评估你这项业务的大致时间,按照这个时间来设定即可。

采用读写分离的架构怎么办?

如果数据库采用的是读写分离的架构,那么又会出现新的问题,如下图:

进程A先删除缓存,再更新主数据库,然后主库将数据同步到从库。而在主从数据库同步之前,可能会有进程B访问了缓存,发现数据不存在,进而它去访问从库获取到旧的数据,然后同步到缓存。这样,最终也会导致缓存与数据库的数据不一致。这个问题的解决方案,依然是采用延时双删的策略,但是在评估延长时间的时候,要考虑到主从数据库同步的时间。

第二次删除失败了怎么办?

如果第二次删除依然失败,则可以增加重试的次数,但是这个次数要有限制,当超出一定的次数时,要采取报错、记日志、发邮件提醒等措施。


相关文章
|
3月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
589 5
|
11月前
|
存储 缓存 NoSQL
缓存加速新玩法,让你的应用飞起来
本文主要叙述如何运用云数据库 Tair 构建缓存,助力应用提速、优化性能。
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
242 6
|
9月前
|
缓存 NoSQL Java
Redis应用—8.相关的缓存框架
本文介绍了Ehcache和Guava Cache两个缓存框架及其使用方法,以及如何自定义缓存。主要内容包括:Ehcache缓存框架、Guava Cache缓存框架、自定义缓存。总结:Ehcache适合用作本地缓存或与Redis结合使用,Guava Cache则提供了更灵活的缓存管理和更高的并发性能。自定义缓存可以根据具体需求选择不同的数据结构和引用类型来实现特定的缓存策略。
602 16
Redis应用—8.相关的缓存框架
|
9月前
|
消息中间件 缓存 NoSQL
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
|
9月前
|
缓存 NoSQL PHP
用装饰器模式实现多层缓存:让PHP应用更快更稳
通过装饰器模式实现PHP多层缓存架构,详解如何利用内存、Redis、文件缓存组合提升应用性能。包含设计思路、代码示例与实战效果对比,助您构建高效缓存策略。
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
256 5
|
缓存 NoSQL 数据库
运用云数据库 Tair 构建缓存为应用提速,完成任务得苹果音响、充电套装等好礼!
本活动将带大家了解云数据库 Tair(兼容 Redis),通过体验构建缓存以提速应用,完成任务,即可领取罗马仕安卓充电套装,限量1000个,先到先得。邀请好友共同参与活动,还可赢取苹果 HomePod mini、小米蓝牙耳机等精美好礼!
|
缓存 NoSQL 关系型数据库
mysql和缓存一致性问题
本文介绍了五种常见的MySQL与Redis数据同步方法:1. 双写一致性,2. 延迟双删策略,3. 订阅发布模式(使用消息队列),4. 基于事件的缓存更新,5. 缓存预热。每种方法的实现步骤、优缺点均有详细说明。
460 3
|
存储 缓存 数据库
缓存技术有哪些应用场景呢
【10月更文挑战第19天】缓存技术有哪些应用场景呢

热门文章

最新文章