mysql 和 redis 数据不致性怎么办?
发布日期:2021-10-06 02:38:24
浏览次数:7
分类:技术文章
本文共 829 字,大约阅读时间需要 2 分钟。
在高并发的业务场景下,mysql 和 redis 很容易出现数据不一致。
比如:
- 如果删除了缓存Redis,还没有来得及写库MySQL,另一个线程就来读取,发现缓存为空,则去数据库中读取数据写入缓存,此时缓存中为脏数据。
- 如果先写了库,在删除缓存前,写库的线程宕机了,没有删除掉缓存,则也会出现数据不一致情况。
如何解决?延迟双删 + 懒加载
什么是懒加载?
当业务读取数据的时候再从存储层加载的模式,而不是更新后主动刷新
延迟双删
在写库前后都进行redis.del(key)操作,并且第二次删除通过延迟的方式进行。
方案一: 1)先删除缓存; 2)再写数据库; 3)休眠N毫秒 4)再次删除缓存。 休眠N毫秒怎么确定的,具体该休眠多久呢? 需要评估自己的项目的读数据业务逻辑的耗时。这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。 当然,这种策略还要考虑 redis 和数据库主从同步的耗时。最后的写数据的休眠时间:则在读数据业务逻辑的耗时的基础上,加上几百ms即可。比如:休眠1秒。 方案二,异步延迟删除: 1)先删除缓存; 2)再写数据库; 3)触发异步写人串行化mq(也可以采取一种key+version的分布式锁); 4)mq接受再次删除缓存。 异步删除对线上业务无影响,串行化处理保障并发情况下正确删除。
为什么要双删?
db更新分为两个阶段,更新前及更新后
更新前的删除,在db更新的过程中由于读取的操作存在并发可能,会出现缓存重新写入数据,这时就需要更新后的删除
双删失败如何处理?
- 设置缓存过期时间
从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。所有的写操作以数据库为准,只要到达缓存过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。
结合双删策略+缓存超时设置,这样最差的情况就是在超时时间内数据存在不一致。- 重试方案
重试方案有两种实现,一种在业务层做,另外一种实现中间件负责处理。
转载地址:https://blog.csdn.net/luxuiary/article/details/105703520 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2024年03月01日 17时23分38秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
python中func自定义函数_Python函数之自定义函数&作用域&闭包
2019-04-21
wget连接指定端口_端口通不通 telnet wget ssh
2019-04-21
easyexcel 工具类_问了个在阿里的同学,他们常用的15款开发者工具!
2019-04-21
mysql统计结果大于0时返回true_mysql表查询练习
2019-04-21
mysql登录15046_ASMCMD命令拷贝文件报错ORA-15046 (转)
2019-04-21
mysql5.7中文匹配度 match_深度解析MySQL 5.7之中文全文检索
2019-04-21
node mysql 事件循环_nodejs的事件循环简单理解
2019-04-21
java post返回值乱码_java post请求乱码解决方法
2019-04-21
java开源物联网_JetLinks开源物联网平台源码 v1.8.0
2019-04-21
java小猿_猿辅导笔试第二题(Java版)-小猿抽奖
2019-04-21
import java.io后报错_大神求解,IO报错文件名、目录名或卷标语法不正确
2019-04-21
给图片加上水印php视频,php给图片添加水印的实现过程
2019-04-21
php计算时间差js,js 求时间差怎么求实例代码
2019-04-21
php 分布式锁,php 实现Redis分布式锁
2019-04-21