前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis中,什么是缓存击穿、缓存穿透、缓存雪崩

Redis中,什么是缓存击穿、缓存穿透、缓存雪崩

作者头像
李昂君
发布2021-12-24 18:20:24
6990
发布2021-12-24 18:20:24
举报
文章被收录于专栏:李昂君李昂君

阅读量: 166

1、缓存介绍

缓存是互联网开发中必不可少的一部分,它能降低我们数据库的并发数,提高我们系统的性能,比如我们经常使用的redis、emCached等等,其中redis应该是大部分的人选,为什么?因为速度快,易上手,是很多开发者的首选,但是缓存同样存在着问题,如果使用的不恰当,也可能会造成非常严重的后果,这时候你可能就会有疑问,缓存只是存储一些数据而已,怎么会造成严重的后果呢?下面我就带大家一起来分析分析。

2、什么是缓存?

缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。

比如我们的redis、他就是缓存中比较常见的一种,他的并发读写能力能达到10w/s左右的速度,这个速度是相当不错的,相对于传统的数据存储来说,比如数据库,快了不知道多少倍,传统的数据库(mysql)操作的都是磁盘,而redis操作的是内存(ram),所以他们的速度肯定是没法比较的,由于传统数据库的读写较慢,所以并发较高的时候就会造成性能瓶颈问题,这也是为什么需要引入缓存的原因之一。

再唠一下~

缓存的出现,同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。

另外的一些典型问题就是,缓存穿透、缓存雪崩和缓存击穿。目前,业界也都有比较流行的解决方案。本篇文章,并不是要更加完美的解决这三个问题,也不是要颠覆业界流行的解决方案。而是,从实际代码操作,来演示这三个问题现象。之所以要这么做,是因为,仅仅看这些问题的学术解释,脑袋里很难有一个很形象的概念,有了详细的描述,可以加深对这些问题的理解和认识。

2、缓存击穿

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

小编在做电商项目的时候,把这货就成为“爆款”。

其实,大多数情况下这种爆款很难对数据库服务器造成压垮性的压力。达到这个级别的公司没有几家的。所以,务实主义的小编,对主打商品都是早早的做好了准备,让缓存永不过期。即便某些商品自己发酵成了爆款,也是直接设为永不过期就好了。

一、解决方案

1、自动更新

什么是自动更新呢?这个有点类似与jwt的自动刷新token机制,jwt的自动刷新token实现原理大致为:请求的时候判断一下token的剩余有效时间,如果有效时间小于设定的时间,那么jwt将生成一个新的token,然后再将次token重新设置过期时间,并将新的token返回给前端使用,这个也可以参考一下,redis是支持查询某个key剩余有效时间,所以这里我们只需要设定一个时间差,比如3分钟,请求的时候查询的有效时间如果小于3分钟,那么刷新这个key的有效时间,刷新这个操作可以使用异步实现(提高性能)。

可能你想到了,这种方式存在缺陷,没错,如果再快失效的3分钟内没有请求,那么缓存中的key将不会被刷新,还是会存在缓存击穿的问题,所以这种方式不是特别推荐。

2、定时更新

第一种:定时任务,查询快要过期的key,更新内容,并刷新有效时间,这种比较消耗服务器性能,也不是特别推荐。

第二种:延迟队列,如果大家了解它的话可能一下就知道我说的是什么意思了,将数据存入缓存的那一刻同时发送一个延迟队列(按指定时间消费),时间小于缓存中key的过期时间,到了指定时间,消费者刷新key的有效时间再发送一个延迟队列,以此循环,这种方式还是不错的,但是实现方式相对于第一种来说就要复杂一点了,他需要依靠消息中间件来完成,如果消息中间件某个时间宕机,那就gg了,虽然这种方式虽然比较推荐,但是成本偏高,因为为了防止消息中间件宕机,我们有可能需要对消息中间件做集群处理。

3、程序加锁

我个人推荐使用这个,为什么呢?因为它不需要额外的服务器开销,也不需要额外的资源消耗,他仅仅只是让线程串行而已,但是这个时候你可能就会有疑问了,加锁不是会严重影响程序的效率吗?为什么你还推荐这种方式呢?

其实并不是所有的锁都会很大的降低程序的性能,这里我们当然不能使用synchronized,原因很简单,他的效率比较慢,不太适合这种情况,我要介绍的这种锁名字为:读写锁

大道至简,mutex key互斥锁真心用不上。

3、缓存穿透

缓存穿透指的是:同一时刻,大量的并发请求数据库中不存在的信息,他既不会命中缓存,也不会命中数据库,但是他会查找数据库。

上面的bug也是因为它产生的,测试的小哥哥查询的订单都是数据库不存在的,所以这个时候这些并发请求都不会命中缓存(redis),将直达数据库(mysql),由于大量的并发请求到达数据库,而数据库承受不住这么高的并发,从而导致数据库崩溃,这就是缓存穿透。

一、代码流程

  1. 参数传入对象主键ID
  2. 根据key从缓存中获取对象
  3. 如果对象不为空,直接返回
  4. 如果对象为空,进行数据库查询
  5. 如果从数据库查询出的对象不为空,则放入缓存(设定过期时间)想象一下这个情况,如果传入的参数为-1,会是怎么样?这个-1,就是一定不存在的对象。就会每次都去查询数据库,而每次查询都是空,每次又都不会进行缓存。假如有恶意攻击,就可以利用这个漏洞,对数据库造成压力,甚至压垮数据库。即便是采用UUID,也是很容易找到一个不存在的KEY,进行攻击。

二、流程图

三、解决方案

1、将空数据存入缓存

什么意思呢?简单点来说,不管数据库中有没有查询到数据,都往缓存中添加一条数据,这样下次请求的时候就会直接在缓存中返回,这种方式比较简单粗暴。

2、布隆过滤器

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

这个算法实现起来比上面第一种稍微复杂一点,这里就不具体说明了,如果感兴趣的话可以百度自行了解一下,不是很难。

4、缓存雪崩

缓存雪崩,是指在某一个时间段,缓存集中过期失效。

产生雪崩的原因之一,比如在写本文的时候,马上就要到双十二零点,很快就会迎来一波抢购,这波商品时间比较集中的放入了缓存,假设缓存一个小时。那么到了凌晨一点钟的时候,这批商品的缓存就都过期了。而对这批商品的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。

小编在做电商项目的时候,一般是采取不同分类商品,缓存不同周期。在同一分类中的商品,加上一个随机因子。这样能尽可能分散缓存过期时间,而且,热门类目的商品缓存时间长一些,冷门类目的商品缓存时间短一些,也能节省缓存服务的资源。

其实际中过期,倒不是非常致命,比较致命的缓存雪崩,是缓存服务器某个节点宕机或断网。因为自然形成的缓存雪崩,一定是在某个时间段集中创建缓存,那么那个时候数据库能顶住压力,这个时候,数据库也是可以顶住压力的。无非就是对数据库产生周期性的压力而已。而缓存服务节点的宕机,对数据库服务器造成的压力是不可预知的,很有可能瞬间就把数据库压垮。

一、解决方案

1、随机设置过期时间

这个随机时间并不是真正的随机时间,而是指在原来过期时间的基础上生成一个随机时间,这个随机时间比较小,然后两者相加即可。

2、设置永久有效

将一些常用的数据设置成为永久有效,注意哦,是经常使用的而不是全部,这点需要特别注意。

总结

什么是缓存穿透?同一时刻,大量的并发请求数据库中不存在的信息,他既不会命中缓存,也不会命中数据库,但是他会查找数据库。

什么是缓存击穿?缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db(数据库)。

什么是缓存雪崩?缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机

并不是只有上面几种解决方案,这里我只是讲解了几种常用的解决方案,在日常开发中我们可以根据实际的业务需求进行选择,没有最好的,只有最适合自己的,所以不一定要选择最牛逼的解决方案,但是一定要选择最适合项目的解决方案。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-10-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、缓存介绍
  • 2、什么是缓存?
  • 2、缓存击穿
    • 一、解决方案
      • 1、自动更新
      • 2、定时更新
      • 3、程序加锁
  • 3、缓存穿透
    • 一、代码流程
      • 二、流程图
        • 三、解决方案
          • 1、将空数据存入缓存
          • 2、布隆过滤器
      • 4、缓存雪崩
        • 一、解决方案
          • 1、随机设置过期时间
          • 2、设置永久有效
      • 总结
      相关产品与服务
      云数据库 Redis
      腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档