我是靠谱客的博主 动听康乃馨,最近开发中收集的这篇文章主要介绍缓存模式,更新及一些缓存问题(二),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

关于缓存有效期及一些问题,点击缓存的有效期,淘汰策略及一些问题(一)

缓存更新方式

  • 先更新数据库,在更新缓存,这样做有什么问题?

最大的问题就是两个并发的写操作导致脏数据,以Redis和Mysql为例,两个并发更新操作,数据库先更新的反而后更新缓存,数据库后更新的反而先更新缓存。这样就会造成数据库和缓存中的数据不一致问题,应用程序中读取的都是脏数据。
在这里插入图片描述

  • 先删除缓存,再更新数据库

逻辑错误,两个并发的读和写操作导致脏数据,假设更新操作先删除了缓存,此时正好有一个并发的读操作,没有命中缓存后从数据库中取出老数据并且更新回缓存,这个时候更新操作也完成了数据库更新。此时,数据库和缓存中的数据不一致,应用程序中读取的都是原来的数据。
在这里插入图片描述
先更新数据库,再删除缓存(采用)

**严格来讲,这种做法理论上还是可能存在问题。**查询操作没有命中缓存,然后查询出数据库的老数据。此时有一个并发的更新操作,更新操作在读操作之后更新了数据库中的数据并且删除了缓存中的数据。然而读操作将从数据库中读取出的老数据更新回了缓存。这样就会造成数据库和缓存中的数据不一致,应用程序中读取的都是原来的数据。
在这里插入图片描述
仔细想想,这种并发的概率出现极低。因为这个条件需要发生在读缓存时缓存失效,而且有一个并发的写操作。实际上数据库的写操作会比读操作慢得多,而且还要加锁,而读操作必需在写操作前进入数据库操作,又要晚于写操作更新缓存,所有这些条件都具备的概率并不大。严谨来做,为了避免这种极端情况造成脏数据所产生的影响,我们还是要为缓存设置过期时间。

缓存穿透

缓存只是为了缓解数据库压力而添加的一层保护层,当缓存中查询不到我们需要的数据就需要去数据库中查询。如果被非正常请求频繁去访问缓存中没有的数据,那么缓存层就失去了存在的意义,所有请求的压力都落在了数据库上,这样会导致数据库连接异常,宕机,崩溃等。
在这里插入图片描述
解决方案

  1. 对于返回为NULL的仍然缓存,对抛出异常的返回则不进行缓存。采用这种方法的会增加缓存的维护成本,需要在插入缓存的时候删除这个空缓存,也可以通过设置较短的超时时间来解决这个问题。

布隆过滤器

  1. 制定规则过滤一些不可能存在的数据,小数据可使用BitMap,大数据可以用布隆过滤器,比如订单ID设置一个范围1-1000,如果不是1-1000之内的数据直接过滤掉。
    在这里插入图片描述

缓存雪崩

缓存不可用或者大量缓存由于超时相同在同一时间段失效,大量请求直接访问数据库,缓存层宕掉后,流量直捣黄牛,向后端MySQL直接请求,存储数据库压力过大导致系统雪崩,无法提供服务。
在这里插入图片描述
解决方案

  1. 给缓存加上一定区间内的随机生效时间,不同的key设置不同的失效时间,避免同一时间集体失效。比如以前是设置10分钟的超时时间,那每个Key都可以随机15分钟过期,尽量让不同Key的过期时间不同。
  2. 采用多级缓存,不同级别缓存设置的超时时间不同,及时某个级别缓存都过期,也有其他级别缓存兜底。
  3. 通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存。
  4. 利用加锁或者队列方式避免过多请求同时对服务器进行读写操作。
  5. 高可用,主从架构,操作主节点读写,数据同步到从节点,一旦主节点挂掉,从节点变主节点。

最后

以上就是动听康乃馨为你收集整理的缓存模式,更新及一些缓存问题(二)的全部内容,希望文章能够帮你解决缓存模式,更新及一些缓存问题(二)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部