缓存和DB一致性

读操作,一般是先查询缓存,查询不到再查询数据库,最后回写进缓存。

写操作,究竟是先删除(更新)缓存,再更新数据库,还是先更新数据库,再删除(更新)缓存呢?

java 复制代码
1、给缓存设置过期时间
适用于对数据一致性要求较低或者写请求很少的业务

当读请求没有命中缓存时,就从数据库中读,之后回写到缓存里,同时设置一个过期时间。
写请求直接更改数据库,不用操作缓存。


2、先更新数据库,再更新缓存
如果利用到缓存,那么肯定是读多写少的场景
缺点:
写多读少时,频繁更新缓存会降低性能
并发情况下可能存在将脏数据写回缓存的风险

为什么会有脏读:
首先线程1更新数据库,还没来得及更新缓存,线程2更新数据,在更新缓存成功,然后线程1在更新缓存,结果就变成了数
据库和缓存的数据不一致。

3、先更新缓存,再更新数据库
和方案2类似,也会存在相同的问题。

缺点:
比如线程1更新缓存,还没来得及更行数据库,线程2更新缓存在更新数据库,最后线程1更新数据库,这个时候数据和缓存不一致。


4:先更新数据库,再删除缓存
既然方案2与方案3都是更新缓存,这里不妨直接删除缓存呢?

缺点:
这种也有一个问题就是:当线程1准备更新数据库,线程1还没来得及执行,线程2过来读,还没写入缓存,然后线程1更
新数据,并且删除缓存,线程2在写入缓存就造成了数据不一致。

5、先删除缓存,再更新数据库
缺点:线程1删除缓存,线程2过来读,还没写入缓存,结果线程1更新了数据库,线程2在写入缓存,这个时候,缓存和数据
库的数据也不一致。


方案6:延时双删
更新请求:先删除缓存,在更新数据库,在删除缓存。

缺点:
存在第二次删除失败的情况


方案7:消息队列
先更新数据库,接着将删除缓存的消息投递到mq中。自身拿到消息后,尝试进行删除缓存。如果失败,则不断进行重试。

缺点:
引入了消息队列,系统的复杂性提升,可用性降低。
也会带来各种各样的问题,例如消息丢失、乱序与重复消费等。乱序与重复消费的问题,在删除缓存的场景下,不会造
成任何问题。


方案8    消息队列+订阅binlog
复杂度提升了

缓存和DB一致性-canal,其实这个也是基于Binlog+Mq的方式跳转

相关推荐
誰能久伴不乏5 小时前
桌面客户端的运行日志系统:SQLite 分块 + 独立写线程 + 文本降级
数据库·c++·qt·架构·sqlite
程序员清风12 小时前
数据处理脚本工程化:日志、配置、命令行与测试
服务器·开发语言·数据库
正在走向自律13 小时前
数据集成产品的技术底座:从日志解析原理到 KFS 同步链路搭建(含建表与增删改查完整代码)
数据库·oracle·信创·数据集成·国产数据库·kingbasees·全量+增量同步
程序员塔塔喵13 小时前
【MySQL篇|第七篇】MySQL事务
数据库·mysql·mysql事务
独隅14 小时前
Claude API 实战教程:从入门到完整项目
android·java·数据库·claude·claude code
_孤傲_14 小时前
快速掌握 MySQL 语法
数据库·后端·mysql
数字新视界16 小时前
一体化机柜在数据中心运维中的创新应用与优势分析
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
SelectDB16 小时前
从 StarRocks 走向 Apache Doris:如何实现引擎平滑替换与架构升级?
大数据·数据库·数据分析
为思念酝酿的痛16 小时前
MySQL的操作
数据库·mysql
猫咪很可爱17 小时前
Oracle ORA-4031 错误分析与处理:SGA 内存不足导致 update/exp/expdp 失败
数据库·oracle