1.缓存穿透
缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会被打倒数据库上。
即这个数据根本不存在,如果黑客攻击时,启用很多个线程,一直对这个不存在的数据发送请求 ,那么请求就会一直被打到数据库上,很容易将数据库打崩。
解决方案:
1.缓存空对象
优点:实现简单,维护方便
缺点:额外的内存消耗,因为缓存了一些瞎编的id对应的空对象,但是可以通过给对象设置TTL解决,但是会造成短期的数据不一致
2.布隆过滤器
优点:内存占用少
缺点:实现复杂,存在误判
3.其他
使用bitmaps类型定义访问白名单,或进行实时监控,和运维人员配合排查访问对象和访问数据设置黑名单限制服务
2.缓存击穿
缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db,属于常见的“热点”问题
解决方案:
1.预先设置热门数据,提前存入缓存
2.实时监控热门数据,调整key过期时长
3.二级缓存:对于热点数据进行二级缓存,并对于不同级别的缓存设定不同的失效时间。
4.设置分布式锁
3.缓存雪崩
大量的应用请求无法在Redis缓存中进行处理,紧接着应用将大量请求发送到数据库层,导致数据库层的压力激增
击穿与雪崩的区别即在于击穿是对于特定的热点数据来说,而雪崩是全部数据。
原因一:缓存中有大量Key同时过期,导致大量请求无法得到处理,大量数据需要回源数据库
方案一 差异化设置过期时间
差异化缓存过期时间,不要让大量的 Key 在同一时间过期。比如,在初始化缓存的时候,给这些数据的过期时间增加一个较小的随机数,这样一来不同数据的过期时间有所差别又差别不大,即避免了大量数据同时过期又能保证这些数据在相近的时间失效
方案二 服务降级
允许核心业务访问数据库,非核心业务直接返回预定义的信息
方案三 不设置过期时间
初始化缓存数据的时候设置缓存永不过期,然后启动一个后台线程 30 秒一次定时把所有数据更新到缓存,而且通过适当的休眠,控制从数据库更新数据的频率,降低数据库压力。
原因二:Redis实例发生故障宕机,无法处理请求,就会导致大量请求积压到数据库层
方案一 服务熔断
暂停业务应用对缓存服务的访问,从而降低对数据库的压力
方案二 请求限流
控制每秒进入应用程序的请求数,避免过多的请求被发到数据库
方案三 Redis构建高可靠集群
通过主从节点的方式构建Redis高可靠集群。可以保证在Redis主节点故障宕机时,从节点切换到主节点,继续提供服务,避免由于缓存实例宕机导致缓存雪崩