imacoder 2020-01-26
1.缓存雪崩
通常我们在数据量请求大或者热点数据都会做缓存,通常情况缓存的数据是通过定时任务刷新,或者查询不到后,通过数据库查询后更新的,定时任务刷新的场景就会有问题,因为所有的key会在同一时间失效,那么在秒杀的场景中,如果缓存失效,大量的请求全部落入数据库,数据库必然是扛不住的,可能还没收到报警,实际上数据库已经宕机了
应对这种场景的处理方法是:1)在批量往redis中存数据的时候,把每个key的失效时间都加一个随机值,这样可以保证不会在同一时间大面积失效。2)电商应用目前使用redis都是集群部署,将热点数据均匀分布在不同的redis分片中也能避免全部失效的问题。3)设置热点数据永不过期,有数据更新时候,就同步更新缓存
2.缓存穿透
如果查询缓存和数据库中都没有的数据,用户不断的发起请求,可能这种用户是攻击者,这种攻击会导致数据库压力过大,严重时会击垮数据库,比如说数据库中的编号都是正数,用户一直用小于0 的参数去请求,每次都是能够绕开缓存世界查库的,数据库也查不到数据,一直这么高并发的请求,通常就很容易挂掉。
应用这种场景的处理方法是:1)接口服务层要增加对参数合法性的校验,不要信任所有的调用者,该防范的还是需要防范 2)对不存在的数据的查询接口也增加缓存,缓存时间可相对控制较短,比如5s等等,这样做可以一定程度的减轻并发情况下的数据库压力 3)redis有一个高级用法布隆过滤器(Bloom Filter),能利用高效的数据结构和算法快速判断出请求的key是否在数据库中存在,不存在的可以直接返回,具体也还没有使用过,待后续研究
3.缓存击穿
这个和缓存雪崩的场景有点相似,缓存雪崩是因为key的大面积同时生效导致请求全部到DB从而导致DB宕机,缓存击穿是指对一个热点key请求量非常大,这一个key一直在扛着大并发,当这个key失效的瞬间,持续的高并发请求穿破缓存直接请求到DB上,类似于在一个完好无损的冰面上凿开了一个洞
应对这种场景的处理方法是:1)设置缓存用不过期,有变动时候主动更新缓存 2)从数据库读取数据后更新缓存增加互斥锁