如何解决Redis缓存雪崩、缓存穿透、缓存并发等问题?

缓存穿透很多项目在使用Redis或其他缓存框架的时候,都是先查询缓存,查询不的话再查询数据库,查到之后再放到内存中;如果一个key值本身就不存在,那么每一次都会查询数据库,也就是常说的【缓存穿透】。

应对方法:如果在Redis中查询不到,并且查询数据库也没有结果,那么就将这个key写入到Redis中,value=空,并设置一个超时过期时间,例如五分钟,那么五分钟以内的对这个可以的所有查询就可以拦截下来,如果数据库有key对应的数据了,那么五分钟后Redis中的缓存过期,会访问数据库并加载缓存;但是如果被恶意攻击,每次请求的key都不相同且不存在,那么依然会穿透到数据库;布隆过滤器:将可能存在的数据Hash到一个足够大的bitmap上,它可以告诉你 “某个key一定不存在或者可能存在”,一个一定不存在的数据会被bitmap拦截。

缓存雪崩很多时候,Redis中的缓存是要设置过期时间的,假如Redis中的数据,过期时间都设置成一样的,那么到了时间之后,全部缓存过期失效,下一秒所有的请求都会访问数据库,那么数据库可能因为访问量多大导致“崩溃”,这就是缓存雪崩。

应对方法:最暴力的解决办法,缓存不设置自动过期时间,只要缓存不崩,数据库就不会崩。

另外一个办法,就是让缓存过期时间不那么一致,比如一批缓存数据24小时后过期,那么就在这个基础上,每条缓存的过期时间前后随机1-6000秒(1-10分钟)。

缓存并发大多数时候,我们的程序访问Redis都不可能是单线程,那么当多个Client并发对Redis进行set key操作的时候,可能会产生一些问题;其实Redis本身是单线程的,这种时候会按照先后顺序进行操作;或者把操作放在队列中,按顺序执行;但比如这种情况:token过期,有两个线程都去重新获取token;线程1获取token1;线程2获取到token2,此时token1过期;线程1把token1放到Redis,再拿着token1去调用服务,发现过期了,继续去请求token3,此时token2过期;线程2把token2放到Redis,再拿着token2去调用服务,发现过期了,继续去请求token4,此时token3过期;... ...这就需要我们在更新缓存的时候,做一些控制了。

我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。

本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复

    作者信息

    标签TAG

    相关文章