概念:使用缓存和数据库中都没有的数据去做请求,比如使用id=-1的数据去请求造成了穿透缓存,打在了数据库上,访问数量一多,导致数据库挂掉的现象
例子:某个网站做的好了,某同行嫉妒心爆棚,找了一个脚本去使用错误的id去冲击该网站。因为这个请求在数据库中没有,所以查不到数据,也就不会去缓存到redis中,所以每次请求都是请求的数据库,当数量一多,数据库就绷不住了,就直接挂了。导致这个网站都崩了。
解决方式:
方式一:如果请求穿透redis,直接到数据库查询,无论从数据库中返回什么值,都缓存到redis中,导致同一个非法id无法穿透redis
坏处就是可以换不同的id继续操作
方式二:当同一个ip多次造成缓存穿透,直接把它ip拉黑
和上面的一样,坏处就是可以换不同的ip继续操作
方式三:对参数的合法性进行校验,在判断参数不合法的时候直接return
方式四:使用布隆过滤器(最推荐)
概念:大量的redis缓存在同一时间全部失效,大量的key请求到数据库上导致数据库响应不及时,然后挂掉。
例子:某宝,双11的时候,用户基量特别大,难免会出现某一秒大量的数据被缓存到redis中,而这些数据的失效时间都是同一刻。假设2小时失效,2小时候这些数据就失效了,而这时又大量的用户还在访问,导致大量的请求请求到数据库上,它又绷不住了,直接GG。
解决方式:
方式一:设置缓存的失效时间,让他不要在同一时间失效。在设置缓存的时候,随机初始化它的缓存时间
方式二:当redis集群部署时,把热点key放到不同的节点上去,让这些热点的缓存平均分布在不同的redis节点上
方式三(暴力解决):不设置缓存时间,让它永远都不失效
方式四:设置一个定时任务,让他定时的去刷新这些缓存,在缓存失效之前把redis缓存重新写进去,再设置缓存时间
概念:突然某key失效,一瞬间大量该key的请求打到了数据库上,导致数据库响应不及时,然后挂掉
例子:某个网上拍卖,将数据存到了redis上,假设失效时间为2小时,好多人在哪里乒铃乓啷的竞价,2小时过去了,这个数据突然失效,而现在竞价还没结束,又是大量的数据直接请求到数据库上去,数据库又又又“炸”了。
解决方式:
方式一:设置缓存时间为永不失效(不推荐)
方式二:使用分布式锁,在redis去数据库查询数据时,加上一个锁,只有一个线程会抢到这个锁,只有这一个线程会操作数据库,其他线程都在redis中沉睡几毫秒,当去访问数据库的线程把数据查询后,数据库将数据缓冲到redis中,其他线程再去redis中查询数据,就不会导致大量请求打到数据库上导致数据库挂掉(推荐)