阿里面试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代表一个字符, ...
随机推荐
- 常见链表操作-链表中环的检测(JAVA实现)
问题如何检测一个单链表中是否有环,例如下图的例子. 解决思路1:快慢指针法这是最常见的方法.思路就是有两个指针P1和P2,同时从头结点开始往下遍历链表中的所有节点. P1是慢指针,一次遍历一个节点.P ...
- WAF集成:Acunetix和FortiWeb
Acunetix API使您有机会自动化任务以提高效率,尤其是在您可以加速与工作流其他组件的集成功能时.在此示例中,我们将在上一篇文章的基础上,向您展示如何在Bash脚本中使用Acunetix API ...
- SQL关联子查询
SQL关联子查询执行顺序: 1.先取到主查询中的相关数据,一次取一行主查询的数据 2.然后传入子查询,进行子查询 3.最后做主查询where筛选,注意子查询的where条件同样需要加在主查询后 参考: ...
- Hadoop知识总结
------------恢复内容开始------------ Hadoop知识点 Hadoop知识点什么是HadoopHadoop和Spark差异Hadoop常见版本,有哪些特点,一般是如何进行选择H ...
- Linux系统引导过程及排除启动故障
一.Linux操作系统引导过程二.系统初始化进程1.init进程2.Systemd3.Systemd单元类型三.排除启动类故障[1].修复MBR扇区故障(含实验过程)[2].修复GRUB引导故障●方法 ...
- MYSQL 连接举例
内连接:连接的多个数据必须存在才能连接select * from sjh14482条记录 create table sjha as ( select * from sjh1 limit 20 )sel ...
- java集合(1)-概述
Java集合类是一种特别有用的工具类,可用于存储数量不等的对象,并可以实现常用的数据结构,如栈,队列等,此外Java集合还可以用于保存具有映射关系的关联数组.java集合大致可分为Set,List,Q ...
- POJ2482 Stars in Your Window 题解
Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I stil ...
- 【动态规划】合唱队形 luogu-
分析 做两遍最长上升子序列,在遍历一下,取最大值. AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) m ...
- RHEL7配置端口转发和地址伪装
说明:这里是Linux服务综合搭建文章的一部分,本文可以作为Linux上使用firewalld做端口转发和地址伪装以及外网访问内网的参考. 注意:这里所有的标题都是根据主要的文章(Linux基础服务搭 ...