一、缓存三剑客
(图片来源:什么是缓存雪崩、击穿、穿透? | 小林coding)
-
缓存穿透 (Cache Penetration)
- 又称"空缓存"
- 指用户请求的数据在缓存和数据库中都不存在,导致每次请求都去查询数据库,给数据库带来巨大压力。
- 解决办法:缓存无效key、布隆顾虑器、接口限流
-
缓存击穿 (Cache Breakdown)
- 又称"热点Key"
- 指某个Key在缓存过期的瞬间,大量并发请求访问该Key,导致缓存被击穿,应用程序不得不从数据库加载数据,存在于数据库中,但不存在于缓存中 。
- 解决办法:
1.设置热点数据永不过期或者过期时间比较长。
2.针对热点数据提前预热,将其存入缓存中并设置合理的过期时间。
3.请求数据库写数据到缓存之前,先获取互斥锁,保证只有一个请求会落到数据库上。
-
缓存雪崩 (Cache Avalanche)
- 又称"缓存失效"
- 指大量缓存key在某时段集中失效,导致大量请求涌入数据库,引发数据库压力过大甚至系统崩溃。
- 解决办法:
1.采用 Redis 集群,避免单机出现问题整个缓存服务都没办法使用。
2.限流,避免同时处理大量的请求。
3.设置不同的失效时间比如随机设置缓存的失效时间。
二、缓存击穿
【热点数据:通常会有几个数据会被频繁地访问,比如秒杀活动,这类被频地访问的数据】
如果缓存中的某个热点数据过期了,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮,这就是缓存击穿的问题。可以认为缓存击穿是缓存雪崩的一个子集。
(图片来源:什么是缓存雪崩、击穿、穿透? | 小林coding)
三、缓存穿透
当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。那么当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透的问题。
(图片来源:什么是缓存雪崩、击穿、穿透? | 小林coding)
四、缓存雪崩
当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。
(图片来源:什么是缓存雪崩、击穿、穿透? | 小林coding)
五、缓存预热
缓存预热是一种在应用程序启动或缓存失效之后,主动将热点数据加载到缓存中的策略。这样,在实际请求到达应用程序时,热点数据已经存在于缓存中,从而减少了缓存未命中的情况,提高了应用程序的响应速度。
缓存预热的主要作用和目的如下:
- 提高缓存命中率:通过预先加载热点数据,缓存预热可以提高缓存的命中率,从而减少对后端数据源(如数据库)的访问,降低系统的负载。
- 保持应用程序性能稳定:在应用程序启动或缓存失效之后,缓存预热可以防止请求对后端数据源产生突然的压力,从而保持应用程序的性能稳定。
- 优化用户体验:由于热点数据已经存在于缓存中,用户在请求这些数据时能获得更快的响应速度,从而提高用户体验。
-
缓存预热可以帮助避免缓存穿透问题。
- 通过提前将可能被访问的数据预热到缓存中,可以确保首次访问就能命中缓存,不会直接访问到数据库。
-
缓存预热可以缓解缓存击穿问题。
- 如果某个热点数据被提前加载到缓存中,即使该缓存在到期的瞬间大量并发访问,也不会直接击穿缓存。
-
缓存预热有助于减少缓存雪崩的风险。
- 通过定期预热缓存,可以保证缓存中始终有足够的数据,即使部分缓存失效也不会对系统造成太大冲击。