Redis中的缓存穿透,缓存击穿,缓存雪崩,分布式锁

news/2024/11/28 17:26:20/

目录

一、缓存是什么?

二、缓存穿透

1.缓存穿透是什么

2.解决方案

三、缓存击穿

缓存击穿是什么

 2.解决方案

 四、缓存雪崩

1.什么是缓存雪崩

 2.解决方式

五、使用redis实现分布式锁

总结


一、缓存是什么?

缓存是数据交换的缓冲区,是储存数据的临时的读写性能高的场所。

通俗的来说,数据也就是前端与数据库交互的时候中间的缓冲区。我们可以将一些经常被从数据库中查询的数据存放到缓存中,从而来减轻数据库的访问压力

 

 我们经常使用redis作为缓存数据库使用,但是缓存虽好,但是在实际开发中,会出现各种各样的问题。最经常需要解决的问题就是:缓存穿透,缓存击穿,缓存雪崩。

 

二、缓存穿透

1.缓存穿透是什么

缓存穿透是指在企业开发中,可能会收到黑客的攻击,其中一种攻击手段就是,重复查询redis以及数据库中没有的值。当很多线程以及并发做这样的查询的时候,会造成数据库压力过大,造成数据库瘫痪。

如下图所示,用户重复访问一个不存在的key,redis中没有查询到也就频繁的访问数据库。如果是不怀好意的使用一些压力测试工具,短时间内做成百上千次这个动作很可能会导致我们数据库瘫痪。

 

2.解决方案

1.缓存空对象

在用户访问了一个不存在的key后,我们从数据库中访问也没有查询到值,就往缓存中存入一个空值,并设置较短过期时间。这样可以极大程度避免缓存穿透现象

 

2.使用布隆过滤器

布隆过滤器会将数据库中的值以二进制加密保存,并且在用户访问redis之前进行过滤,如果发现不存在的数据则会直接拦截请求。缺点是布隆过滤器的命中率比较低,依然有可能放过很多不合法请求进入redis中。

三、缓存击穿

缓存击穿是什么

缓存击穿经常发生在一个热门的key上,也就是这个key被经常访问。当这个key的定时时间到了,或者这个key突然在redis中消失了。这个时候外部极大的访问压力一下子进入MySQL中,大概率导致数据库直接瘫痪。

例如:在双11活动中,某个商品十分火热很多用户查询这个商品,如果突然这个商品在redis中的缓存消失了会导致大量请求直接到数据库中,导致数据库瘫痪

 2.解决方案

1.进行数据的预热

在热点事件来临之前,预先存入数据到redis中,并且设置长过期时间

2.实时监控

人为监控哪些数据访问量正在加速上升。实时调整过期时间

3.使用分布式锁

当缓存时效的时候,及时使用redis中的setnx设置一个锁,只有得到锁的线程才能进行访问操作。这样就避免了高并发场景下请求涌入数据库的事件发生。在下文会详细说明分布式锁的使用

 四、缓存雪崩

1.什么是缓存雪崩

缓存雪崩与缓存击穿很相似,区别在于缓存雪崩是大多数key同时失效,或者超时,导致数据库压力陡增。

 2.解决方式

1.将缓存失效的时候分散开

在给每一个key添加缓存的时候,都在原有固定过期时间上增加上一个随机值。保证多数缓存不会在同一时间失效

2.使用分布式锁,或者redis中的事务

redis中的事务是命令队列,与分布式锁的作用相同。防止不会有大量的线程对数据库一次性进行读写操作。这种方式不适合高并发的场景下使用

五、使用redis实现分布式锁

使用redis实现分布式锁的核心命令是 setnx,这个命令创建的数据只在键不存在时,才对键进行设置操作。

实施步骤:

使用redis先创建一个变量并且设置定时事件,值我们使用UUID生成。这样可以保证线程直接释放锁的时候不会冲突。在实际开发中如果不适用UUID表示锁可能会出现a线程释放了b线程的锁。

场景如下: a线程获取到了锁,进行业务,这个时候a线程突然卡住了。由于我们给锁设置了过时时间。这个时候b线程得到了新生成的锁。这个时候a线程重新工作了,业务完成后如果没有使用UUID表示锁就可能将b线程的锁释放。

 实例代码

 @Autowiredprivate StringRedisTemplate stringRedisTemplate;@GetMapping("/testRedis")public void testRedis(){//使用uuid对锁进行标识,防止互相释放锁String uuID = UUID.randomUUID().toString();String lockKey = "lock:id:"+uuID;//加锁并且设置过时时间为10秒Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("lock", lockKey, 3, TimeUnit.SECONDS);//如果成功加锁if (lock){String num = stringRedisTemplate.opsForValue().get("num");if (Strings.isBlank(num)){//如果查询到的值为空则直接返回return;}stringRedisTemplate.opsForValue().increment("num");//操作完成后释放锁//判断锁的idString lock1 = stringRedisTemplate.opsForValue().get("lock");if (lockKey.equals(lock1)){//如果锁的id为正确,则释放锁stringRedisTemplate.delete("lock");}else {//如果不正确,直接结束操作return;}}//如果没有得到锁else {try {Thread.sleep(1000);this.testRedis();} catch (InterruptedException e) {e.printStackTrace();}}}
}


总结

概述了redis缓存使用中可能出现的应用问题


http://www.ppmy.cn/news/615754.html

相关文章

南山驿站机器人_fc机器人大战钢铁之魂攻略

【游戏提示】 一,此次改版一共28关攻略集合多位玩家直播和改版作者资料并由本人亲自 通关测试拼凑而成! 二,这个版本有很多游戏坑,比较重要的都会标红说明,各位玩家要认真看,不完美攻略 要漏掉哪个环节&…

Redis——缓存穿透、缓存击穿、缓存雪崩、分布式锁

文章目录: 1.缓存穿透 1.1 什么是缓存穿透? 1.2 缓存穿透的解决方案 2.缓存击穿 2.1 什么是缓存击穿? 2.2 缓存击穿的解决方啊 3.缓存雪崩 3.1 什么是缓存雪崩? 3.2 缓存雪崩的解决方案 4.分布式锁 4.1 使用setnx del…

勇士传说--

1. 将准备好的素材--变成16像素点-- >Fliter Mode--Point -- >Compression(压缩)--None 2.将素材切割-- Sprite Editor--切割--可以按照像素点切割地图--切割人物可以数格数 3.制作背景-->窗口-->2D-->平铺调色板(Palette)-->拖到检…

计算机之魂

计算机之魂 - 关键四个知识 问题 1 朗道程序员分级法如何把程序员分成七级 朗道分级法 : 1 级最高 7 级最低 能够开创一个产业和一个学科的基础能够提出重要的计算机理论和实践中的新问题 , 并且解决他们 , 并且还能设计和实现别人无法实现的产品能够解决前人未解决的问题,并且…

我的世界服务器怎么修复锁链甲,我的世界锁链甲怎么制作

在我的世界中锁链甲可不是那么容易就能获得的哦!在游戏中,锁链甲是需要合成的,或者也可以用一定的几率能够刷出锁链甲,很多小伙伴们可能会问这个锁链甲要怎么进行制作呢?来和小编一起了解一下我的世界中锁链甲的制作步骤分享吧! 我的世界锁链…

说一下<黑暗之魂2>的缺点

前言 首先我特别喜欢魂类游戏 不太喜欢玩多周目, 我喜欢开新档玩, 而且, 每隔一段时间又会拿出来通一遍 通关次数:<黑暗之魂3>7次, <只狼>3次, <黑暗之魂2>2次, <黑暗之魂1>2次, <血源诅咒>3次半, <空洞骑士>3遍, <盐与避难所>3遍…

Redis的雪崩,击穿,穿透

雪崩是大面积的key缓存失效&#xff1b; 穿透是redis里不存在这个缓存key&#xff1b; 击穿是redis某一个热点key突然失效; 最终的受害者都是数据库 雪崩: 在高并发下&#xff0c;大量缓存在redis中的key在同一时间失效&#xff0c;导致大量请求直接请求到数据库上&#xff…

月之魂

月之魂 含情脉脉的朦胧 娇艳欲滴的美 像一场玄幻的梦境 轻轻舞动的娉婷 杨柳岸晓风拂面 依稀间追忆绵绵 何时逗惹了你 竟惩罚我万般思念