2019独角兽企业重金招聘Python工程师标准>>>

问题:怎么保持缓存与数据库一致?

要解答这个问题,我们首先来看不一致的几种情况。我将不一致分为三种情况

  1. 数据库有数据,缓存没有数据;
  2. 数据库有数据,缓存也有数据,数据不相等;
  3. 数据库没有数据,缓存有数据。

在讨论这三种情况之前,先说明一下我使用缓存的策略,也是大多数人使用的策略,叫做 Cache Aside Pattern。酷壳里的 缓存更新的套路 一文,很值得一读,我的策略也是从他那学来的。 简而言之,就是

  1. 首先尝试从缓存读取,读到数据则直接返回;如果读不到,就读数据库,并将数据会写到缓存,并返回。
  2. 需要更新数据时,先更新数据库,然后把缓存里对应的数据失效掉(删掉)。

因为:

  1. 读的逻辑大家都很容易理解,谈谈更新。如果不采取我提到的这种更新方法,你还能想到什么更新方法呢?大概会是:先删除缓存,然后再更新数据库。这么做引发的问题是,如果A,B两个线程同时要更新数据,并且A,B已经都做完了删除缓存这一步,接下来,A先更新了数据库,C线程读取数据,由于缓存没有,则查数据库,并把A更新的数据,写入了缓存,最后B更新数据库。那么缓存和数据库的值就不一致了。

  2. 另外有人会问,如果采用你提到的方法,为什么最后是把缓存的数据删掉,而不是把更新的数据写到缓存里。这么做引发的问题是,如果A,B两个线程同时做数据更新,A先更新了数据库,B后更新数据库,则此时数据库里存的是B的数据。而更新缓存的时候,是B先更新了缓存,而A后更新了缓存,则缓存里是A的数据。这样缓存和数据库的数据也不一致。

按照我提到的这种更新缓存的策略,理论上也是有不一致的风险的,酷壳的文章有提到,只不过概率很小,我们暂时可以不考虑,后面我们有其他手段来补救。 讨论完使用缓存的策略,我们再来看这三种不一致的情况。

  1. 对于第一种,在读数据的时候,会自动把数据库的数据写到缓存,因此不一致自动消除
  2. 对于第二种,数据最终变成了不相等,但他们之前在某一个时间点一定是相等的(不管你使用懒加载还是预加载的方式,在缓存加载的那一刻,它一定和数据库一致)。这种不一致,一定是由于你更新数据所引发的。前面我们讲了更新数据的策略,先更新数据库,然后删除缓存。因此,不一致的原因,一定是数据库更新了,但是删除缓存失败了。
  3. 对于第三种,情况和第二种类似,你把数据库的数据删了,但是删除缓存的时候失败了。

因此,最终的结论是,需要解决的不一致,产生的原因是更新数据库成功,但是删除缓存失败。 我想出的解决方案大概有以下几种:

  1. 对删除缓存进行重试,数据的一致性要求越高,我越是重试得快。
  2. 定期全量更新,简单地说,就是我定期把缓存全部清掉,然后再全量加载。
  3. 给所有的缓存一个失效期。

第三种方案可以说是一个大杀器,任何不一致,都可以靠失效期解决,失效期越短,数据一致性越高。但是失效期越短,查数据库就会越频繁。因此失效期应该根据业务来定。

转载于:https://my.oschina.net/u/3691499/blog/3027645

为什么你的缓存更新策略是先更新数据库后删除缓存,讲讲其他的情况有什么问题?...相关推荐

  1. 为什么是先更新数据库再删除缓存,而不是更新缓存?

    一开始看很多人说更新数据库后删除缓存,然后有人说是更新缓存时需要遍历list或者hash查找导致慢,我!@#&((&(&^%&%&m&*&()& ...

  2. 更新操作先删除缓存后更新DB,还是先更新DB后删除缓存问题???

    以前自己在学校学习redis的时候还真没想到这么多,上班后看公司的项目代码,发现都是先更新DB,然后删除缓存,而且更新DB后不会立马将DB数据放入缓存,然而我以前不管是查询还是update都是操作完D ...

  3. 计算机更新策略,客户端无法更新组策略

    你好,客户端windows 7,服务器windows server 2008.该域部署了多个站点,某些站点部署的是只读域控制器. 客户反馈客户端无法更新组策略,执行gpupdate /force,报错 ...

  4. Redis缓存(二)缓存淘汰策略,脏数据/脏页,缓存污染

    一.应该给Redis分配多少内存空间 八二原则:80%的请求都是访问数据库中同样的20%的数据(热点数据只占20%),所以一般给Redis分配15% - 30%数据总量的内存空间(只保存热点数据,冷数 ...

  5. 缓存服务的更新策略有哪些?

    原文 在互联网项目开发中,缓存的应用是非常普遍了,缓存可以帮助页面提高加载速度,减少服务器或数据源的负载. 1.为什么需要缓存? 一般在项目中,最消耗性能的地方就是后端服务的数据库了.而数据库的读写频 ...

  6. 【Redis学习03】redis缓存及其更新策略

    文章目录 1. 什么是缓存 2. 添加redis缓存 2.1 缓存商铺信息 3. 缓存更新策略 3.1 缓存更新策略方法 3.2 主动更新策略 3.3 缓存更新策略总结 4. 对商铺查询的缓存添加超时 ...

  7. 【Redis】缓存更新策略

    1. 缓存更新策略综述 内存淘汰 不用自己维护,利用 Redis 自己的内存淘汰机制 (内存不足时,触发策略,默认开启,可自己配置),其可在一定程度上保持数据一致性 超时剔除 给数据添加 TTL,到期 ...

  8. Redis:缓存一致性问题(缓存更新策略)

    Redis缓存的一致性 1. 缓存 1.1 缓存的作用: 1.2 缓存的成本: 2. 缓存模型 3. 缓存一致性问题 3.1 引入 3.2 解决 (1) 主动更新:先更新数据库,再手动删除缓存 (2) ...

  9. 两难!先更新数据库再删缓存?还是先删缓存再更新数据库?

    前言 当我们在做数据库与缓存数据同步时,究竟更新缓存,还是删除缓存,究竟是先操作数据库,还是先操作缓存?本文带大家深度分析数据库与缓存的双写问题,并且给出了所有方案的实现代码方便大家参考. 本篇文章主 ...

最新文章

  1. 她说要介绍10000个开源项目?来!我们一起监督!
  2. 001-SDK框架之Unity游戏调用SDK
  3. Arcgis 使用ArcToolbox实现数据统计
  4. STL浅析——序列式容器vector的数据结构
  5. 贪吃蛇程序 php,微信小程序-贪吃蛇教程实例
  6. FTP服务器构建与维护,ftp服务器的搭建与三种访问途径
  7. 第一次使用SSE指令集
  8. 最简单的基于FFmpeg的移动端例子附件:SDL Android HelloWorld
  9. prepareStatement的用法和解释
  10. 电脑html怎么导入苹果手机,爱思助手把电脑视频怎么导入苹果手机 视频导入iPhone教程...
  11. 最新可用的快速FLV转MP4方法,解决转换后无声音及视频不流畅问题
  12. 控制服务器系统,控制服务器操作系统
  13. svn服务器搭建(一) VisualSVN-Server
  14. 如何开始做一个开源项目?他的亲身经历值得参考
  15. 下载Docker Compose超时的问题(Fail connect to github-production-release-asset-2e65be.s3.amazonaws.com:443)
  16. 九头牛的故事—你就是那个美丽的期待(刘俊平咨询师)
  17. Moran_DeepLPF_Deep_Local_Parametric_Filters_for_Image_Enhancement_CVPR_2020_paper
  18. MediaStore.Images.Media.insertImage保存图片
  19. java的tey语句return了_Java中try、finally语句中有return时的执行情况
  20. Visual Studio 2022 解决无法打开源文件“stdio.h”问题

热门文章

  1. WindowsServices_无法拷贝文件到服务器
  2. 单元测试注意事项总结(一)
  3. SQL Server中 缓冲和池的不同点
  4. 值类型和引用类型的区别[转]
  5. vue-cli 搭建的项目处理不同环境下请求不同域名的问题
  6. leetcode127. Word Ladder
  7. Centos下oracle11g R2的启动与关闭监听、数据库
  8. Struts2中Action各种转发类型
  9. WPF 3D模型的一个扩展方法
  10. 《天风文章》 V1.1.0设计文档