面试官:介绍一下什么是缓存雪崩、缓存击穿、缓存穿透?
面试官:我看你简历上有写到 Redis,那你可以介绍一下什么是缓存雪崩、缓存击穿和缓存穿透吗?
缓存雪崩
缓存雪崩是指大量的缓存数据几乎在同一时间内失效,而这时候又刚好碰上大量请求过来获取该数据,导致缓存没有击中,所有的请求都直接打在了我们的后端数据库中;
数据库压力骤增,就可能引发链路滚雪球式的不可用,一个服务拖垮一堆服务。
在 Redis 作缓存的场景中,表现的原因有:
大量的 key 几乎在同一时间失效
Redis 宕机,导致所有 key 不可用
针对第一个原因,我们可以采取以下的策略进行预防:
均匀地设置过期时间,避免大量数据同时失效
使用互斥锁构建缓存,避免所有请求都打到后端数据库
采用双 key 策略,主 key 设置过期时间,备 key 不设置,在主 key 失效的时候,可以返回备 key
Redis 后台构建缓存,可以是定期巡检,发现过期了就触发构建缓存,也可以是业务线程发现缓存失效后,通知 Redis 后台线程构建缓存。
针对 Redis 宕机的原因,我们可以这么做:
合理设计服务熔断或者请求限流机制,避免大量请求同时打到数据库
构建 Redis 高可用集群,避免 Redis 缓存层面的不可用
可以看到我们解决缓存雪崩的核心点就是避免大量请求同时打到后端数据库,造成数据库压力骤增,从而避免了雪崩情况的发生。
缓存击穿
缓存击穿和缓存雪崩很像,它是指一个或者几个缓存数据失效,大量请求过来获取该数据,导致缓存没有击中,所有的请求都直接打在了我们的后端数据库中;
数据库压力骤增,甚至被击垮。
缓存击穿可以看成是缓存雪崩的一个特例,因为缓存击穿更多的是热点数据失效导致的,而不是大量数据;
但是它们所造成的后果是相似的——容易击垮数据库,从而导致一系列服务不可用。
所以我们也是可以用互斥锁和后台构建缓存的方案来解决缓存击穿。
缓存穿透
缓存穿透,和前面两种不同,前面两种只是缓存没击中,还是有数据库兜底的;但是缓存穿透就不一样了,它是缓存没有该数据,数据库也没有该数据的。
缓存穿透产生的情况一般是以下两种:
操作失误,把数据库的数据删了
非法请求,专门请求数据库没有的数据
针对第一种情况,就是要规范我们的操作,避免出现误删的情况
针对第二种情况,我们可以:
限制非法请求
缓存空值或者默认值
使用布隆过滤器提前发现数据库中是否存在该数据
可以看到解决这类问题的核心是在该类场景下,避免大量请求到达数据库,在达到这个目的的前提下,可以有多种解决方案。
这里的根因是数据库所能承受的并发量不是特别高所决定的。
以上就是我对缓存雪崩、缓存击穿和缓存穿透的回答。
评论