| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 如何保障 MySQL 和 Redis 的数据一致性? -> 正文阅读 |
|
[大数据]如何保障 MySQL 和 Redis 的数据一致性? |
前言在写这篇文章前,我把所有的情况简单列一下:
除了上面的 Case,还有文章总结出以下策略:
我先评价一下,很多文章写的真的不太好,容易误导用户,比如上面的策略,看了费劲且用处不大,分析了一圈,最后也没有告诉用户终极解决方案。 在满足实时性的条件下,不存在两者完全保存一致的方案,只有最终一致性方案,这里直接给出最终结论:
不好的方案1. 先写 MySQL,再写 Redis
请求 A、B 都是先写 MySQL,然后再写 Redis,在高并发情况下,如果请求 A 在写 Redis 时卡了一会,请求 B 已经依次完成数据的更新,就会出现图中的问题。 这个图已经画的很清晰了,我就不用再去啰嗦了吧,不过这里有个前提,就是对于读请求,先去读 Redis,如果没有,再去读 DB,但是读请求不会再回写 Redis。?大白话说一下,就是读请求不会更新 Redis。 2. 先写 Redis,再写 MySQL同“先写 MySQL,再写 Redis”,看图可秒懂。 3. 先删除 Redis,再写 MySQL这幅图和上面有些不一样,前面的请求 A 和 B 都是更新请求,这里的请求 A 是更新请求,但是请求 B 是读请求,且请求 B 的读请求会回写 Redis。 请求 A 先删除缓存,可能因为卡顿,导致数据一直没有更新到 MySQL,导致两者数据不一致。 这种情况出现的概率比较大,因为请求 A 更新 MySQL 可能耗时会比较长,而请求 B 的前两步都是查询,会非常快。 好的方案4. 先删除 Redis,再写 MySQL,再删除 Redis对于“先删除 Redis,再写 MySQL”,如果要解决最后的不一致问题,其实再对 Redis 重新删除即可,这个也是大家常说的“缓存双删”。 为了便于大家看图,对于蓝色的文字,“删除缓存 10”必须在“回写缓存10”后面,那如何才能保证一定是在后面呢?网上给出的第一个方案是,让请求 A 的最后一次删除,等待 500ms。 对于这种方案,看看就行,反正我是不会用,太 Low 了,风险也不可控,不知道是那个脑残想的。 那有没有更好的方案呢,我建议异步串行化删除,即删除请求入队列 异步删除对线上业务无影响,串行化处理保障并发情况下正确删除。 如果双删失败怎么办,网上有给 Redis 加一个缓存过期时间的方案,这个不敢苟同。个人建议整个重试机制,可以借助消息队列的重试机制,也可以自己整个表,记录重试次数,方法很多。
5. 先写 MySQL,再删除 Redis对于上面这种情况,对于第一次查询,请求 B 查询的数据是 10,但是 MySQL 的数据是 11,只存在这一次不一致的情况,对于不是强一致性要求的业务,可以容忍。(那什么情况下不能容忍呢,比如秒杀业务、库存服务等。) 当请求 B 进行第二次查询时,因为没有命中 Redis,会重新查一次 DB,然后再回写到 Reids。 这里需要满足 2 个条件:
对于第二个条件,我们都知道更新 DB 肯定比查询耗时要长,所以出现这个情况的概率很小,同时满足上述条件的情况更小。 6. 先写 MySQL,通过 Binlog,异步更新 Redis这种方案,主要是监听 MySQL 的 Binlog,然后通过异步的方式,将数据更新到 Redis,这种方案有个前提,查询的请求,不会回写 Redis。 这个方案,会保证 MySQL 和 Redis 的最终一致性,但是如果中途请求 B 需要查询数据,如果缓存无数据,就直接查 DB;如果缓存有数据,查询的数据也会存在不一致的情况。 所以这个方案,是实现最终一致性的终极解决方案,但是不能保证实时性。 几种方案比较我们对比一下上面讨论的 6 中方案:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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年11日历 | -2024/11/24 3:10:50- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |