缓存双写一致性的套路

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

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

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交互,减轻了数据库的压力,具有较好的吞吐性,显然这种方式适用于大量写操作的场景。

总结

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

相关推荐
梵刹古音28 分钟前
【C语言】 函数基础与定义
c语言·开发语言·算法
编程彩机30 分钟前
互联网大厂Java面试:从Java SE到大数据场景的技术深度解析
java·大数据·spring boot·面试·spark·java se·互联网大厂
笨蛋不要掉眼泪33 分钟前
Spring Boot集成LangChain4j:与大模型对话的极速入门
java·人工智能·后端·spring·langchain
筵陌1 小时前
算法:模拟
算法
We་ct1 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
renhongxia12 小时前
AI算法实战:逻辑回归在风控场景中的应用
人工智能·深度学习·算法·机器学习·信息可视化·语言模型·逻辑回归
CoderCodingNo2 小时前
【GESP】C++四级/五级练习题 luogu-P1223 排队接水
开发语言·c++·算法
民乐团扒谱机2 小时前
【AI笔记】精密光时频传递技术核心内容总结
人工智能·算法·光学频率梳
像少年啦飞驰点、2 小时前
零基础入门 Spring Boot:从“Hello World”到可上线微服务的完整学习指南
java·spring boot·微服务·编程入门·后端开发
CoderCodingNo2 小时前
【GESP】C++五级/四级练习题 luogu-P1413 坚果保龄球
开发语言·c++·算法