高级面试题
redis击穿与穿透
面试题目
redis 击穿、穿透区别,如何设计用例以及完成测试?
公司
- 阿里
- 顺丰
招聘类型
- 社招
解题思路
Redis 的基本概念
在没有添加 Redis 的时候,后端的查询流程是:
- 用户访问页面。
- 请求后端服务。
- 经过逻辑处理后,去数据库查询信息。
在添加 Redis 的之后,后端的查询流程是:
- 用户访问页面。
- 请求后端服务。
- 经过逻辑处理后,先去缓存(Redis)中进行查询,如果查到,则直接返回。
- 如果没有查到信息,则直接向数据库进行查询,查询到之后,数据库会讲数据信息同步到缓存(Redis)中,以便下次查询。
什么是击穿
当 Redis 某个热 key(比如首页广告)过期或者因为某些异常原因导致于无法从缓存中获取,导致大量的并发访问数据库而崩溃。
举个例子,比如双十一活动中,大量用户同时会查询首页的某个广告服务,正常查询流程中,我们的服务会直接在缓存中进行查询,查到了之后,返回给用户。
但是假设在这个过程中,这个广告服务的 key 过期,即这个缓存失效了,那么就会有大量的并发请求直接打到数据库中,导致数据库崩溃。
如果要复现这个测试场景,可以通过如下的测试步骤进行复现:
- 获取热 key 的列表(与运维沟通后获取)。
- 模拟热 key 失效的场景(比如登陆 Redis,直接将热 key 删除)。
- 查看研发是否有对应的容错机制(降级或熔断),从而能保证主要服务的正常运行。
什么是穿透
缓存穿透就是指:用户不断发起请求缓存和数据库中都没有的数据。
在正常的请求过程中,如果在缓存(Redis)中没有查到信息,则直接向数据库进行查询,查询到之后,数据库会讲数据信息同步到缓存(Redis)中,以便下次查询。
如果是缓存穿透的场景,比如传一个用户 id 为-1,这个用户 id 在缓存里面是肯定不存在的,因为每次请求数据库中也没有对应的数据信息,那么数据库也就不会同步到缓存(Redis)中,所以就会导致,每一次的请求,都会直接打到数据库上,导致数据库崩溃。
如果要复现这个测试场景,可以通过如下的测试步骤进行复现:
- 不停访问对应服务的接口,传递一个不存在的数据的查询请求。
- 查看研发是否有对应的容错机制,从而能保证不会有大量的请求打在数据库上。
答案
击穿是指当 Redis 某个热 key(比如首页广告)过期或者因为某些异常原因导致于无法从缓存中获取,导致大量的并发访问数据库而崩溃。如果要复现击穿的测试场景,可以通过如下的测试步骤:
- 获取热 key 的列表(与运维沟通后获取)。
- 模拟热 key 失效的场景(比如登陆 Redis,直接将热 key 删除)。
- 查看研发是否有对应的容错机制(降级或熔断),从而能保证主要服务的正常运行。
穿透是指用户不断发起请求缓存和数据库中都没有的数据,如果要复现穿透这个测试场景,可以通过如下的测试步骤:
- 不停访问对应服务的接口,传递一个不存在的数据的查询请求。
- 查看研发是否有对应的容错机制,从而能保证不会有大量的请求打在数据库上。
redis淘汰缓存与更新缓存
面试题目
你们的 Redis 使用的是淘汰缓存还是更新缓存,这两者有什么区别?请详细说明
公司
- 阿里
- 顺丰
招聘类型
- 社招
解题思路
首先,需要了解到在 Redis 中,缓存操作的读与写究竟是一个怎么样的流程
缓存操作流程-读
在添加 Redis 的之后,后端的查询(读)流程是:
- 请求后端服务。
- 经过逻辑处理后,先去缓存(Redis)中进行查询,如果查到,则直接返回。
- 如果没有查到信息,则直接向数据库进行查询,查询到之后,数据库会讲数据信息同步到缓存(Redis)中,以便下次查询。
缓存操作流程-写
在使用 Redis 之后,缓存的更新通常来说有两种方案:
- 淘汰缓存
- 更新缓存
什么是淘汰缓存
淘汰缓存的过程为:
- 更新数据库后,直接将缓存中的记录删除。
- 查询数据时,就无法从缓存中获取,只能从数据库获取。从数据库获取之后,同步更新缓存。
- 第二次查询数据时,即可从缓存中读取到最新的数据。
淘汰缓存的优点与缺点:
- 优点:操作简单,性能比较好
- 缺点:淘汰之后下一次请求就会读取数据库,至少会出现一个 cache miss。
什么是更新缓存
更新缓存的过程为:
- 由缓存的调用者,在更新数据库的同时更新缓存。
- 查询数据时,即可从缓存中读取到最新的数据。
答案
更新缓存的优点与缺点:
- 优点:基本不会出现cache miss的情况。
- 缺点:每次更新数据库都更新缓存,比较影响性能。
总结:在实际工作中,具体使用淘汰缓存还是更新缓存应该视情况而定。大部分情况,修改数据成本会高于增加一次cache miss,因此应该选用淘汰缓存。
怎么定位Redis缓存失效问题
面试题目
怎么定位 Redis 缓存失效问题(缓存坏了)?
公司
- 阿里
- Shopee
招聘类型
- 社招
解题思路
什么是缓存失效
简单来说就是由于各种原因导致的缓存不可用,而让原本应该打在 redis 的请求,直接打到了数据库上。
为什么会产生缓存失效
缓存失效对应的一般是以下这四个原因:
- 缓存过期
如果缓存不设计过期时间,那么就永久的占据一块内存,所以通常都会为缓存设计过期时间,一旦缓存过期,缓存数据则完全失效。
- 缓存更新
缓存的更新通常采用“淘汰策略”,一般更新完数据库之后,会直接把缓存淘汰掉,这样在下次用户请求中,如果没有在缓存中拿到信息就会去数据库读取,在向数据库读取成功之后,数据库则会反写到 redis。
但是在这个过程中,有一个极短的时间是没有缓存数据的,如果在这个极短的时间内,正好有大量的请求打进来,那么就会直接打到数据库上面。
- Redis 异常
Redis 异常的话,自然请求也是直接全部打到了数据库,而导致数据库崩溃。
- 网络异常
网络异常和 Redis 异常逻辑相同。
如何解决缓存失效问题
针对于由于各种情况可能产生的缓存失效问题,研发是如何解决的?通常有两种方式:
- 降级: 禁用部分接口,开放核心接口。
- 熔断: 禁用部分服务,开放核心服务。
很多同学看到这两种方式可能很难理解,如果禁用部分接口或服务的话,直接导致的问题就是应用的某些功能是不可用的,依然会影响到用户体验。但是其实这个过程,好比一个人被烧伤,他的手臂已经坏死,医生常常也会抛出这样两难的选择,如果不选择切除手臂,那么 48 小时之后,人就会因为感染而死亡。所以在这种情况下,大部分人都会选择“自断一臂”。
熔断和降级根本目的也是这个,有的用比完全瘫痪强,核心服务可用更比完全瘫痪强。
缓存失效相关的测试点
对于测试来说,除了考虑有哪些原因可能导致缓存失效,我们尽量规避外。还要检查了解到如果真的发生缓存失效的问题,研发是否有对应的解决方案,而不是缓存一失效,系统就瘫痪完全无法使用了。
比如在缓存失效下,可以使用如下的测试步骤,验证降级或者熔断功能的能力:
- 梳理系统中的核心服务列表(通常直接让研发给出对应列表)。
- 梳理服务中核心接口列表(通常直接让研发给出对应列表)。
- 模拟 Redis 失效,查看 redis 失效之后,这些核心服务和核心接口是否还能正常运行。
模拟 redis 缓存失效其实比较简单。其中,直接使用命令切断 redis 和服务的网络连接是最简单的方式。比如使用IPTABLES
和 TC
命令。以及阿里云的ChaosBlade
命令工具也可以非常容易的实现。
答案
面试碰到这个问题,可以从以下 3 个角度进行回答
- Redis 失效是什么?
- Redis 失效的原因是什么?
- Redis 失效研发应该在哪些方面做什么处理,以及测试是如何去测试的进行回答。
Redis缓存应用场景
面试题目
- Redis缓存应用场景
公司
- 某金融公司
招聘类型
- 社招
答案
什么是 Redis
Redis 是一款开源的缓存数据库,它具有以下特点:
-
读写性能优异(基于内存、IO 的多路复用+单进程)
-
数据类型丰富(k-v,list,set,zset,hash 等数据结构的存储)。
-
Redis 支持数据的备份。
-
数据自动过期。
-
发布订阅。
-
分布式。
基于这样的特点,在查询数据的时候,使用与不使用Redis的流程也是完全不一样的。
首先我们先来看在不使用 Redis 进行查询操作的时候,后端的查询流程是:
-
1、用户访问页面。
-
2、请求后端服务。
-
3、经过逻辑处理后,去数据库查询信息。
在添加 Redis 之后,后端的查询流程是:
-
1、用户访问页面。
-
2、请求后端服务。
-
3、经过逻辑处理后,先去缓存(Redis)中进行查询,如果查到,则直接返回。
-
4、如果没有查到信息,则直接向数据库进行查询,查询到之后,数据库会讲数据信息同步到缓存(Redis)中,以便下次查询。
Redis 的应用场景
从以上 Redis 的特点我们可以看出,它适宜的应用场景主要包含:
-
读多写少,并发强的场景,比如秒杀,明星热点。
-
有时间性的业务场景,比如短信验证码。
-
对有序集合数据类型排序,例如排行榜(有序集合数据类型)。
-
对于时效性要求不高,但是数据库请求较多的场景,比如计数器、社交网络。
-
Session 会话缓存。
-
消息系统(较少,更多使用专业的消息队列中间件)。
-
单线程的特点可以天然用作分布式锁。(开发关注)