【无标题】

旁路缓存笔记

参考了小林coding和java全栈知识体系的文章

逻辑:

读:先读缓存,如果缓存中不存在就读数据库,然后更新缓存

写:先更新数据库,再删除缓存

具体逻辑:

失效:应用程序先从cache获取数据,如果没有得到,则从数据库中取数据数据,成功后放入缓存中

命中:命中后直接缓存

更新:先把数据库中的数据更新,然后删除缓存

先读后写问题

先读取cache发现为空,然后去db写入,随后一个写入请求写入db并删除cache,然后写操作再去cache写入。

这种情况会导致cache中存储的仍然是旧的数据。所以我们需要给缓存设置过期时间。

上面这个问题的发生的可能性不高,因为缓存写入的速度一般远远快于数据库更新+删除的速度。而且还有本身缓存过期时间的兜底,即使发生了先读后写导致的bug,也只是之前的数据没更新,等缓存的时间一过就可以访问了。

回写缓存失败问题

接下来还有问题:如果更新数据库+删除缓存这一套流程中,第二步删除缓存失败这个操作丢失怎么办?

通常来讲有两个解决方案:

1.消息队列重试机制 2. 订阅MySQL binlog,再操作缓存

消息队列重试机制

引入消息队列,将第二个操作要操作的数据加入到消息队列,让消费者来进行以下操作:

1.如果删除缓存失败,则进行重试,如果重试次数超过阈值,就返回给业务层报错

2.如果删除缓存成功,就要把数据从消息队列中移除。

这个方法有个问题就是对业务线有大的侵入。

异步更新缓存(基于订阅binlog的同步机制)

这个方案与消息队列的不同之处在于使用了数据库的binlog日志 ,然后订阅binlog来监控操作,一旦发现binlog中有更新的指令,就推送到非业务代码中执行前面的消息队列重试机制,好处就是因为监听的是数据库,所以对业务代码基本没有影响。

业界一般都是用的是binlog的异步更新缓存策略,可以使用阿里的中间件Canal来做binlog异步同步。

相关推荐
oak隔壁找我1 分钟前
SpringBoot 将项目打包成 Fat JAR(肥包),核心原理
后端
陌殇殇20 分钟前
001 Spring AI Alibaba框架整合百炼大模型平台 — 快速入门
人工智能·spring boot·ai
言慢行善33 分钟前
sqlserver模糊查询问题
java·数据库·sqlserver
专吃海绵宝宝菠萝屋的派大星39 分钟前
使用Dify对接自己开发的mcp
java·服务器·前端
大数据新鸟1 小时前
操作系统之虚拟内存
java·服务器·网络
Tong Z1 小时前
常见的限流算法和实现原理
java·开发语言
凭君语未可1 小时前
Java 中的实现类是什么
java·开发语言
He少年1 小时前
【基础知识、Skill、Rules和MCP案例介绍】
java·前端·python
克里斯蒂亚诺更新1 小时前
myeclipse的pojie
java·ide·myeclipse