以前自己在学校学习redis的时候还真没想到这么多,上班后看公司的项目代码,发现都是先更新DB,然后删除缓存,而且更新DB后不会立马将DB数据放入缓存,然而我以前不管是查询还是update都是操作完DB后立马放入缓存。。。

扯远了,回到重点,为什么先更新DB后删除缓存呢?听我慢慢道来~

提出问题

问题场景:当数据出现变化的时候,DB和redis的一致性就显得非常重要!并发的情况下,主要是看场景,和代价,进行选择。
目前主要有两种策略:

  • 先删除缓存后更新DB(用的少,容易产生大量的脏数据)

结论:容易产生脏数据(以为着在以后不产生更新的情况下,脏数据一直会持续下去)
举例:如上图所示,有两个并发操作分别是更新查询第一步更新操作先将redis中的缓存进行删除,接着第二步查询操作并发进来首先寻找redis中有没有缓存,此时因为redis中的数据已经被删除了,第三步只能走DB进行查询,第四步将查询的数据保存到redis当中,此时第五步更新操作属于写操作比较慢才将数据在DB中更新成功。这个时候缓存中的数据就成了旧数据,如果后续不再更新的话,那么这个数据将一直在缓存中存在。(除非设置过期时间)

  • 先更新DB然后删除缓存 (使用场景多)

结论:产生脏数据的概率较小,但是会出现一致性的问题;若更新操作的时候,同时进行查询操作,若hit,则查询得到的数据是旧的数据。但是不会影响后面的查询。(代价较小)
举例:有两个并发操作更新查询第一步更新操作进来后先更新DB,第二步查询操作先从缓存中查询,查询的是redis中更新DB后未同步缓存的数据(脏数据)返回,第三步更新操作在DB中操作完之后将redis中的缓存删除,下一轮查询操作就直接走的是DB然后将数据放入缓存,所以脏数据只产生了一次,不会像上面那种情况一直产生脏数据。

该设计模式产生脏数据的可能情况:

一个是读操作,但是没有命中缓存,然后就到数据库中取数据,此时来了一个写操作,写完数据库后,让缓存失效,然后,之前的那个读操作再把老的数据放进去,所以,会造成脏数据。

该情况出现的概率可能非常低,因为这个条件需要发生在读缓存时缓存失效,而且并发着有一个写操作。而实际上数据库的写操作会比读操作慢得多,而且还要锁表,而读操作必需在写操作前进入数据库操作,而又要晚于写操作更新缓存,所有的这些条件都具备的概率基本并不大。

再优化

(1)先淘汰缓存

(2)再写数据库(这两步和原来一样)

(3)休眠1秒,再次淘汰缓存.时长不定1s,根据情况,具体设定。要再提高性能,也可以自己起一个线程,异步删除.

如果怕第二步删除失败,可采用下面方案:
提供一个保障的重试机制即可,这里给出两套方案。
方案一如下图

流程如下所示

(1)更新数据库数据;

(2)缓存因为种种问题删除失败

(3)将需要删除的key发送至消息队列

(4)自己消费消息,获得需要删除的key

(5)继续重试删除操作,直到成功

然而,该方案有一个缺点,对业务线代码造成大量的侵入。于是有了方案二,在方案二中,启动一个订阅程序去订阅数据库的binlog,获得需要操作的数据。在应用程序中,另起一段程序,获得这个订阅程序传来的信息,进行删除缓存操作。
方案二如下图

流程如下图所示:

(1)更新数据库数据

(2)数据库会将操作信息写入binlog日志当中

(3)订阅程序提取出所需要的数据以及key

(4)另起一段非业务代码,获得该信息

(5)尝试删除缓存操作,发现删除失败

(6)将这些信息发送至消息队列

(7)重新从消息队列中获得该数据,重试操作。

备注说明:上述的订阅binlog程序在mysql中有现成的中间件叫canal,可以完成订阅binlog日志的功能。至于oracle中,博主目前不知道有没有现成中间件可以使用。另外,重试机制,博主是采用的是消息队列的方式。如果对一致性要求不是很高,直接在程序中另起一个线程,每隔一段时间去重试即可,这些大家可以灵活自由发挥,只是提供一个思路。
来源 链接:https://zhuanlan.zhihu.com/p/98909029侵删

更新操作先删除缓存后更新DB,还是先更新DB后删除缓存问题???相关推荐

  1. ClickHouse 更新操作

    clickhouse 更多应用在 查询select  和写入insert  上. 提供部分更新操作,但相比其他各大数据库的更新操作来说,效果已经很好了,下面来详细介绍一下 更新这一块. 更新: 1. ...

  2. 一文教会你Elasticsearch的更新操作(Updata与Updata by Query)

    目录 前言 Update API 使用部分文档进行更新 Updata by Query API 前言 Elasticsearch操作中,最常用的就是搜索和更新操作了.之前介绍了Elasticsearc ...

  3. 分布式系统中一些主要的副本更新策略——Dynamo/Cassandra/Riak同时采取了主从式更新的同步+异步类型,以及任意节点更新的策略。...

    分布式系统中一些主要的副本更新策略. 1.同时更新 类型A:没有任何协议,可能出现多个节点执行顺序交叉导致数据不一致情况. 类型B:通过一致性协议唯一确定不同更新操作的执行顺序,从而保证数据一致性 2 ...

  4. Java 技术篇-java连接并操作数据库实例演示,执行查询、插入、更新和删除操作

    Java 操作数据库 第一章:Java 代码四个类实现 ① 项目结构展示 ② 数据库连接类 ③ 数据库查询类 ④ 数据库更新类 ⑤ 数据库主类 第二章:查询和更新操作实例演示 ① 查询操作演示 ② 更 ...

  5. 31-32 python mysql-connector创建数据、crud,where,排序,删除等。PyMSQL驱动,插入操作、查询操作、更新操作、删除操作、执行

    31Python MysSQL - mysql-connector驱动 使用pip命令安装mysql-connector: python -m pip install mysql-connector ...

  6. SpringBoot + RabbitMQ + canal实现缓存更新操作

    之前已经分享了一篇关于springboot + canal实现缓存更新的功能,但这种方案存在缺陷,当项目属于微服务架构时,一个服务可能有多个实例,即使多个实例都在监听canal的消息,但是只有一个实例 ...

  7. python编程实例详解-Python编程之列表操作实例详解【创建、使用、更新、删除】...

    这篇文章主要介绍了Python编程之列表操作,结合实例形式分析了Python列表的创建.使用.更新.删除等实现方法与相关操作技巧,需要的朋友可以参考下 #coding=utf8 ''''' 列表类型也 ...

  8. 04-插入操作更新操作删除操作

    保存更新删除 目录 插入操作 获取插入的最后一个id 更新操作 删除操作 插入操作 映射文件 Customer.xml : 插入数据的标签为 insert,与查询 select 区分开来. param ...

  9. 【MyBatis笔记】04-插入操作更新操作删除操作

    保存更新删除 插入操作 获取插入的最后一个id 更新操作 删除操作 查询操作在之前的笔记中~ 插入操作 映射文件 Customer.xml : 插入数据的标签为 insert,与查询 select 区 ...

最新文章

  1. python 內建数据类型
  2. Klockwork告警常见错误
  3. 解决python时间戳最大为3001年1月1日15时59分59秒的问题
  4. 大数据和人工智能的关系是什么?
  5. 蓝桥杯基础模块9:IO口扩展与存储器映射
  6. C# 按钮美化技巧
  7. React简介、虚拟DOM、Diff算法、创建React项目、JSX语法、组件、组件声明方式、组件传值props和state、组件的生命周期
  8. 报错,o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column ‘org0_.create_by‘ in ‘field list‘
  9. 学者:比特币暴涨有合理性但仍应警惕其风险
  10. 应用多元统计分析第五章判别分析例题python代码
  11. SPSS 逐步回归【SPSS 028期】
  12. 【Fusion】mosek.fusion基本模型
  13. Windows 配置 Aria2 及 Web 管理面板教程
  14. DM8数据库的归档配置,开启归档,关闭归档
  15. 神仙程序媛小姐姐的一些列Java教程,从小白到进阶,春招和秋招必备的面试题,全站式保姆的Java教程导航帖(未完结)
  16. 认识Kernel 内存泄漏
  17. mysql主备方案_Mysql 主备双库方案
  18. Python入门认知学习程序
  19. NOJ 2015年陕西省程序设计竞赛网络预赛(正式赛)(小女警的异世界之战-前序中序求后序)
  20. 分享112个JS特效动画效果,总有一款适合您

热门文章

  1. pgsql命令行直接输入密码登录
  2. filco蓝牙不好用_蓝牙党+精简布局键位的选择:Filco Minila Air青轴两个月使用体验...
  3. win10系统解决office16的VBE6EXT.OLB不能被加载的问题
  4. 计算机中电容状态表示什么,电容上面是字母代表什么
  5. 如何在网页中屏蔽右键
  6. c语言中y=0x20什么意思,0x20(十六进制0x20等于多少)
  7. 9 年小厂老前端的年终总结(90 后,12 年毕业,工作 9 年,发过传单,做过运营)
  8. 如何完全的卸载ArcGIS?
  9. C/C++编程刷题分享—常见的经典面试题一
  10. 云台和华为p30pro_除了拍月亮 华为P30 Pro还拍出了首部轻科幻CG短片