首页 > 其他 > 详细

更新缓存

时间:2019-04-22 20:06:12      阅读:124      评论:0      收藏:0      [点我收藏+]

更新缓存的时候涉及两个问题:

  • 删除(del)还是 修改(set)?
  • 先操作数据库,还是 先操作缓存?

组合起来就有四种情况:

第一种情况:先删除缓存,后更新数据库

如果删除缓存失败,则后面的操作都不会执行,没问题;

如果删除缓存成功,更新数据库失败,则缓存与数据库不一致,但这种不一致会马上被修正,因而不影响,因为下一次请求缓存的时候发现缓存中没有,会从数据库重新加载;但是,又有一个问题出现了,在旧的缓存被删除后,新的缓存未写入之前,这段时间内如果有读操作,那么旧的值会被重新加载到缓存,这就相当于没更新缓存;

第二种情况:先更新缓存,后更新数据库

同样,如果更新缓存成功,更新数据库是吧,则出现缓存与数据库不一致,数据不一致就是问题

第三种情况:先更新数据库,后删除缓存

如果更新数据库成功,删除缓存失败,则出现缓存与数据库不一致,数据不一致就是问题

第四种情况:先更新数据库,后更新缓存

跟第三种情况一样

 

虽然,看上去好像都有问题,但是,任何脱离实际业务的设计都是耍流氓

既然我们把Redis当缓存,那么所有数据都要以数据库为准,像上面第二种情况(缓存中有的数据在数据库中没有)是不能容忍的,而对于第一种情况,可以采取双删的策略(删除缓存 --> 更新数据库 --> 再删除缓存),后面两种情况,可以用定时任务进行补偿,有些场景下我们是可以接受不一致的情况的。

不过,话又说回来,直接删除缓存当然是最简单的,它相当于延迟加载(第一次使用的时候发现没有才会去从数据库加载),这样可能导致第一次请求会比较慢;而采用修改缓存的方式,相当于预先加载。

在实际使用的时候,可以采用这两种方式:

  1. 先删除缓存,再更新数据库,最后再删一次
  2. 先更新数据库,然后向MQ发一条消息,由专门的缓存服务去更新数据

 

上面说的是只有一个数据库实例的情况,而实际生产过程中肯定是一主多从的

按照写主读从,缓存加载数据的时候应该从从库中读,而本来主从同步就有延迟,于是读从库很有可能读到的是旧数据

为了解决这种问题,可以考虑以下几种方案:

第一种:强制缓存读主数据库

这样一来,就不必考虑主从同步的问题了,可行(PS:跟微信公众号开发的时候获取Token一样)

第二种:选择性地读主数据库

之所以强制读主库,是因为再主从同步完成之前从库中的数据还是旧的,当主从同步完成后再读从库就没什么问题了,那么如果在主从同步的这段时间内如果没有请求读这个KEY就没有问题,如果这段时间内有请求读取这个KEY,那么在同步完成后要删除这个KEY

如何判断在主从同步这段时间内有没有请求读取这个KEY呢?

在更新数据库的时候,往缓存中设置一个KEY,格式是:缓存KEY+业务数据ID,其生存时间是主从延时时间

比如,假设主从同步延时是3秒,而有业务缓存KEY是hash类型的,更新的这条数据的ID是213,那么在更新数据库后要立即设置  set USER_213_KV  1  3

在读的时候,首先判断缓存中有没有这样一个KEY,如果有则从主库中重新加载数据到缓存,没有,则直接从从库中加载数据到缓存

第三种:订阅从库的binlog

可以通过工具(比如,canal)订阅从库的binlog,这是比较准确的,从库数据有更新,则立即更新缓存

https://github.com/alibaba/canal

 

补充1:缓存穿透

缓存穿透

缓存穿透,指的是查询一个数据库中不存在的数据。这样的话,每次都会查询数据库,相当于缓存就没有用了。

针对这种情况,可以缓存空值,并设置一个较短的生存时间,比如60秒。

 

缓存雪崩

缓存雪崩,指的是大量缓存在一段时间内集体失效。这样的话,短时间内大量请求会直接打到数据库。

针对这种情况,可以在缓存的生存时间后面再加上一个随机数,这样的话就不至于同一时刻集体过期。实际上,因为大量缓存失效意味着这些缓存在同一时刻被设置的,而这种情况不多见。

 

缓存击穿

缓存击穿,指的是单个缓存在被高并发访问时失效了导致请求全部打到数据库。

针对这种情况,在加载缓存的时候要加分布式锁。

 

补充2:Redis客户端工具Medis

https://github.com/luin/medis

git clone https://github.com/luin/medis.git
cd medis
npm install
npm run build
npm start

技术分享图片

技术分享图片

 

更新缓存

原文:https://www.cnblogs.com/cjsblog/p/10752245.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!