带你悄悄走进缓存redis的世界(三)

266 阅读4分钟

“这是我参与更文挑战的第18天,活动详情查看: 更文挑战

Redis缓存中实战

Redis作为一个高性能的缓存数据库,一直在Java后端作为数据领域占据着很大的分量,可以说Java后端的数据很大一部分的性能和用户的体验是由于Redis的缓存来掌握的,所谓得性能者得天下,我们比较羡慕高级的优化工程师,将服务器的优化很彻底;我们今天是来简单的了解一下Redis作为缓存常见的三种情况,这种情况会多数出现,也是你要使用Redis缓存要避免的问题;  那我们就开始吧,

Redis作为单线程的io多路复用,本身有数据库为16个,所以可以存储很多热点数据了;

缓存雪崩

  一般的电商公司的系统会将自己很多的热点数据存在Redis中,以供用户更快的拿到数据,这样可以既可以获得最新的优惠信息,也可以提供良好的用户体验。  但是这些数据的key--value数据是将数据直接作为一个键值对存在的,也就是说根据key-value寻找对应的value数据,;但是这个key是有过期时间的,比如是十分钟,7天等          如果说这些key在十二个小时直接刷新失效,可以将数据key全部失效,会导致所有的用户会直接访问DB,这样数据库的压力会特别大;

实例:

   当一个系统的数据十二个小时会直接将刷新,将key全部都过期,但是这时候要是有一个秒杀活动,可能数据用户会一下子提升很多,比如之前QPS(200M/S)-->一下子提升到五千,那那么多的人访问数据,Redis的key又全部失效,只能去访问数据库Mysql,这样的话,数据库一下会被打死(支撑不住),这样就算重启也无济于事,只能是等请求高峰过去;   上述大量的key因为过期时间同一时间失效,导致用户大量去访问数据库,导致数据库宕机的情况=====>缓存雪崩(大雪直接奔溃)

  (最近的高并发系统中,一般缓存出现能接受的QPS是5000), 我刻意看了下我做过的项⽬感觉再吊的都不允许这么⼤的QPS直接打DB去,不过没慢SQL加上分库, ⼤表分表可能还还算能顶,但是跟⽤了Redis的差距还是很⼤  解决方式:     使得每个key的失效时间是随机值,比如要在某个时间点刷新的话,可以加上随机时间值;就可以保证key不在同一时间大面积的失效(避免直接用户直接访问数据库)

 可以利用失效时间的不同--->从而从根本上解决缓存雪崩的问题;

Redis.setKey("key","value",12*3600+Random.nextInt(10000));

//表示的数据可以直接添加过期时间, 比如有一个关于分布式锁的setnx的解决方式;

缓存穿透:

  一般我们访问数据会优先去redis中查询,如果查询不到才回去DB中去,但是有一种情况是我们请求一个根本是不存在的数据,比如ID为-1,以为大多数的系统,ID都是自增的或者是UUID,为负数的基本见不到,当我用一个ID为负数的值去请求数据库,一直访问的话会导致高峰期(因为每次访问能绕开缓存redis),并发高点就直接挂了;(并发)

 解决方式:

  这里要对于调用的接口,传入的参数进行合法性的校验,如果不合法直接return开始;    比如ID<0,直接return, ,加强参数的校验和,以及接口调用的权限的开放;不相信的心态;

      从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应Key的Value对写为null、位置错误、  稍后重试这样的值具体取啥问产品,或者看具体的场景,缓存有效时间可以设置短点,如30秒(设置太 ⻓会导致正常情况也没法使⽤)。 这样可以防⽌攻击⽤户反复⽤同⼀个id暴⼒攻击,但是我们要知道正常⽤户是不会在单秒内发起这么多 次请求的,那⽹关层Nginx本渣我也记得有配置项,可以让运维⼤⼤对单个IP每秒访问次数超出阈值的 IP都拉⿊。

那你还有别的办法么?

还有我记得Redis还有⼀个⾼级⽤法布隆过滤器(Bloom Filter)这个也能很好的防⽌缓存穿透的发 ⽣,他的原理也很简单就是利⽤⾼效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不 存在你return就好了,存在你就去查了DB刷新KV再return。 那⼜有⼩伙伴说了如果⿊客有很多个IP同时发起攻击呢?这点我⼀直也不是很想得通,但是⼀般级别的 ⿊客没这么多⾁鸡,再者正常级别的Redis集群都能抗住这种级别的访问的,⼩公司我想他们不会感兴 趣的。把系统的⾼可⽤做好了,集群还是很能顶的     

缓存击穿:

  比如 一个高并发的热点数据key,在缓存中正在被大量用户请求,但是呢,这时候突然一瞬间,缓热点数据直接失效,key--->所有的并发都由Db来抗,一下子就崩溃了,表示热点数据失效,高流量一下打到具体的DB上来,;      

 解决方式:

   设置热点数据永远不过期。或者加上互斥锁就能搞定了

卢卡寄语

如果使用缓存的,就要考虑缓存失效的问题,Redis的考虑关于缓存击穿,穿透以及雪崩的,如果说考虑不周到,线上环境容易被打死,很容易出问题,

今天的分享就到这里了,晚安了