写点什么

缓存的世界 Redis(三)

用户头像
卢卡多多
关注
发布于: 2021 年 06 月 22 日

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 的考虑关于缓存击穿,穿透以及雪崩的,如果说考虑不周到,线上环境容易被打死,很容易出问题,

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

发布于: 2021 年 06 月 22 日阅读数: 5
用户头像

卢卡多多

关注

还未添加个人签名 2020.04.12 加入

还未添加个人简介

评论

发布
暂无评论
缓存的世界 Redis(三)