4、Redis应用问题解决

迷人的老约翰 2021-08-03 12:43:54 18530 0 0 0

redis雪崩

1、数据库压力变大,应用访问变慢,访问redis堆积过大,导致全部崩溃

问题:

​ 1、在极少时间段,查询大量key的集中过期情况

解决方案

(1)构建多级缓存架构:nginx缓存 + redis缓存 +其他缓存(ehcache等)

(2)使用锁或队列:
用加锁或者队列的方式保证来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。不适用高并发情况

(3) 设置过期标志更新缓存:

记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际key的缓存。

(4) 将缓存失效时间分散开:

比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

redis穿透

1、应用服务器压力变大

2、访问缓存获取不存在数据,redis命中率降低

3、redis没有这个数据,则一直查询数据库

redis查询不到数据库,

出现很多的非正常的url访问

多是出现黑客攻击,恶意攻击

目的不是获取数据,是让服务器崩溃

解决方案

1、对空值作缓存,

​ 如果一个查询返回的数据为空(不管是数据是否不存在),我们仍然把这个空结果(null)进行缓存,设置空结果的过期时间会很短,最长不超过五分钟

2、设置白名单

​ 使用bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次访问和bitmap里面的id进行比较,如果访问id不在bitmaps里面,进行拦截,不允许访问。

3、布隆过滤器

​ (1) 是1970年由布隆提出的。它实际上是一个很长的二进制向量(位图)和一系列随机映射函数(哈希函数)。

布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。)

将所有可能存在的数据哈希到一个足够大的bitmaps中,一个一定不存在的数据会被 这个bitmaps拦截掉,从而避免了对底层存储系统的查询压力

4.实时监控

​ 当发现Redis的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制服务

redis击穿

1、数据库的访问压力瞬间加大

2、redis里并没有出现大量key过期

3、redis正常运行

原因:

​ 1、redis中某个key,但是这个key是热点key,redis就去查数据库,热点查询,就让数据库压力过大

解决问题:

​ 1、**预先设置热门数据:**在redis高峰访问之前,把一些热门数据提前存入到redis里面,加大这些热门数据key的时长

​ 2、**实时调整:**现场监控哪些数据热门,实时调整key的过期时长

​ 3、使用锁

​ 肯定能解决问题,但是会拉低效率

​ (1) 就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db。

​ (2) 先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX)去set一个mutex key

​ (3) 当操作返回成功时,再进行load db的操作,并回设缓存,最后删除mutex key;

​ (4) 当操作返回失败,证明有线程在load db,当前线程睡眠一段时间再重试整个get缓存的方法。

图片alt

分布式锁

问题描述:

​ 随着业务发展的需要,原单体单机部署的系统被演化成分布式集群系统后,由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的Java API并不能提供分布式锁的能力。为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题!

分布式锁主流的实现方案:

基于数据库实现分布式锁

基于缓存(Redis等)

基于Zookeeper

每一种分布式锁解决方案都有各自的优缺点:

性能:redis最高

可靠性:zookeeper最高
这里,我们就基于redis实现分布式锁

解决方案:

setnx u1 100 #创建锁
dl ui		#释放锁

给锁设置过期时间

expire ui 10  #过期就失效

这不是一个原子操作,如果在两个命令之间出现bug之后,就无法设置时间

使用原子命令

#         上锁  过期时间
set urs 10 nx  ex 13

代码情况下!
在高并发情况下,是不是需要给锁设置过期时间,让锁释放资源?
如果在一个人释放了锁的时候,报错了是不是会发生死锁?
给redis设置了10s过期时间后,,高并发下,第一个人进来拿到了锁,然后执行了5s,这个时候key并没有释放,第二个人进来又拿到锁了,假设执行了8s,第一个key执行完释放了,第三个人来又拿到了锁,执行了3s,等等操作,会不会发生每个人都拿到了前一个人的锁?

这个时候使用到
分布式锁中的王者方案-Redisson
路灯
https://www.cnblogs.com/jackson0714/p/redisson.html