Redis进阶高频面试:缓存穿透、缓存击穿、缓存雪崩

一、前言

Redis是非关系型数据库,数据都存储在内存中,既可以当做数据库存储数据,也能作为日常缓存使用,本文主要探讨Redis作为缓存,在实践中可能会有哪些问题?比如一致性, 穿击, 穿透, 雪崩, 污染等。在我们实际开发过程中对缓存使用也是高频用到的场景,以及面试大法!

为什么要了解?

缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面,也大大缓解了数据库访问压力,但同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。

另外一些典型的问题就是,缓存穿透缓存击穿 和 缓存雪崩。目前业界也都有较流行的解决方案

二、缓存穿透 

快速记忆:没有数据!

概念:用户请求缓存和数据库中都没有的数据。

该数据在缓存 和 DB 中都不存在。导致用户请求都落在DB上,最终可能导致DB承受不住而挂掉。

☛ 举例说明:查询 “ id= -1 ” 或 id特别大不存在的数据。可能发生黑客利用不存在的key频繁攻击。


 

解决方案

  1. 接口层增加校验    :如用户参数校验,id<=0的直接拦截;

  2. 无效的key存放Redis   :如果是缓存和数据库都查不到的情况下,可以把key保存到Redis中,设置value="null",过期时间可设置短点(如30秒)。防止用户反复用同一个key暴力攻击,需注意:如果Key是随机的,那存进Redis也只是浪费内存!

  3. 布隆过滤器(hash结构) :将数据库中的所有key都存储在布隆过滤器中,查询Redis前先去布隆过滤器查询 key 是否存在,不存在就直接返回,避免了对底层存储系统的查询压力

三、缓存击穿 

快速记忆:有数据,单key失效;并发查同一条数据!

概念:某个热点key在缓存中没有或已过期,从而产生集中请求

大并发集中对其进行请求,同时读缓存没读到数据,又同时到DB读取,瞬间剧增DB压力。

☛ 举例说明:某个热点的key失效了,例如秒杀某个商品,导致大并发集中打在数据库上。

思路:第一考虑热点key不设置过期时间,第二考虑降低打在数据库上的请求数量

解决方案

  1. 设置热点数据永远不过期

  2. 接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些 服务 不可用时候,进行熔断,失败快速返回机制。

  3. 加互斥锁。通过互斥锁或队列来控制访问DB的线程数,比如某个key只允许一个线程查询数据和写缓存,其他线程等待。这种方式会阻塞其他的线程,系统的吞吐量会下降

三、缓存雪崩

快速记忆:有数据,大量key失效;并发查不同数据!

概念:同一个时刻大量key失效,引起数据库压力过大甚至down机。

缓存击穿指并发查同一条数据,缓存雪崩是批量的key失效,落到DB并发查大量不同数据。可能瞬间就会导致数据库宕机。重启数据库,马上又会有新的流量把数据库打死。

☛ 举例说明:同一时间的大规模的key失效,例如:Redis宕机,或者大量key都采用相同过期时间

解决方案

  1. 均匀过期:缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。

  2. 热点数据永远不过期。(如数据有变化触发更新缓存)

  3. 互斥锁+熔断机制,限流降级。返回“系统拥挤”之类的提示,保证一部分用户可用,防止过多请求落在DB,原理同缓存击穿解决方案!

  4. 开启Redis持久化机制,尽快恢复缓存数据,一旦重启,从磁盘上自动加载数据恢复到内存中

  5. 数据预热,系统上线前,提前将部分数据加载到缓存。避免用户请求时,先查询数据库,然后再对数据进行缓存。

  6. Redis高可用,搭建Redis集群,多增加几台Redis服务,一台挂掉,其他还可以继续工作。

四、缓存污染

指的是对部分访问一次少次访问的数据,不会再访问了,这部分数据依然存留在缓存中,占用内存空间。

缓存污染会随着数据的持续增加而逐渐显露。随着服务的不断运行,久而久之,缓存中会存在大量冷门数据(即很少访问)。直到空间满了,再往缓存里写数据时产生额外开销,影响Redis性能。比如写时的判断淘汰策略,根据淘汰策略去选择要淘汰的数据,然后进行删除操作。

redis.conf 配置文件中可设置maxmemory-policy参数,主要针对Redis的超过maxmemory设置的容量后,对数据的处理策略。

五、总结

可以围绕着三个方面分析:

  • 事前:Redis 高可用,主从+哨兵,Redis cluster,避免全盘崩溃。
  • 事中:本地 ehcache 缓存 + Hystrix 限流+降级,避免 MySQL 被打死。
  • 事后:Redis 持久化 RDB+AOF,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

限流+降级

限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,采用 降级!返回提示:系统忙碌中,或者空白页面。对用户来说,对加载不出来的页面可能就是多刷新几次。

比如,某某微博热搜,有的人直接进了,有的人就显示空白页面,多刷新几次后也能出来,就是降级原理,牺牲部分用户体验换取服务器安全!

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值