今天与大家一起来聊一聊面试中几个常见的缓存问题。为什么突然想梳理这一问题呢,主要是缓存相关知识点在现在的面试中还是会被经常问题,这类问题不能是通过背的方式来准备,而是应该彻底的理解它的原理和解决方案,也正因为这个原因,我确定开始做 《面试过关斩将》 这个专栏系列,该篇是首篇博客,废话少说,接下来,我们开始吧。
🙋♂️:什么是缓存穿透、缓存击穿、缓存雪崩??
缓存穿透(缓存无、数据库无)
缓存穿透: 缓存穿透指的是服务器中没有缓存数据,数据库中也没有符合条件的数据,导致业务系统每次都绕过缓存服务器直接将请求达到打到下游数据库,不仅缓存被击穿了,数据库也被击穿了,这就是所谓的“透”。
缓存穿透的主要可能原因有哪些?
- 遭到恶意
- 爬虫造成空命中
如何解决缓存穿透?
1️⃣ 方法一:缓存空值或者标记错误
也就是在缓存中存储控制或标记,比如:将这些key对应的值设置为null并放到缓存中,这样下次查询这个key的时候,直接返回null,可以避免走数据库的查询,如下所示:
2️⃣ 方法二:布隆过滤器BloomFilter
除了缓存空对象,我们还可以在存储和缓存之前,加一个布隆过滤器,做一层过滤,布隆过滤器里会保存数据是否存在,如果判断数据不不能再,就不会访问存储。
布隆过滤器的过滤原理主要是:
- 通过三个
Hash函数分别将元素a、b、c存储到上图的位数组中,将九个位置为1; - 当检索某个元素时,如果三个哈希函数运算后所得到位值都为1,那么布隆过滤器会告诉我们元素存在;
- 如果有一个位值为0,那边布隆过滤器会告诉我们元素不存在;
3️⃣ 方法三:黑/白名单方式过滤
通过黑白名单可以提前预知对应的访问对象,避免一些陌生恶意的访问者。
4️⃣ 方法四:缓存预热
将热门数据通过程序的方式提前加载到缓存,以此来降低瞬时并发带来的数据库负载。
通过综合使用以上这些方法,可以有效的解决缓存穿透的问题,提高系统的性能和稳定性,同时降低数据库的CPU负载。
缓存击穿(缓存无,数据库有)
缓存击穿: 缓存击穿指的是在高并发访问下,某个热点Key过期失效后,大量请求绕过缓存全部打到数据库DB,导致后端存储负载增大、响应时间变慢,甚至瘫痪。解决方案通常包括使用互斥锁或者分布式锁来对并发请求进行控制,避免对同一资源的并发读写竞争,另外也可以使用热点数据预加载等机制来提前将热点数据加入缓存,在其失效时快速刷新缓存。
缓存击穿的主要可能原因有哪些?
- 在某一时刻资源被超高并发地访问,来不及刷新缓存,造成“击穿”
如何解决缓存击穿?
1️⃣ 方法一:使用互斥锁
这个是业界比较差常用的方法,简单来说就是缓存失败不存在的时候,不是立马去load DB,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX)去set一个mutex key(对缓存的逻辑加锁),当操作返回成功时,再进行load DB的操作并回设缓存。
2️⃣ 方法二:异步定时更新缓存
比如:某一个热点key数据的过期时间为1小时,那么每59分钟,通过定时任务去刷新这个缓存,为缓存“续期”,但是这种定时异步更新机制实际上有些场景比较难处理,因为我们很多时候缓存数据往往都不是一种单一个String类型、或者List集合数据,可能是有很多业务数据聚合的缓存结构,所以这种方式也是因场景而异。
缓存雪崩(缓存无,数据库可能有或者无)
缓存雪崩: 缓存雪崩指的是因为某些原因导致缓存中大量的数据同时失效或过期,导致后续请求都落到后端存储上,从而引起系统负载暴增、性能下降甚至瘫痪。
缓存雪崩的主要可能原因有哪些?
- 缓存服务器宕机或者重启
- 大量热点缓存数据集中在某一时间段失效
如何解决缓存雪崩?
1️⃣ 方法一:缓存失效时间分散开(过期时间错开)**
这个是最直接高效的解决缓存雪崩的问题,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。应用程序限流等措施来避免缓存失效时间集中在同一时间段,以及使用缓存预热和自动刷新机制等手段来减轻缓存压力。
2️⃣ 方法二:热点数据设置永不过期
Redis中保存热点key永不失效,这样就不会出现缓存同时失效的问题,但是随随之而来的问题就是长期下来Redis会被占用大量的存储空间。
2️⃣ 方法三:提高缓存层高可用性
- Redis集群模式、哨兵模式,即便个别
Redis节点下线,整个缓存层依然可以正常使用,避免单点故障。 - 多级缓存,基于多级缓存,不同层级缓存设置不同的过期时间,提高缓存的命中率。
3️⃣ 方法四:做好熔断降级
- 服务熔断:当缓存服务器宕机或超时响应时,为了防止整个系统出现雪崩,暂时停止业务服务访问缓存系统。
- 服务降级:出现大量缓存失效,而且处在高并发高负荷的情况下,在业务系统内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的
fallback错误处理信息。
参考
- [1]. 《Redis深度历险.核心原理与应用实践》书籍
- [2]. 《高级Redis进阶课 解决Redis实际问题》
- [3]. 一篇吃透布隆过滤器(Bloom Filter)及其使用场景