使用redis做缓存的时候,常遇见的几个问题,在这里记录一下他的解决方案
Redis缓存穿透
就是假如有个人一直做redis.get(“0”),而这个key又不存在于redis里,那一般程序里,就会当做缓存失效(key的有效时间过期了)去直接查询数据库。那这样压力就来到了数据库这边,数据库会返回一个空数据,redis假设没把这个空数据存储,下次请求过来就会循环这个过程,就会导致数据库一直做空查询,从而拖累数据库的性能。
解决方法其实就在上边的问题中,只要查询到redis没有,就直接去数据库查,不管有没有查出来数据,都直接存到缓存里,设置一个几分钟的过期时间,这样,就算有人一直用这种方法攻击你的服务器,也不过是几分钟查一下业务库的频率而已。
Redis缓存击穿
这个就是有一条缓存数据,刚好过了失效时间,key过期了,而恰巧有大量的用户请求进来,都去查询这个key。假设有十万请求过来了,那就是瞬间有十万个请求因为redis找不到而去查业务库,这压力就一下子到数据库这边了,很容易影响性能。
解决方法也简单,本质就是用redis实现分布式锁的逻辑。用setex,给这个key再加一个几分钟过期的key去查询业务库(给缓存加缓存),key的key存在,就直接返回当前key的值(哪怕当前查到的数据是空的,也返回,因为不到一秒后,第一个查这个key的请求,会给key加key,然后查业务库,然后把查询到的数据赋值到value上,然后把这个key的key直接删除,随后后边的请求的查询就都走这个新的缓存了。等于影响,就只有前边几十个请求返回空,但是随后后边的请求就没问题了)
Redis血崩
这个问题实质就是redis的缓存击穿的key*n,一瞬间有大量的key全失效了。
比较好的方法就是,这些key的失效时间不要设置成统一,类似不要全部设置成5分钟过期。可以过期时间再加一个随机数,错开过期时间就可。
有一次有个小老弟问我,假如redis服务挂了,有啥方法避免线上业务不受影响?
我想说,上边的三个问题和解决方案都是基于redis正常运行的情况下的,假如你的redis真的宕机了,你的唯一解决方案就是把redis重启回来。这就好像你再问我,服务器停了,有啥方法避免不......
Emmm,也可以让运维背锅,这也是一个解决方案,为啥redis就自己挂了.......
或者,弄redis集群,分布式部署,一个节点的redis挂了,其他节点的数据还在,还是可以恢复的。