一个 Redis 的雪崩和穿透问题,小学妹画了个图,结果入职了(上)

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 阿粉的一个小学妹最近刚从某个小互联网公司跳槽,然后最近面试的挺多的,一个不善言语的小姑娘,技术还是 OK 的,本来之前是做 UI 的,但是时间长了,感觉没太大意思,所以就开始学了后端,然后从原有公司慢慢的转为了后端开发人,也就是我们所说的 “程序猿”,最近面试给阿粉谈了谈她的面试经验。阿粉比较印象深刻的一句话就是,我给你画个图,你看一下,这是对面试官说的,事情是什么样子的呢?

你了解 Redis 穿透和雪崩么?

为什么这么说,因为面试官当你说到 Redis 的时候,面试官问的现在已经不是 "你说一下 Redis 的几种数据结构" ,现在面试问的时候,很多都是对 Redis 的实际使用开始问了,比如说,

  • Redis 都有哪些架构模式?单机版,主从复制,哨兵机制,集群(proxy 型),集群(直连型)
  • 使用过 Redis 分布式锁么,它是怎么实现的?
  • 使用过 Redis 做异步队列么,你是怎么用的?有什么缺点?
  • 什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?

而阿粉的小学妹遇到的就是关于 Redis 的缓存穿透和雪崩问题了。这个问题学妹配合了一波自己的 UI 功底图加上口头的解释,于是成功的拿到了这个 Offer,也可能是因为小学妹比较美丽并且技术还过的去。所以,就准备入职了。

我们来看看小学妹到底画了什么图,让面试官问了一波之后就入职了。

缓存穿透

如图:图是阿粉找小学妹专门画出来的,大家看一下

63.jpg

既然我们看完图了,相信大家也都看到了什么是缓存穿透了,也就是说,在我们的缓存系统中,也就是 Redis 中,我们都是拿着我们的 Key 去 Redis 中去寻找 Value 中,如果说我们在 Redis 中找不到我们的数据之后,我们就会去数据库中去寻找我们的数据,如果只是单一请求的话,也不能算是个太大的问题,只能称之为击穿而已,但是如果说要是请求并发量很大的话,就会对我们的数据库造成很大的压力,这其实就称之为缓存穿透,而穿透出现的严重后果,就会是缓存的雪崩了,我们先说穿透,一会再说雪崩。

那么都会有什么情况会造成缓存被穿透呢?

  • 自身代码问题
  • 一些恶意攻击、爬虫造成大量空的命中。

如果有个黑客对你们公司的项目和数据库比较感兴趣,他就可能会给你整出巨多的一些不存在的ID,然后就疯狂的去调用你们的某项接口,这些本身不存在的 ID 去查询缓存的数据的时候,那就是压根没有的,这时候就会有大量的请求去访问数据库,虽然可能数据能支撑一段时间,但是早晚会让人家给你整的凉了。

那么应该怎么去解决缓存穿透的问题呢?

  • 利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试。
  • 采用异步更新策略,无论 Key 是否取到值,都直接返回。Value 值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
  • 提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的 Key。迅速判断出,请求所携带的 Key 是否合法有效。如果不合法,则直接返回。

布隆过滤器实际上是一种比较推荐的方式。

布隆过滤器的实现原理则是这样的:

当一个变量被加入集合时,通过 K 个映射函数将这个变量映射成位图中的 K 个点,把它们置为 1。查询某个变量的时候我们只要看看这些点是不是都是 1 就可以大概率知道集合中有没有它了,如果这些点有任何一个 0,则被查询变量一定不在;如果都是 1,则被查询变量很可能在。注意,这里是可能存在,不一定一定存在!这就是布隆过滤器的基本思想。

而当你说出布隆过滤器的时候,可能这才是面试官想要问你的内容,这时候你就得好好的和面试官开始聊聊什么事布隆过滤器了。

我们还是继续用大众都想看到的图解来解释布隆过滤器。

64.jpg

字符串 "Java" 在经过四个映射函数操作后在位图上有四个点被设置成了 1。当我们需要判断 “ziyou” 字符串是否存在的时候只要在一次对字符串进行映射函数的操作,得到四个 1 就说明 “Java” 是可能存在的。

注意语言,是可能存在,而不是一定存在,

那是因为映射函数本身就是散列函数,散列函数是会有碰撞的,意思也就是说会存在一个字符串可能是 “Java1” 经过相同的四个映射函数运算得到的四个点跟 “Java” 可能是一样的,这种情况下我们就说出现了误算。

另外还有可能这四个点位上的 1 是四个不同的变量经过运算后得到的,这也不能证明字符串 “Java” 是一定存在的。

而我们使用布隆过滤器其实就是提供一个能迅速判断请求是否有效的拦截机制,判断出请求所携带的 Key 是否合法有效。如果不合法,则直接返回。

而阿粉的小学妹给面试官解释了一波这操作之后,看样子,面试官对这个“程序猿”开始有点印象了,接下来就顺着问了,那什么事缓存的雪崩呢?

缓存雪崩

65.jpg

这时候也就是说,当我们有多个请求访问缓存的时候,这时候,缓存中的数据是没有的,也就是说缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常

他和穿透实际上相似但是又有所不同,相似的地方是都是搞数据库,不同的是缓存穿透是指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库

而解决缓存雪崩的策略也是比较多的,而且都是比较实用的。比如:

  • 给缓存的失效时间,加上一个随机值,避免集体失效。
  • 双缓存。我们有两个缓存,缓存 A 和缓存 B。缓存 A 的失效时间为 20 分钟,缓存 B 不设失效时间

双缓存策略比较有意思,当请求来临的时候,我们先从 A 缓存中获取,如果 A 缓存有数据,那么直接给他返回,如果 A 中没有数据,那么就直接从 B 中获取数据,直接返回,与此同时,我们启动一个更新的线程,更新 A 缓存和 B 缓存,这就是双缓存的策略。

上述的处理缓存雪崩的情况实际上都是从代码上来进行实现,而我们换个思路考虑呢,也就是从架构的方向去考虑的话,解决方案就是以下的几种了。

  • 限流
  • 降级
  • 熔断
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
存储 缓存 NoSQL
redis缓存雪崩、穿透、击穿
redis缓存雪崩、穿透、击穿
|
2月前
|
缓存 NoSQL 安全
【Redis】缓存穿透
【Redis】缓存穿透
41 0
|
2月前
|
缓存 NoSQL 数据库
探秘Redis读写策略:CacheAside、读写穿透、异步写入
本文介绍了 Redis 的三种高可用性读写模式:CacheAside、Read/Write Through 和 Write Behind Caching。CacheAside 简单易用,但可能引发数据不一致;Read/Write Through 保证数据一致性,但性能可能受限于数据库;Write Behind Caching 提高写入性能,但有数据丢失风险。开发者应根据业务需求选择合适模式。
292 2
探秘Redis读写策略:CacheAside、读写穿透、异步写入
|
2月前
|
存储 缓存 NoSQL
redis之缓存穿透,击透,雪崩~
redis之缓存穿透,击透,雪崩~
|
2月前
|
缓存 监控 NoSQL
redis 缓存穿透 击穿 雪崩 的原因及解决方法
redis 缓存穿透 击穿 雪崩 的原因及解决方法
|
12天前
|
缓存 NoSQL Redis
蓝易云 - 如何使用Redis来防止穿透、击穿和雪崩问题
1. 缓存雪崩:缓存雪崩是指缓存中的大部分数据同时失效,导致短时间内大量的请求直接打到数据库上。防止缓存雪崩的方法是,给每一个key设置一个随机的过期时间,这样可以保证不会有大量的key同时失效。
12 1
|
2天前
|
缓存 NoSQL Java
Redis系列学习文章分享---第四篇(Redis快速入门之Java客户端--商户查询缓存+更新+双写一致+穿透+雪崩+击穿+工具封装)
Redis系列学习文章分享---第四篇(Redis快速入门之Java客户端--商户查询缓存+更新+双写一致+穿透+雪崩+击穿+工具封装)
6 0
|
2月前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文介绍了缓存穿透问题在分布式系统和缓存应用中的严重性,当请求的数据在缓存和数据库都不存在时,可能导致数据库崩溃。为解决此问题,提出了五种策略:接口层增加校验、缓存空值、使用布隆过滤器、数据库查询优化和加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统稳定性的影响。
138 3
|
2月前
|
缓存 NoSQL 搜索推荐
Redis缓存雪崩穿透等解决方案
本文讨论了缓存使用中可能出现的问题及其解决方案。首先,缓存穿透是指查询数据库中不存在的数据,导致请求频繁到达数据库。解决方法包括数据校验、缓存空值和使用BloomFilter。其次,缓存击穿是大量请求同一失效缓存项,可采取监控、限流或加锁策略。再者,缓存雪崩是大量缓存同时失效,引发数据库压力。应对措施是避免同一失效时间,分散缓存过期。接着,文章介绍了Spring Boot中Redis缓存的配置,包括缓存null值以防止穿透,并展示了自定义缓存过期时间的实现,以避免雪崩效应。最后,提供了在`application.yml`中配置不同缓存项的个性化过期时间的方法。
|
2月前
|
缓存 NoSQL 算法
Redis 解决缓存雪崩 缓存穿透 缓存击穿(Redis使用必看)
Redis 解决缓存雪崩 缓存穿透 缓存击穿(Redis使用必看)
35 1