正常的访问流程
缓存穿透
客户端采用id<0或无穷的大的数,去请求数据,redis中数据不存在,会一直访问mysql查询。
此时,redis已经起不到缓存作用了,这就是穿透。(访问无效数据)
【短时间内大量访问不存在的数据,导致穿透redis直接访问数据库,造成数据库瓶颈】
解决方法:
没有值时,也保存redis 可以保存null (但可能保存数据增多溢出内存)
封禁对方ip(对方可以更改ip)
对参数进行校验,把非法参数过滤掉
布隆过滤器【最优】
缓存雪崩
数据保存在redis过期时间相同,当redis中数据过期,访问查询将全部进入mysql,可能造成mysql的瓶颈崩溃。(大量key失效)
【大量redis key 同一时间失效,导致请求访问到数据库,造成数据库瓶颈】
解决办法:
过期时间随机设置
定时任务重新设置过期时间
永不过期【不推荐,可能造成数据冗余,内存溢出】
缓存击穿
redis设置的过期时间失效,全部访问同时访问一个热key。并发量很多,同时访问,redis失效后,查询并发来到mysql。(热点key突然失效)
【一个热点的key失效,导致访问这个热点key的请求,直接访问数据库,造成数据库瓶颈】
解决办法:
加锁,分布式锁或者互斥锁
一般使用分布式锁,当第一个请求在redis中没有找到key时,访问mysql这时先上锁,其他没有拿到锁的请求,等待数据。第一个请求拿到数据后,放到redis中,其他数据等待后,再redis里拿到数据。