缓存穿透
是指查询一个存在的数据,由于在缓存查不到,在数据库也无法查询出,因此也不会写入到缓存中,这样缓存永远不会生效,导致每个查询都会去请求数据库,导致DB的压力瞬间变大而卡死或者宕机,造成缓存穿透。
解决方法
1、由于请求的参数是不合法的(每次都请求不存在的参数),于是我们可以使用布隆过滤器(BloomFilter) 或者压缩filter提前拦截,不合法就不让这个请求到数据库层!
2缓存空对象 当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据。
缓存雪崩
由于原有缓存失效(或者数据未加载到缓存中),新缓存未到期间(缓存正常从Redis中获取)所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,造成系统的崩溃。
解决方法
1、可以使用分布式锁,单机版的话本地锁。在缓存更新或者过期的情况下,先获取锁,在进行更新或者从数据库中获取数据后,再释放锁,确保只有少数请求可以修改缓存,降低并发冲突带来的影响。
2、消息中间件方式,缓存更新可以推迟到后台任务完成,这样即使有大量的更新请求,也不会立即冲击缓存服务,减少了雪崩的可能性。
3、使用一级和二级缓存Redis+Ehchache,当一级缓存满或数据更新时,将部分数据迁移到持久化存储,保证短期高频访问的数据快速响应。
4、分析用户的行为,尽量让缓存失效的时间均匀分布,均摊分配Redis的key的失效时间。
缓存并发
缓存并发是指,高并发场景下同时大量查询过期的key值、最后查询数据库将缓存结果回写到缓存、造成数据库压力过大。
解决方法
在缓存更新或者过期的情况下,先获取锁,在进行更新或者从数据库中获取数据后,再释放锁,确保只有少数请求可以修改缓存,降低并发冲突带来的影响。