IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 令人头痛的延时双删 -> 正文阅读

[大数据]令人头痛的延时双删

经常看到一个问题redis和mysql数据同步方式有几种,哪种更适用,个人感觉虽然不难,但是有时候绕不明白,所以做了写总结,并且使用图解的方式通俗易懂。

redis和mysql数据同步有五种情况:

1.更新数据库,更新缓存

2.更新缓存,更新数据库

3.删除缓存,更新数据库

4.更新数据库,删除缓存

5.删除缓存,更新数据库,延时删除缓存

1.更新数据库,更新缓存

c4bed86d97534f698cfda21f1c1d2b77.png

图中的场景是有一台mysql和redis数据库初始值都是10,用户1(上面的用户)此时进行了更新操作,把num改成9,此时mysql数据库更新成了9,但是更新缓存之前用户2(下面的用户)进行查询操作,这时读取的是redis的旧值也就是10,mysql和redis数据不一致。总结来说就是步骤2和步骤3插入了一个线程访问,这样就更好理解。

?2.更新缓存,更新数据库

这种情况和第一种原理类似。

3.删除缓存,更新数据库

96c22bdee60747a480b39867a3b8c79a.png

第一幅图用户1去更新数据num=9,此时执行步骤1删除缓存,redis中的10被删除,但是此时用户2执行查询操作由于redis前面删除了所以会去查询mysql,此时的mysql因为还没更新所以用户2得到的值依然为10,并缓存到redis中,最后在执行数据库更新操作,mysql的数据变成了9。mysql和redis数据不一致。

4.更新数据库,删除缓存

733af0413a224edeb0c9917ac7ba2d40.png

和上述类似,用户1请求更新操作num=9,此时执行步骤1,更新数据库,mysql的值变成9,?

但是此时用户2查询操作,发现redis有值返回10,虽然这时候mysql和redis的数据不一致,但是最后执行步骤4,删除缓存之后其他线程访问得到的数据一致,也就是说这个过程是最终一致性,中间只是部分数据不同步,有什么解决办法吗?延时双删可以解决!

?5.删除缓存,更新数据库,延时删除缓存

0bb24c9012c2431eb03f7f4afc081268.png

2a7022cd835c40e09cb176433e053289.png?3f72326896e844d6a23509866ef2f580.png

?终于到了延时双删!用户1更新数据num=9,然后执行步骤2删除缓存,此时用户2来查询数据,由于redis缓存被前面一步删除,所以查询mysql数据库得到num=10,并缓存到redis中,然后执行步骤4更新数据库mysql得到num=9,此时延时一段时间再把缓存给删除,下次其他用户访问时就能把mysql中的数据同步到redis实现了数据同步!但是由于延时,造成了性能不佳,吞吐量不高,不适合高并发场景。

为什么要延时呢?

对照第二张图,此时redis没有值,用户2去查询mysql数据库,然后返回值并构建缓存,如果不是延时删除缓存而是直接删除缓存,那么有可能返回值构建缓存还没完成,在这种情况下直接删除缓存,又会把从mysql返回值(旧值)构建缓存,就相当于没有其任何作用。说白了,延时的目的就是让用户2有时间将mysql查询到的值构建到redis中,只有构建好了再删除才能确保最后redis中没有缓存。???????

附加:

MQ重试机制?

使用canal

总结:一般redis和mysql数据同步使用先更新数据库,再删缓存,到达最终一致性,延时双删虽然可以保证数据一致性但是由于需要延时因而不适合高并发场景,在高并发场景下可以使用MQ重试机制,如果删除缓存失败就一致重试,但是高耦合。低耦合的解决方案是使用canal。canal伪装成mysql的从机,监听主机mysql的二进制文件,当数据发生变化时发送给MQ。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-07-03 10:53:18  更:2022-07-03 10:54:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:57:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码