redis 缓存预热_Redis异常问题解决方案:缓存雪崩、预热、穿透、击穿、降解方案分析…

  • Post author:
  • Post category:其他


f3a489d269500739d387021e647fc8f6.png


不管你在工作中还是面试中,Redis异常问题的解决方案都是不得不去学习了解的,下面来细品一下!


一、缓存雪崩


1、什么是缓存雪崩?

如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩由于原有缓存失效,新缓存未到期间所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。

举例来说, 我们在准备一项抢购的促销运营活动,活动期间将带来大量的商品信息、库存等相关信息的查询。 为了避免商品数据库的压力,将商品数据放入缓存中存储。 不巧的是,抢购活动期间,大量的热门商品缓存同时失效过期了,导致很大的查询流量落到了数据库之上。对于数据库来说造成很大的压力。


2、有什么解决方案来防止缓存雪崩?


1、加锁排队


mutex互斥锁解决,Redis的SETNX去set一个mutex key,当操作返回成功时,再进行加载数据库的操作并回设缓存,否则,就重试整个get缓存的方法

2、数据预热


缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题。用户直接查询事先被预热的缓存数据。可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key

3、双层缓存策略


C1为原始缓存,C2为拷贝缓存,C1失效时,可以访问C2,C1缓存失效时间设置为短期,C2设置为长期

4、定时更新缓存策略


实效性要求不高的缓存,容器启动初始化加载,采用定时任务更新或移除缓存

5、设置不同的过期时间,让缓存失效的时间点尽量均匀


二、缓存预热


1.什么是缓存预热

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题。

用户直接查询事先被预热的缓存数据。如图所示:

0614413310c8a96f79b53b8a67ec651a.png

如果不进行预热, 那么 Redis 初识状态数据为空,系统上线初期,对于高并发的流量,都会访问到数据库中, 对数据库造成流量的压力。


2.有什么解决方案?

  1. 数据量不大的时候,工程启动的时候进行加载缓存动作;
  2. 数据量大的时候,设置一个定时任务脚本,进行缓存的刷新;
  3. 数据量太大的时候,优先保证热点数据进行提前加载到缓存。


三、缓存穿透


1、什么是缓存穿透?

缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到对应key的value,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库

a879131a1fe6750387105ab4b68e5163.png


2、有什么解决方案来防止缓存穿透?


1、缓存空值


如果一个查询返回的数据为空(不管是数据不存在,还是系统故障)我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过5分钟。通过这个设置的默认值存放到缓存,这样第二次到缓存中获取就有值了,而不会继续访问数据库

2、采用布隆过滤器BloomFilter


优势:

占用内存空间很小,位存储;性能特别高,使用key的hash判断key存不存在

将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力

在缓存之前在加一层BloomFilter,在查询的时候先去BloomFilter去查询key是否存在,如果不存在就直接返回,存在再去查询缓存,缓存中没有再去查询数据库


四、缓存降级

降级的情况,就是缓存失效或者缓存服务挂掉的情况下,我们也不去访问数据库。我们直接访问内存部分数据缓存或者直接返回默认数据。


举例来说:

对于应用的首页,一般是访问量非常大的地方,首页里面往往包含了部分推荐商品的展示信息。这些推荐商品都会放到缓存中进行存储,同时我们为了避免缓存的异常情况,对热点商品数据也存储到了内存中。同时内存中还保留了一些默认的商品信息。如下图所示:

7b4cc1312e47beec50da00f9bd0d5d2e.png

降级一般是有损的操作,所以尽量减少降级对于业务的影响程度。


五、缓存击穿


1、什么是缓存击穿?

在平常高并发的系统中,大量的请求同时查询一个key时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去。这种现象我们称为缓存击穿


2、会带来什么问题

会造成某一时刻数据库请求量过大,压力剧增


3、如何解决

上面的现象是多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它

其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存


基于Redis分布式锁的教学


免费分享上期的Redis分布式锁教学视频给大家,有需要的朋友可以加VX:rxh8515 免费获取,如果文章对你有用可以帮忙点赞一下,谢谢支持!同时Zookeeper分布式锁的学习视频也可以来获取!

763cf7cf7aad4364464eb1d882534d5e.png


还有更多Redis教学视频可以加VX:rxh8515 免费获取

c6d70d6819a10de478c92cc1cd591444.png

5cc4eeacdba31f57432e6d9dd86e2214.png


Redis 学习笔记:

  1. redis简介
  2. 为什么要用redis /为什么要用缓存
  3. 为什么要用redis而不用map/guava做缓存?
  4. redis和memcached的区别
  5. redis常见数据结构以及使用场景分析
  6. redis设置过期时间
  7. redis 内存淘汰机制(MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?)
  8. redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)
  9. redis事务
  10. Redis常见异常及解决方案
  11. 分布式环境下常见的应用场景
  12. Redis集群模式
  13. 如何解决Redis的并发竞争Key问题
  14. 如何保证缓存与数据库双写时的数据一致性?
aa920fd76fbd41553560218a774b3512.png



版权声明:本文为weixin_34379608原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。