穿透
概念
缓存穿透是指,用户访问缓存和数据库都没有的数据,本次查询失败,当用户量很多时,由于缓存都没有命中,大量数据请求瞬间打到DB,会给持久层数据库造成很大的压力,严重的话还会击垮数据库
实例
比如发起id为-1的数据,或者id为根本不存在的数据,此时的用户很可能是攻击者
解决方案
- 接口层用户鉴权校验,参数做校验,不合法的return
- Nginx有配置项,可以让运维大大对单个IP每秒访问次数超出阈值的IP都拉黑。
- 布隆过滤器(Bloom Filter)查询数据库是否存在数据,存在返回刷新KV数据库,不存在直接return
- 如果对应在数据库中的数据都不存在,我们将此key对应的value设置为一个默认的值,比如“NULL”,并设置一个缓存的失效时间。当然这个key的时效比正常的时效要小的多,比如5分钟,这样既可以抗住短时间大量的并发请求了。
击穿
概念
缓存击穿是指,一个十分热点的key,不停的接受高并发访问,在这个key过期失效的一瞬间,大量的请求就击穿了缓存,直接请求数据库
解决方案
- 设置热点数据永远不过期
- 加上互斥锁
让第一个进来的线程查询数据库,并将数据更新回缓存,然后释放锁,这样就可以让接下来并发操作的线程去缓存拿数据
缓存雪崩
概念
缓存雪崩是指大量的key值失效,数据直接打到DB,将数据库直接打垮,同一时间大面积失效,那一瞬间Redis跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,你想想如果打挂的是一个用户服务的库,那其他依赖他的库所有的接口几乎都会报错,用户会对你的产品失去信心
解决方案
- 设置key值随机过期
setRedis(Key,value,time + Math.random() * 10000);
- key值不过期
- redis集群部署,多个redis存放均匀的热点数据
- 资源隔离组件hystrix,熔断降级