缓存双写一致性的套路

对于缓存可能很多小伙伴会有疑问,到底是更新缓存还是删除缓存? 到底是先更新数据库,再删除缓存,还是先删除缓存,再更新数据库?>

这篇文章主要分享为了达到最终一致性,针对不同的场景,一些更新缓存的套路。

Cache Aside Pattern(旁路缓存模式)


适用于读多写少的场景,应该是目前最常用的方式。

实现逻辑

  • 读请求中,先请求缓存,若缓存命中,则直接返回缓存中的数据;若缓存未命中,则查询数据库并将查询结果更新至缓存,然后返回查询出的数据。

  • 写请求中,先更新数据库,再删除缓存。

在这种方式中,读请求很好理解,相信大部分小伙伴都是这么做的。而对于写请求相信会有不同的看法,为什么不是更新缓存?

如果是更新缓存,在并发的情况下,线程A写请求,先去更新了数据库。此时,线程B也是写请求进来更新了数据库,然而线程A因为某些原因没还去更新缓存(网络延迟等)。线程B先完成了更新缓存,线程A才完成了更新缓存。这时缓存中是线程A的旧数据,数据库中是线程B的新数据。

删除缓存就没有并发问题了吗,还是有,但是出现的概率非常小

有人会问如果删除缓存失败呢,对于这种情况那就需要采取一定的补偿机制,例如通过引入消息队列,将删除失败的缓存对应的 key 放入消息队列中,在对应的消费者中获取删除失败的 key ,异步重试删除等。

Read/Write Through Pattern


Read-Through(读穿透模式)

实现逻辑

对比Cache Aside Pattern 模式中读请求,不同点在于 Read-Through 中多了一个缓存服务,访问控制层。Cache Aside 是由调用方负责把数据加载入缓存,而Read-Through 则是通过缓存服务来完成缓存层及持久化层交互

Write Through(直写模式)

实现逻辑

对比Cache Aside Pattern 模式中写请求,Write-Through 除了多了一个访问控制层,还由之前的删除缓存变成了更新缓存,那就会出现上面的并发问题。Write-Through 直写模式适合写操作较多,并且对一致性要求较高的场景,在应用 Write-Through 模式时,也需要通过一定的补偿机制来解决它的问题。

Write-Behind(异步回写模式)


实现逻辑

可以看到Write-Behind 也有一个访问控制层,最大的区别在于该模式在更新数据的时候,只更新缓存,不更新数据库,然后通过缓存会异步地批量更新数据库数据。基于这种实现方式,数据库和缓存的一致性较弱,而且可能会丢失数据。但是异步更新数据库,我们可以合并同一数据的多次操作去更新,减少了I/O交互,减轻了数据库的压力,具有较好的吞吐性,显然这种方式适用于大量写操作的场景。

总结

对于解决缓存双写一致性问题,我们最好是按照已有的套路来解决,毕竟是经过大量验证的。当然对于具体选用哪种模式,需要结合实际业务场景来考虑,不同的模式,存在不同的优缺点,缺点我们可以通过额外的机制来处理(设置缓存过期时间,补偿机制等)。

相关推荐
jazz_bin2 小时前
人工智能安全——大语言模型遗忘学习(LLM unlearning)与多目标优化算法
人工智能·算法·语言模型·unlearning·多目标优化·人工智能安全
JINGWHALE12 小时前
设计模式 结构型 外观模式(Facade Pattern)与 常见技术框架应用 解析
前端·人工智能·后端·设计模式·性能优化·系统架构·外观模式
生信碱移2 小时前
使用大语言模型的生物嵌入,后续应该会有很多类似文章出来!
人工智能·算法·语言模型·自然语言处理·chatgpt·数据分析
高 朗4 小时前
【算法刷题】链表
数据结构·算法·链表
顾北辰204 小时前
利用Deeplearning4j进行 图像识别
java·spring boot·机器学习
Libby博仙4 小时前
asp.net core mvc的 ViewBag 和 ViewData 和 Module
后端·asp.net·mvc
2401_858286115 小时前
L27.【LeetCode笔记】2 的幂(五种解法)
c语言·开发语言·笔记·算法·leetcode
chenziang15 小时前
leetcode hot 100 不同路径
算法·leetcode·职场和发展
走在考研路上5 小时前
力扣459 重复的字符串
数据结构·算法·leetcode
❦丿多像灬笑话、℡5 小时前
leetcode热题100(763. 划分字母区间) c++
c++·算法·leetcode