阿里面试Redis常考问题
一提到Redis缓存,我们不得不了解的三个问题就是:缓存雪崩、缓存击穿和缓存穿透。这三个问题一旦发生,会导致大量的请求直接请求到数据库层。如果并发压力大,就会导致数据库崩溃。那p0级的故障是没跑了。
今天我们就来详细的了解这个三个问题诱因以及如何解决。
废话不多说,我们直接开搞!!!
一、缓存雪崩
什么是缓存雪崩?缓存雪崩就是大量请求无法在redis缓存中进行处理,而是直接发送到了数据库层,使得数据库压力陡增。就好像redis一下子突然失效了一样。一般造成缓存雪崩主要有两个原因,我们来一一分析一下。
1.缓存中大量数据同时过期
缓存中大量数据同时过期,就会导致大量请求无法在redis缓存层面进行处理。具体来说,就是给redis中大量数据设置了相同的过期时间,一旦它们同时失效,应用就会把请求直接发送给数据库,直接从数据库中读取数据。如果应用的并发量很大,那数据库的压力就会很大。如下图所示:
针对大量数据同时失效带来的缓存雪崩问题,我们一般采取以下两种解决方案。 (1)我们在开发过程中要避免给大量数据设置相同的过期时间。我们可以在给数据设置过期时间时给时间加一个很小的随机数,这样不同数据的过期时间就会有所差别,但差别也不会太大,保证数据在一定范围内过期,从而满足业务层要求同时过期的需要。 (2)服务降级。所谓的服务降级,是指发生缓存雪崩后,针对不同的数据采取不同的策略。
- 当业务访问非核心数据时(例如商品属性信息),我们直接返回预定义的信息。
- 当业务访问的是如库存数据等核心数据时,仍然允许查询缓存,如果缓存缺失,也可以从数据库中继续读取。
这样一来,只有部分过期的数据会访问数据库,所以数据库压力就没那么大。
2.Redis实例发生故障
当Redis实例发生故障,那就相当于缓存已经废掉了,所以大量请求会直接请求数据库,造成数据库压力变大,甚至宕机。针对这种情况发生的缓存雪崩,我们有以下两种处理方式。 (1)在业务系统侧实现服务熔断或请求限流机制 所谓的服务熔断,就是指在发生缓存雪崩时,为了防止大流量直接打到数据库,我们会暂停对缓存系统的访问。当上层应用访问缓存时,缓存接口不会去访问Redis实例,而是直接返回。等redis恢复后,再允许应用程序请求缓存系统。这样就会避免因为redis缓存宕机,导致数据库压力陡增的情况。
服务熔断虽然可以保证数据库不被崩溃,但是暂停了整个服务的访问,对业务的影响范围大,为了减小对上层服务的影响,我们一般采用请求限流。请求限流是指业务系统去控制每秒进入系统的请求数,避免过多的请求被发送到数据库。比如正常运行时,业务系统每秒进入的请求是1万个,其中有80%在缓存中就可以处理了,有20%会去数据库中处理。一旦发生缓存雪崩,100%的流量就会请求数据库,为了不造成数据库崩溃,我们就可以启动请求限流机制。业务系统只允许30%的流量进入,而70%的流量被拒绝服务。这也是目前主流大厂常用的方法,比如在某个明星爆出大瓜后,我们刷微博经常刷不出来,多刷几次就能进入,那就是因为做了服务降级。只允许一部分流量进入。
(2)使用高可靠集群
我们可以通过主从节点来部署高可靠的Redis集群。当主节点挂掉后,从节点还可以切换成主节点。
二、缓存击穿
缓存击穿是指针对某个热点数据,无法在缓存中进行处理,然后访问该数据的大量请求,一下子都发到后端数据库中,导致数据库压力激增。对于缓存击穿的情况,经常发生在热点数据过期失效时。
为了避免这种情况发生,最常采取的措施就是对于访问特别频繁的热点数据,我们就不设置过期时间了。这样一来,对热点数据的访问,都可以在缓存中进行。
三、缓存穿透
缓存穿透是指要访问的数据既不在缓存中,也不在数据库中,会导致请求缓存时,发生缓存缺失,然后请求数据库,发现数据库中也没有需要的数据。这样一来,缓存就成了“摆设”,如果有大量的这种请求,就会给数据库带来很大的压力。
这个问题一般都是黑客进行恶意攻击造成的。为了避免这种问题发生,我们有三种解决方式。
1、缓存空值或者缺省值
一旦发生缓存穿透,我们就可以在redis中设置一个空值或者给定的某个缺省值。这样,业务应用的后续这种请求,都可以命中缓存。这样就避免了把大量请求发送给数据库了。
2、使用布隆过滤器来快速判断数据是否存在
这里我们先来解释一下什么是布隆过滤器。
布隆过滤器由一个初值都为0的bit数组和N个哈希函数组成,可以用来快速判断某个数据是否存在。当我们想标记某个数据存在时,布隆过滤器会通过三个操作来完成标记:
- 首先,使用N个哈希函数,分别计算数据的哈希值,得到N个哈希值。
- 然后把这N个哈希值对bit数组的长度取模,得到每个哈希值在数组中的位置。
- 最后,我们把对应位置的bit位设置为1,这样就完成了布隆过滤器中标记数据的操作。
如果数据不存在,也就是我们没有用布隆过滤器标记过,bit数组对应的bit位为0。 当我们需要判断某个数据是否存在时,我们就执行上面的计算过程,我们先求出这个数据对应的hash值,然后取模,然后去bit数组查这N个位置上的bit值。只要这N个bit值有一个不为1,就表明这个数据没有被标记过。 基于布隆过滤器的快速检测特性,我们可以把数据写入数据库时,使用布隆过滤器做个标记,当缓存失效后,上层应用查询数据库时,可以通过查询布隆过滤器快速判断数据是否存在。如果不存在,就不用在去数据库中去查了。这样一来,即使发生缓存穿透,也不会对数据库造成压力。
3、业务层对请求进行检测
缓存穿透发生的原因主要就是恶意请求访问不存在的数据,所以业务层接受到请求后,一定要进行合法性检测,把恶意请求给过滤掉,这样就可以避免缓存穿透的问题了。
今天我们就聊到这里,如果感兴趣,记得关注一波公众号【程序员学长】,有你意想不到的收获哦。

阿里面试Redis常考问题的更多相关文章
- 害...原来阿里面试Redis最常问的是它呀
一提到Redis缓存,我们不得不了解的三个问题就是:缓存雪崩.缓存击穿和缓存穿透.这三个问题一旦发生,会导致大量的请求直接请求到数据库层.如果并发压力大,就会导致数据库崩溃.那p0级的故障是没跑了. ...
- http面试笔试常考知识点(二)
接上一篇随笔 1. https协议为什么比http安全? 内容加密:建立一个信息安全通道,确保信息传输安全: 身份认证:确保网站的真实性: 数据完整性校验:防止内容被第三方冒充或者篡改 2.常见状态码 ...
- Java面试2018常考题目汇总
一.JAVA基础篇-概念 1.简述你所知道的Linux: Linux起源于1991年,1995年流行起来的免费操作系统,目前, Linux是主流的服务器操作系统, 广泛应用于互联网.云计算.智能手机( ...
- http面试笔试常考知识点(一)
1.什么是http HTTP是客户端和服务器端请求和应答的标准.通过使用Web浏览器.网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求.(我们称这个客户端)叫用 ...
- 面试中常考的字符串操作方法大全,包含ES6
原文链接:http://caibaojian.com/js-string.html 一.charAt() 返回在指定位置的字符. var str="abc" console.log ...
- PHP面试常考内容之Memcache和Redis(2)
你好,是我琉忆.继周一(2019.2-18)发布的"PHP面试常考内容之Memcache和Redis(1)"后,这是第二篇,感谢你的支持和阅读.本周(2019.2-18至2-22) ...
- PHP面试常考内容之Memcache和Redis(1)
你好,是我琉忆.继上周(2019.2-11至2-15)发布的"PHP面试常考内容之面向对象"专题后,发布的第二个专题,感谢你的阅读.本周(2019.2-18至2-22)的文章内容点 ...
- Java面试题中常考的容易混淆的知识点区别
以下是我收集的Java编程里各种区别,供Java学习爱好者参考,这些区别都是每次Java面试中常考的,大家好好掌握,如有失误请留言指出.想要获取Java详细全套学习资料请到上海尚学堂官网获取. 1.H ...
- C/C++求职宝典21个重点笔记(常考笔试面试点)
这是我之前准备找工作时看<C/C++求职宝典>一书做的笔记,都是一些笔试面试中常考的重点难点问题,但比较基础,适合初学者看. 1. char c = '\72'; 中的\72代表一个字符, ...
随机推荐
- 浅读tomcat架构设计之tomcat生命周期(2)
浅读tomcat架构设计和tomcat启动过程(1) https://www.cnblogs.com/piaomiaohongchen/p/14977272.html tomcat通过org.apac ...
- python之struct详解
python之struct详解 2018-05-23 18:20:29 醉小义 阅读数 20115更多 分类专栏: python 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议 ...
- mybatis框架的第二天
一.mybatis的基础crud的操作 先在接口中,写对应的方法名称,返回类型,访问符. 之后在映射配置文件中,写具体的实现 二.mybati中crud的细节 1.模糊查询 这是接口中 这是xml中 ...
- TransE 算法学习笔记
http://yaoleo.github.io/2017/10/27/TransE算法的理解/ tranE是在模型中嵌入知识图谱等三元组类的一个方法,就像是句子利用词典嵌入一样.
- 2021最新WordPress安装教程(三):安装WordPress详细步骤
前面已经通过< 2021最新WordPress安装教程(一):Centos7安装Apache>和< 2021最新WordPress安装教程(二):配置PHP和MySQL>两篇文 ...
- YAOI Round #3 题解
前言 比赛链接: Div.1 : http://47.110.12.131:9016/contest/7 Div.2 : http://47.110.12.131:9016/contest/8 Div ...
- python03篇 字符串常用方法和文件操作(一)
一.字符串常用方法 s1 = ' abcsfsfaadfdd ' s = s1.strip() print(s) print(len(s.strip())) print(s.count('a')) # ...
- Scala学习——模式匹配
scala模式匹配 1.基础match case(类似java里switch case,但功能强大些) object MatchApp { def main(args: Array[String]): ...
- Java基础之反射生成JDK动态代理
在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口.通过这个类和接口可以生成JDK动态代理类或动态代理对象. JDK动态代理例子: / ...
- 微信小程序云开发-云函数-创建云函数
一.检查云函数环境 检查云函数环境时候,鼠标右键点击查看当前环境.如果存在多个云开发环境,要确保云函数的当前环境要与app.js中evn的环境值一致. 如果不一致,则鼠标右键切换当前云开发环境.(如果 ...