Redis更新的正确方法
原文(缓存更新的套路):看到好些人在写更新缓存数据代码时,先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中。然而,这个是逻辑是错误的。试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。
视图分析:
写流程(更新策略)
- 先淘汰 cache(删除缓存);
- 再写 DB(更新数据库)。
读流程
- 先读 cache,如果数据命中 hit 则返回;
- 如果数据未命中 miss 则读 DB;
- 将 DB 中读取出来的数据入缓存。
什么情况下可能出现缓存和数据库不一致呢?

在分布式环境下,数据的读写都是并发的,上游有多个应用,通过一个服务的多个部署(为了保证可用性,一定是部署多份的),对同一个数据进行读写,在数据库层面并发的读写并不能保证完成顺序,也就是说后发出的读请求很可能先完成(读出脏数据):
- 发生了写请求 A,A 的第一步淘汰了 cache(如上图中的1);
- A 的第二步写数据库,发出修改请求(如上图中的2);
- 发生了读请求 B,B 的第一步读取 cache,发现 cache 中是空的(如上图中的步骤3);
- B 的第二步读取数据库,发出读取请求,此时 A 的第二步写数据还没开始,读出了一个脏数据放入 cache(如上图中的步骤4)。
最终导致缓存与数据库不一致。
先更新数据库,后删除缓存(建议,使用场景最多),但是,是不是这个就不会有并发问题了?不是的,比如,一个是读操作,但是没有命中缓存,然后就到数据库中取数据,此时来了一个写操作,写完数据库后,让缓存失效,然后,之前的那个读操作再把老的数据放进去,所以,会造成脏数据。
Redis更新的正确方法的更多相关文章
- edis更新的正确方法
Redis更新的正确方法 https://www.cnblogs.com/westboy/p/8696607.html redis做缓存,怎么更新里面的数据 https://blog.csdn.net ...
- Web 性能优化: 使用 Webpack 分离数据的正确方法
摘要: Webpack骚操作. 原文:Web 性能优化: 使用 Webpack 分离数据的正确方法 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 制定向用户提供文件的最佳方式可能是一 ...
- dedecms网站迁移时记得将安装目录放空 附迁移的正确方法
这段时间在赶一些新项目,我们建站一般都在本地服务器搭建起来,测试得差不多了才传到网上,这样对蜘蛛也相对友好一些,要不然改来改去变化太大给搜索引擎的第一印象很不好.但是由于本地环境和服务器环境还是有一些 ...
- mysqldump 逻辑备份的正确方法【转】
1. 利用mysqldump进行逻辑备份 1)全逻辑备份: mysqldump -uxxx -p --flush-logs --delete-master-logs --all-databases & ...
- 安装ANSYS19.0的正确方法(附下载)
安装ANSYS19.0的正确方法 卸载干净旧版本ANSYS 安装或重新安装之前必须先卸载干净,安装过旧版本ANSYS的也要确保卸载干净.电脑环境准备参考以下内容 ANSYS 卸载后重装需要注意的问题_ ...
- (一)Redis for Windows正确打开方式
目录 (一)Redis for Windows正确打开方式 (二)Redis for 阿里云公网连接 (三)Redis for StackExchange.Redis 下载地址 官网.中文网1 及 中 ...
- AbpVnext使用分布式IDistributedCache Redis缓存(自定义扩展方法)
AbpVnext使用分布式IDistributedCache缓存from Redis(带自定义扩展方法) 我的依赖包的主要版本以及Redis依赖如下 1:添加依赖 <PackageReferen ...
- java并发编程(三)线程挂起,恢复和终止的正确方法
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17095733 下面我们给出不用上述两个方法来实现线程挂起和恢复的策略--设置标志位. ...
- mysql如果数据不存在,则插入新数据,否则更新的实现方法
mysql如果数据不存在,则插入新数据,否则更新的实现方法 //如果不存在,则插入新数据 $sql = "INSERT INTO {$ecs->table('cat_lang')} ( ...
随机推荐
- SPLAY,LCT学习笔记(二)
能够看到,上一篇的代码中有一段叫做find我没有提到,感觉起来也没有什么用,那么他的存在意义是什么呢? 接下来我们来填一下这个坑 回到我们的主题:NOI 2005维修数列 我们刚刚讨论了区间翻转的操作 ...
- Map集合遍历的四种方式理解和简单使用
~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后根据键获取到值 for(String s:m ...
- 攻击图生成工具mulval的安装和配置
https://doc.mbalib.com/view/8620168b35e50fbe9b005fee33c192ad.html http://www.bingbig.com/227.html
- 开始写博客,学习Linq(4)
应该是可以敲代码了,Linq是.NET Framework3.5的功能,该版本的框架同时发布了新增的和更新了得类库,也为C#和VB.NET语言提供了新版本的编译器.Linq的功能支持源于编译器和类库, ...
- token登录验证机制图解
- PostgreSQL主要优势
PostgreSQL主要优势: 1. PostgreSQL完全免费,而且是BSD协议,如果你把PostgreSQL改一改,然后再拿去卖钱,也没有人管你,这一点很重要,这表明了PostgreSQL数据 ...
- [转]硬盘的那些事(主分区、扩展分区、逻辑分区、活动分区、系统分区、启动分区、引导扇区、MBR等)
http://xu3stones.blog.163.com/blog/static/205957136201210309424303 主分区,扩展分区,逻辑分区,活动分区,系统分区,启动分区..... ...
- BZOJ3198 [Sdoi2013]spring 哈希 容斥原理
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3198 题意概括 有n(1<=n<=100000)组数据,每组数据6个数. 现在问有几对 ...
- BZOJ1071 [SCOI2007]压缩 其他
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1071 题意概括 有两个序列a[1..n], b[1..n],其编号为1..n,设为s序列.现在我们 ...
- Window环境下,PHP调用Python脚本
参考 php调用python脚本*** php 调用 python脚本的方法 解决办法:php提供了许多调用其他脚本或程序的方法,比如exec/system/popen/proc_open/passt ...