一、缓存穿透
请求查询缓存 缓存没有命中 查询数据库
业务系统访问压根就不存在的数据,就称为缓存穿透。
缓存穿透的危害:大量的请求查询本来不存在的数据 最后都落在DB上,导致数据库压力剧增,大致系统崩溃
产生缓存穿透的原因:主要是恶意请求,玩意攻击行为,海量请求不存在的数据导致系统崩溃
缓存穿透的解决方案:
1.缓存空数据的方案
缓存这些空数据的key ,后续查询直接返回null 不用再次查询DB
问题:
1)缓存太多 恶意攻击浪费内存 可以设置key失效
2)缓存层和存储层的数据会有一段时间窗口的不一致,缓存了空值 在缓存有效期内当有数据以后还是查询返回空值(可以利用消息或者数据库binlog同步等机制去同步)
2.BloomFilter 布隆过滤器
采用布隆过滤器 里面存储目前数据库中存在的所有key 在业务请求和数据查询之间加入了屏障 一个请求过来先查询布隆过滤器是否存在 不存在直接返回null,若存在先去查询缓存 缓存不存在去查询DB
优点是占用资源少,缺点是维护复杂,需要维护一个布隆过滤器(布隆过滤器的新建)
方案选择
1.空数据的key值较少 请求量大但是基本重复的情况 可以使用第一种方案(缓存空数据)
2.恶意攻击行为 key值各不相同,请求重复概率低的情况 可以使用第二种方案
二、缓存雪崩
致命的缓存雪崩就是当缓存服务器宕机或者网络等原因无法访问的情况下,瞬间所有的请求直接访问DB可能造成瞬间击垮数据库
解决方案:
1).使用高可用,保证缓存服务器的可靠性,可以通过 Redis Sentinel 和 Redis Cluster 都实现了高可用缓存集群,单个节点出问题不影响缓存服务的正常使用
2)使用Hystrix熔断、限流、降级来防止雪崩 Hystrix使用命令模式每一项服务处理请求都有各自的处理器
处理器会记录失败率 达到预设的阀值 ,Hystrix会拒绝后续请求 直接返回预先设定的返回值
三、缓存击穿
热点数据集中失效的情况,比如秒杀的场景下 查询的key正好失效 突然大量的请求落入数据库,导致数据库的崩溃
解决方案
1.互斥锁的方式
1).热点数据设置不同的失效时间,避免同时失效可以 在失效时间加减随机数保证不同时失效
2).采用互斥锁的形式 第一个请求过来 缓存的数据上锁 后面的请求直接阻塞,止到第一个请求查询数据库重建索引 释放锁 后面的请求可以直接从缓存中查询数据
2.key永不过期
不设置失效时间,采用异步同步数据 在构建缓存期间会导致数据不一致的情况
注意:互斥锁也有一定的风险 就是第一个key构建缓存时间长,有可能产生死锁,线程池阻塞的风险