缓存击穿
-
原因:承载着高并发的热点数据key设置了过期时间,从这个key过期到重新从MySQL加载数据放到缓存的一段时间内,大量的请求有可能因为在缓存中无法查询到去访问数据库,引起数据库压力瞬间增大,甚至直接打死。
-
解决:
- 设置热点数据key永不过期,或者过期之前,通过另一个异步线程重新设置。
- 当从缓存根据key拿不到数据时候,重新从数据库加载数据的过程中加分布式锁,阻塞其他线程继续访问数据库。
缓存雪崩
- 原因:假设有如一个系统,正常时高峰期请求为5000次/秒,4000次走了缓存,只有1000次落到了数据库上,数据库每秒1000的并发是一个正常的指标,完全可以正常工作,但如果缓存宕机了,或者缓存设置了相同的过期时间,导致缓存在同一时刻同时失效,每秒5000次的请求会全部落到数据库上,数据库立马就死掉了,而此时如果重启数据库,立马又会被新的请求打死了,这就是缓存雪崩。
缓存雪崩是指大量缓存失效,缓存击穿是指热点数据的缓存失效
- 解决:
- 缓存的失效时间设置为随机值,避免同时失效
- 设置热点数据永远不过期。
- 使用集群缓存,保证缓存服务的高可用。在发生缓存雪崩对缓存集群实现高可用。
缓存穿透
- 原因:例如正常id为正数,而恶意请求一直查询id为负的数据,这样会因为缓存不起作用,导致数据库压力过大甚至宕机。
- 解决:
- 接口层增加校验,如正常id为正数,则对id < 0的数据直接返回
- 查询不到的数据也放到缓存,value设置为空,如 set -999 “”。这样可以防止同一个id恶意攻击