为什么延迟删除可以保证MYSQL 与redis的一致性?
看过很多保持MYSQL 与redis保持一致性的文章都提到了延迟删除,其实脱离任何业务场景的设计都是不切实际的,所以我会本着一个通用的读写场景去分析为什么延迟删除大概率可以保证MYSQL与redis的最终一致。
通常的读写场景
通常在使用redis作为读写缓存时,我们采用的是cache aside pattern 的形式,这种形式的读写一般是这样,
1,读请求: 从缓存中获取不到数据时,从db中读取数据,然后再set到缓存里。
2,写请求: 修改db中的数据,然后删掉缓存。
这样的模式大概率是不会有问题的,但是会有极小的概率出现读请求中,可能会很长时间存在旧数据,来看一下这个例子, 下面的数字标明了每个步骤执行的顺序。
可以看到在并发环境下,如果读请求先从db中读取了旧数据,然后写请求再去执行修改db,删除缓存的操作,此时读请求再把读取出来的旧db数据 set到缓存中,那么后续的读请求便会会一直读取到旧数据的缓存,除非缓存过期。

延迟删除是如何解决db与缓存数据不一致的
其实无论是上述缓存模型,还是其他的读写缓存方式,在并发环境下,其实都有可能出现缓存旧数据的问题,其本质原因是,修改缓存的地方不是单协程进行的,多协程修改必然存在并发先后的问题。
解决上述不一致的方式是可以延迟写请求中,删除缓存的时间。先来看下读写请求的并发场景,
1,如果读请求发生在写请求前,那么写请求后续删除缓存,是不存在不一致问题的。
2,如果读请求发生在写请求后,那么后续读请求读取出来的数据就是新数据,也不会有问题。
3,如果读写同时发生,但是缓存还未过期,此时也不会有一致性问题。
4,如果读写同时发生,但是缓存过期,这个时候才有可能出现上面缓存中长时间存在旧数据的问题。
基于此,我们可以延迟写请求中删除缓存的时间,因为一般我们数据有段比较长的缓存时间,在最开始读请求更新缓存后,后续的读请求会比较长时间读取缓存中数据,我们让写请求等待(可以同步,也可以异步)最开始更新缓存的读请求结束,然后再去删除缓存,就避开了读写请求并发更新缓存的场景,这样,下次读请求就不会读取到旧db数据缓存,而是重新从db中获取新数据。
具体等待多长时间才进行缓存删除,需要根据业务读请求接口的处理时长自己决定。
为什么延迟删除可以保证MYSQL 与redis的一致性?的更多相关文章
- PHP商品秒杀问题解决方案实例详解【mysql与redis】
本文实例讲述了PHP商品秒杀问题解决方案.分享给大家供大家参考,具体如下: 引言 假设num是存储在数据库中的字段,保存了被秒杀产品的剩余数量. if($num > 0){ //用户抢购成功,记 ...
- Mysql和Redis数据如何保持一致
先阐明一下Mysql和Redis的关系:Mysql是数据库,用来持久化数据,一定程度上保证数据的可靠性:Redis是用来当缓存,用来提升数据访问的性能. 关于如何保证Mysql和Redis中的数据一致 ...
- python学习道路(day12note)(mysql操作,python链接mysql,redis)
1,针对mysql操作 SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass'); 设置密码 update user set password ...
- 通过Gearman实现MySQL到Redis的数据同步
对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached.File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的 ...
- JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)
MySQL到Redis数据复制方案 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来 ...
- python访问mysql和redis
1. 修改mysql配置文件 修改bind-address=0.0.0.0(允许通过远程网络连接) 2. 修改redis配置文件 修改bind-address=0.0.0.0(允许通过远程网络连接), ...
- 电商中的库存管理实现-mysql与redis
库存是电商系统的核心环节,如何做到不少卖,不超卖是库存关心的核心业务问题.业务量大时带来的问题是如何更快速的处理库存计算. 此处以最简模式来讨论库存设计. 以下内容只做分析,不能直接套用,欢迎 ...
- MySQL与Redis实现二级缓存
redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化, ...
- python笔记7:mysql、redis操作
模块安装: 数据操作用到的模块pymysql,需要通过pip install pymysql进行安装. redis操作用的模块是redis,需要通过pip install redis进行安装. 检验是 ...
- 06 python操作MySQL和redis(进阶)
python操作mysql.redis 阶段一.mysql事务 主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息, ...
随机推荐
- ArrayList中的遍历删除
ArrayList 中的遍历删除 在代码编写过程中经常会遇到这样的要求:遍历一个线性表,要求只遍历一遍(时间复杂度\(O(n)\)),删除符合指定条件的元素,且要求空间复杂度 \(O(1)\). 例如 ...
- BeginCTF 2024(自由赛道)MISC
real check in 题目: 从catf1y的笔记本中发现了这个神秘的代码 MJSWO2LOPNLUKTCDJ5GWKX3UN5PUEM2HNFXEGVCGL4ZDAMRUL5EDAUDFL5M ...
- C++——异常处理模块笔记
异常处理是C++中的重要概念之一,用于处理在程序执行过程中可能发生的错误或异常情况.异常是指在程序执行过程中发生的一些不寻常的事件,例如除零错误.访问无效内存等.C++提供了一套异常处理机制,使得程序 ...
- Ubuntu安装typecho博客
Ubuntu安装typecho博客 简介 名称的来历 Typecho 是由 type 和 echo 两个词合成的,来自于开发团队的头脑风暴. Type,有打字的意思,博客这个东西,正是一个让我们通过打 ...
- NC16615 [NOIP2008]传纸条
题目链接 题目 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接 ...
- colrm命令
colrm命令 colrm命令用于编辑源代码文件,脚本文件或常规文本文件中的文本,此命令从文件中删除选定的列,列定义为一行中的单个字符.索引总是从1开始,而不是0.如果同时指定了开始和结束,则它们之间 ...
- Java I/O 教程(六) BufferedInputStream 类
Java BufferedInputStream Class Java BufferedInputStream class 用于从输入流读取数据,和BufferedOutStream一样内部使用缓冲机 ...
- iOS APP包瘦身,你在工作中真的会关注吗?
安装包组成 谈到 App 瘦身,最直接的想法莫过于分析一个安装包内部结构,了解其每一部分的来源.解压一个 ipa 包,拿到其 payload 中 app 文件的数据,整理归类后其大致如下: Exect ...
- Golang 常用工具记录
Golang 常用工具记录 1 golang 类 1.1 日常使用的 copier 复制结构体到另外一个结构体 等等类似的功能 asynq Go中简单.可靠.高效的分布式任务队列,使用 redis 做 ...
- 【Azure 存储服务】关于Storage Account Queue使用的几个问题
1) 在消费Storage Queue中的数据的时候,如何只过滤出 Subject 为"message/{messageid}"这种,去掉subject为"informa ...