看完包你搞懂Redis缓存穿透、击穿和雪崩!!!说到做到

发布时间 2023-10-10 23:49:59作者: Melo70000

缓存穿透

缓存穿透是指当用户对Redis发出无效或者不存在的数据信息操作时,这条数据在Redis中不存在,Redis就会在MySQL数据库中查询,可时无效的信息在mysql数据库中也不存在,就会造成Redis一直查询MySQL,对MySQL造成极大压力

解决方式

方式一:返回缓存空值

这种方式有点像“以牙还牙”,对于你的不存在信息,Redis没有就先会查MySQL,MySQL也没有就为你返回一个空值,虽然是空值,但是我至少返回了。

但是这种方式是存在却缺陷的,举个例子:

比如说有个黑客对你的Redis发出来查询 id=-1 的信息,我们知道,id都是大于等于0的,不过好在你有返回空值的方式,驳回了他“无理的请求”,以后他在输入id=-1,Redis直接记住了,直接驳回。

但是这时候这名黑客 接连输入了 id=-2、-3、-4...,这下Redis傻了,对于这么多“无理的请求”,只好不断去问“大哥MySQL”。

大哥MySQL也烦了,就崩溃了。Redis也存了一肚子的空值

所以,若是有不同形式的无效信息,redis需要一直查询MySQL,MySQL没有后返回大量的空值在Redis中。你可得记住,空值不是空,空值也是值。

方式二:布隆过滤器

布隆过滤器是一种过滤器,本质上布隆过滤器是一种基于概率的数据结构,比较巧妙的概率性数据结构,特点是高效的插入和查询。可以用来告诉你“某样东西一定不存在或可能存在”

注:布隆过滤器一定可以判断不存在,但是对判断存在会有误差

缓存击穿

缓存击穿是指 Redis 缓存中有一些的热点数据 key 同时过期失效,或有一些非热点数据 Key 突然有大量的并发访问请求,这样会导致大量的并发请求直接穿透 Redis 缓存,涌入MySql数据库,巡检增大数据库的访问压力,甚至崩溃

解决方式

方式一:永不过期

就是设置 key 永不过期,就不会出现大量 key 过期失效的问题, 优点是维护简单,缺点是占用空间。且对于非热点数据的高并发访问无效

方式二:加锁

对于 Redis 缓存中 key 过期时,在 key 要查询 MySQL 数据库的时候加锁,这时只能让第一个请求进行查询数据库,然后把从数据库中查询到的值存储到 Redis 缓存中,对于其他的相同的 key 查询,可以直接从 Redis 缓存中获取即可

缓存雪崩

缓存雪崩是指在某一个时间段内,Redis缓存突然宕机或大量的 key 集中过期失效,如果这个时间段内有大量请求,而查询数据量巨大,所有的请求都会达到Mysql 数据库,数据库的访问量会暴增,引起数据库崩溃

解决方案

下图所示:

  • 图1的解决方式就是扩展redis的数量,防止大量数据涌入或单个redis服务器的崩坏。
  • 图2是当缓存已经失效时,通过加锁和队列来限制数据流量降低操作级别
  • 图3的目的将可能访问的数据提前放入redis中
  • 图4就是设置多个过期时间,以便于redis中的数据不会在同一时间全部失效

总结区分

上面的内容中若是不小心,很容易就会搞混淆。比如名字上很难区分穿透和击穿,概念上击穿和雪崩又有点相似。没事,看完下面保证你明明白白:

首先是穿透和击穿,我们从直觉上来说,击穿是不是比穿透跟尖锐一点

没错,你的感觉是对的。

我很喜欢举个例子:

你走在路上,遇到一个人对你突然无理取闹。

你只是会觉得这人神经病吧?!但是你对于他这种”无理的语言“,左耳朵进,右耳朵出,他的话只是穿过你的耳朵。结合上述穿透的例子,有感觉没?

但是如果你走在路上,有人对你的眼睛扔了个小石头。如果你平时戴眼镜,用的力气大一点就会击穿你的眼镜玻璃...

没事,不要紧张,只是个例子。

这说明保护眼睛十分重要的,尤其是作为程序员的我们,看完这篇就可以休息一下眼睛了。

这下应该可以深刻的体会到两者区别了吧

其次是击穿和雪崩

对比一下概念,这两个整的是太像了,感觉都是Redis中数据失效,直接去查MySQL数据库的。

我们还是用心感觉一下两个词,如果说击穿是尖锐的,那么雪崩就和他的名字一样

感觉上是不是雪崩就比击穿范围要大,击穿可以是面,但在雪崩面前,他就是点。

击穿的重点是,我的操作的信息本该打到Redis上的,可是Redis中存的过期了,打穿了。

雪崩的重点是,Redis本是缓存系统假设缓存了100条,我突然查了10000000条数据进去,不崩才怪。

创作不易,转载可私信。未经同意禁止转载!!!