redis使用场景
在Redis的使用场景中,如果Redis不仅仅是作为缓存使用也作为缓存数据库来使用的时候,那么使用Redis的步骤基本上是这样的:
先去Redis中查找数据
如果Redis中存在数据则返回或者更新数据,如果Redis中数据不存在则访问关系数据库例如Mysql(因为缓存数据最终要存到数据库比如mysql,可以使用定时任务在请求低估时候执行)
当从Mysql数据库中获取到数据之后再放入到Redis缓存中,这样以后都在缓存中进行数据读写
缓存穿透:
缓存穿透是指用户每次请求访问的key在redis中不存在并且数据库中也不存在的时候,因为数据库中也不存在所以缓存中会一直不命中也就是说查找不到,这样请求就会一直访问到存储数据库 (Mysql) 中去,当请求量超出数据库的承受压力时,便会导致数据库崩溃
缓存穿透会导致Redis缓存失去了缓存数据库的意义,当访问流量特别大的时候DB是扛不住的会直接崩溃掉,要是有人利用不存在的kev频繁攻击我们的应用,就导致出现安全漏洞。
缓存穿透解决办法:
接口层增加参数校验,例如: 对于查询id<0的直接拦截掉;
对空值缓存,从缓存和数据库中都没有的数据,这时也设置key只不过value设置为null,其过期时间会设置较短,如30秒 (设置太长会导致正常情况也没法使用) 。这样可以防止攻击用户反复用同一个id暴力攻击。
使用布隆过滤器,使用布隆过滤器存储所有可能访问的 key进行快速查询,不存在的 key直接被过滤,存在的 key 则再进一步查询缓存和数据库,当然它的缺点是有误识别率并且删除困难
进行实时监控: 对于redis缓存中命中率急速下降时,迅速排查访问对象和访问数据,将其设置为访问黑名单。
缓存穿透:
某些热点 key,在缓存过期的一瞬间,而此时又有大量请求访问该数据,由于此时缓存过期了,请求会直接访问数据库并回设到缓存中,造成瞬时数据库请求量大、压力骤增,严重时DB直接崩溃挂掉,这就是缓存击穿了。
缓存击穿解决办法:
提前设置热门数据到缓存中,或适当延长缓存中key过期时间。也可以对于热点key设置永不过期或者在java中设置一个后台线程一直给key续期。
添加加互斥锁。当热点key过期后,大量的请求涌入时,只有第一个请求能获取锁并阻塞此时该请求查询数据库,并将查询结果写入redis后释放锁。后续的请求直接走缓存.从缓存中读取数据 ->缓存中不存在数据一>获取锁->数据库读取数据->更新缓存数据-> 释放锁
缓存雪崩:
缓存雪崩指的是redis中存在缓存key,但是出现大量的热点key过期时间相同,在某一时刻,缓存中大量key过期,而此时大量高并发请求访问,会直接访问存储数据库,导致数据库崩溃。
缓存雪崩解决办法:
将热点key的缓存时间进行一定范围内随机,这样就可以将它们的过期时间打散。
使用锁或队列机制,使用锁或队列保证不会有大量线程一次性对数据库进行读写,从而避免大量并发请求访问数据库,但是效率会降低
对于热点key设置不过期或者后台线程续期
搭建Redis集群进行分布式部署,将热点数据均匀分布在不同的缓存数据库中,避免key全部失效问题
进行多级缓存设置,当一级缓存失效后,再去二级缓存查找二级缓存的时间相对较长,避免短时间内key过期