你知道缓存的这个问题到底把多少程序员坑惨了吗?

在现代系统中,缓存可以极大地提升性能,减少数据库的压力。

然而,一旦缓存和数据库的数据不一致,就会引发各种诡异的问题。

我们来看看几种常见的解决缓存与数据库不一致的方案,每种方案都有各自的优缺点

先更新缓存,再更新数据库

这种方案看似简单,实际上很少被推荐。

原因在于如果在更新数据库之前发生了错误,缓存中的数据将和数据库中的数据不一致,最终导致更大的问题。

先更新数据库,再更新缓存

这种方法解决了更新缓存失败的问题,但可能引发另外一个问题:

在高并发场景下,数据库已经更新,但缓存还没有更新时,其他请求可能会读到旧的缓存数据。

先删除缓存,后更新数据库

这种方案在高并发下容易产生问题:

在缓存删除和数据库更新之间的时间窗口内,其他请求可能会读取到旧的数据,导致短时间内的数据不一致

先更新数据库,后删除缓存

这是较为推荐的一种方法,但在高并发场景下也有一定的局限性:

如果数据库更新成功但缓存删除失败,可能导致短时间内的数据不一致。

强一致性与最终一致性

在讨论一致性的时候,我们常常会提到强一致性和最终一致性。

根据业务需求权衡这两者,是缓存策略设计中的重要一步。

后面我会给出一个弱一致性的推荐方案,供大家参考。

SpringCache是一个非常实用的缓存管理框架,能帮助我们简化缓存操作。

以下是一个简单的SpringCache配置示例:

缓存预热策略

缓存预热的重要性不言而喻,上线后瞬时大流量可能导致缓存击穿。

以下是几种常见的缓存预热方案:

  1. 启动时加载:系统启动时加载常用数据到缓存。

  2. 定时加载:定时任务定期加载数据。

  3. 手动加载:手动执行预热脚本。

推荐方案

综合考虑各种方案的优缺点,我给大家一种工作中真正常用的方案,也是我待过的互联网公司中实践过的方案。

这是一种非常简单且成本很低的操作,但能解决绝大多数的缓存与数据库不一致问题。

原理很好理解,就是更新数据库之后设置合理的休眠时间,然后再次删除掉其他线程请求进来导致的旧缓存,最终达到缓存和数据库都是最新数据的目的。

其中休眠时间要根据自身业务的平均耗时来决定,而延迟双删其实就够了,延迟三删只是为了开阔大家的思路,因为真有些公司删除三次来保证一些极端情况的不一致,但我觉得没必要,太极端就不是弱一致性了。

如果是比较复杂的项目,甚至能再进一步的优化,也就是借用定时任务MQ来替代休眠线程,实现异步删除缓存,达到弱一致性的结果。

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

相关推荐
minhuan2 分钟前
大模型应用:大模型数据缓存复用方案:从API请求数据累积到智能融合.50
缓存·api调用·大模型应用·大模型数据缓存复用
QQ_4376643142 小时前
redis相关命令讲解及原理
数据库·redis·缓存
yuankunliu3 小时前
【redis】1、Redis的安装部署
数据库·redis·缓存
最贪吃的虎5 小时前
Redis其实并不是线程安全的
java·开发语言·数据库·redis·后端·缓存·lua
OpsEye5 小时前
Redis 内存碎片的隐形消耗——如何用 memory purge 命令释放空间?
运维·网络·数据库·redis·缓存·内存·监控
optimistic_chen6 小时前
【Redis系列】事务特性
数据库·redis·笔记·缓存·事务
CodeCipher6 小时前
关于Redis单线程问题
数据库·redis·缓存
威风少侠6 小时前
Redis集群配置优化指南
数据库·redis·缓存
indexsunny9 小时前
互联网大厂Java求职面试实战:Spring Boot微服务与Redis缓存场景解析
java·spring boot·redis·缓存·微服务·消息队列·电商
起名时在学Aiifox15 小时前
Vue 3 响应式缓存策略:从页面状态追踪到智能数据管理
前端·vue.js·缓存