一、缓存穿透
概念:查询一个缓存不存在的数据、导致每次请求都要落到数据库层去查询,这样就失去缓存层保护数据库层的本意。
原因:自身业务代码或者数据出现问题。一些恶意攻击、 爬虫等造成大量空命中。
解决:1、缓存空对象:将空的也放进redis中缓存。2、BloomFilter
二、缓存雪崩
概念:通常是互联网场景下、大并发导致redis宕掉(通常是超过了10万+,如常见的秒杀、促销活动)。这时流量都落到了后端、
这时导致数据库宕机、或者调用数据库的服务宕机而发生的级联故障。
解决:1) 保证缓存层服务高可用性,比如使用Redis Sentinel或Redis Cluster。
2) 依赖隔离组件为后端限流并降级。比如使用Hystrix限流降级组件。
3)提前演练。 在项目上线前, 演练缓存层宕掉后, 应用以及后端的负载情况以及可能出现的问题,
在此基础上做一些预案设定。
三、缓存击穿(热点key失效导致的问题)
场景:
开发人员使用“缓存+过期时间”的策略既可以加速数据读写, 又保证数据的定期更新,
这种模式基本能够满足绝大部分需求。 但是有两个问题如果同时出现,
1、当前key是一个热点key(例如一个热门的娱乐新闻),并发量非常大。
2、重建缓存不能在短时间完成, 可能是一个复杂计算, 例如复杂的SQL、 多次IO、 多个依赖等。
可能就会对应用造成致命的危害:
在缓存失效的瞬间, 有大量线程来重建缓存, 造成后端负载加大, 甚至可能会让应用崩溃。
要解决这个问题主要就是要避免大量线程同时重建缓存。
我们可以利用互斥锁来解决,此方法只允许一个线程重建缓存, 其他线程等待重建缓存的线程执行完,
重新从缓存获取数据即可。
redis.setex(key, timeout, value);