某讯一面,感觉问Redis的难度不是很大

news2025/1/20 7:43:22

前不久,有位朋友去某讯面试,他说被问到了很多关于 Redis 的问题,比如为什么用 Redis 作为 MySQL 的缓存?Redis 中大量 key 集中过期怎么办?如何保证缓存和数据库数据的一致性?我将它们整理出来,跟大家一起来探讨如何回答这些问题,希望对大家有所帮助。

Redis 为什么这么快?

为什么用 Redis 作为 MySQL 的缓存?

Redis 除了做缓存,还能做什么?

使用 redis 分布式锁,如何合理设置过期时间?

Redis 单线程模型了解吗?

Redis 中大量 key 集中过期怎么办?

如何保证缓存和数据库数据的一致性?

Redis 为什么这么快?

Redis 内部做了非常多的性能优化,比较重要的有下面几点:

  1. Redis 基于内存,内存的访问速度比磁盘快很多;
  2. Redis 基于 Reactor 模式设计开发了一套高效的事件处理模型,主要是单线程事件循环IO 多路复用
  3. Redis 内置了多种优化过后的数据类型/结构实现,性能非常高。
  4. Redis 通信协议实现简单且解析高效。

扩展:那既然都这么快了,为什么不直接用 Redis 当主数据库呢?

  • 主要是因为内存成本太高且 Redis 提供的数据持久化仍然有数据丢失的风险。

为什么用 Redis 作为 MySQL 的缓存?

主要是因为 Redis 具备高性能高并发两种特性。下面来详细介绍一个高性能和高并发。(这个问题是个开放题,我的答案仅供参考)

高性能

假如用户第一次访问 MySQL 中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据缓存在 Redis 中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了,操作 Redis 缓存就是直接操作内存,所以速度相当快。

如果 MySQL 中的对应数据改变的之后,同步改变 Redis 缓存中相应的数据即可。

高并发

单台设备的 Redis 的 QPS(Query Per Second,每秒钟处理完请求的次数) 是 MySQL 的 10 倍,Redis 单机的 QPS 能轻松破 10w,而 MySQL 单机的 QPS 很难破 1w。

所以,直接访问 Redis 能够承受的请求是远远大于直接访问 MySQL 的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。

Redis 除了做缓存,还能做什么?

  1. 分布式锁:通过 Redis 来做分布式锁是一种比较常见的方式。通常情况下,我们都是基于 Redisson 来实现分布式锁。
  2. 限流:一般是通过 Redis + Lua 脚本的方式来实现限流。如果不想自己写 Lua 脚本的话,也可以直接利用 Redisson 中的 RRateLimiter 来实现分布式限流,其底层实现就是基于 Lua 代码+令牌桶算法。
  3. 消息队列:Redis 自带的 List 数据结构可以作为一个简单的队列使用。Redis 5.0 中增加的 Stream 类型的数据结构更加适合用来做消息队列。它比较类似于 Kafka,有主题和消费组的概念,支持消息持久化以及 ACK 机制。
  4. 延时队列:Redisson 内置了延时队列(基于 Sorted Set 实现的)。
  5. 分布式 Session:利用 String 或者 Hash 数据类型保存 Session 数据,所有的服务器都可以访问。
  6. 复杂业务场景:通过 Redis 以及 Redis 扩展(比如 Redisson)提供的数据结构,我们可以很方便地完成很多复杂的业务场景比如通过 Bitmap 统计活跃用户、通过 Sorted Set 维护排行榜。

使用 redis 分布式锁,如何合理设置过期时间?

Redis 单线程模型了解吗?

Redis 基于 Reactor 模式设计开发了一套高效的事件处理模型 ,这套事件处理模型对应的是 Redis 中的文件事件处理器(file event handler)。

由于文件事件处理器是单线程方式运行的,所以我们一般都说 Redis 是单线程模型。

面试官又问了一个小问题,感觉回答的不错

既然是单线程,那怎么监听大量的客户端连接呢?

Redis 通过 IO 多路复用程序 来监听来自客户端的大量连接(或者说是监听多个 socket),它会将感兴趣的事件及类型(读、写)注册到内核中并监听每个事件是否发生。

I/O 多路复用技术的使用让 Redis 不需要额外创建多余的线程来监听客户端的大量连接,降低了资源的消耗,这样使用的好处是非常明显的。

使用 redis 分布式锁,如何合理设置过期时间?

需要考虑如下几个因素:

  1. 任务执行时间:确保过期时间大于预期的最长执行时间,以免任务还在执行过程中锁就被自动释放,导致并发问题
  2. 锁自动续期:如果使用了支持锁自动续期的 Redis 客户端库(如 Redisson),在持有锁的线程还在执行任务期间,可以定期自动延长锁的有效期,这样可以减小因锁过期导致的并发问题。
  3. 锁竞争激烈程度:如果锁的竞争非常激烈,过期时间不宜设置得太短,否则可能会频繁触发锁的竞争,消耗更多资源。反之,如果锁的竞争不大,可以适当缩短过期时间,更快地回收锁资源。
  4. 死锁检测与处理:设定一个合理的最大等待时间,超过这个时间还没有释放的锁可以被认为是持有锁的客户端出现问题,可以通过监控和相应的逻辑来处理此类死锁。
  5. 网络延迟和异常恢复:考虑到网络不稳定等因素,过期时间还应该预留一部分用于处理网络延迟或客户端异常恢复的情况。过期时间太短可能导致客户端未能及时释放锁或重新获取锁。
  6. 锁释放的可靠性:使用 lua 脚本来保证解锁操作的原子性,同时结合 watch 命令或事务处理,以最大程度地确保锁在业务逻辑完成后能够正确释放,降低对过期时间依赖的程度。

Redis 中大量 key 集中过期怎么办?

首先回答 大量 key 集中过期可能出现的问题:

  • 请求延迟增加: Redis 在处理过期 key 时需要消耗 CPU 资源,如果过期 key 数量庞大,会导致 Redis 实例的 CPU 占用率升高,进而影响其他请求的处理速度,造成延迟增加。
  • 内存占用过高: 过期的 key 虽然已经失效,但在 Redis 真正删除它们之前,仍然会占用内存空间。如果过期 key 没有及时清理,可能会导致内存占用过高,甚至引发内存溢出。

之后再回答 可以采取的方案:

  • 1.尽量避免 key 集中过期: 在设置键的过期时间时尽量随机一点。
  • 2.开启 lazy free 机制: 修改 redis.conf 配置文件,将 lazyfree-lazy-expire 参数设置为 yes,即可开启 lazy free 机制。开启 lazy free 机制后,Redis 会在后台异步删除过期的 key,不会阻塞主线程的运行,从而降低对 Redis 性能的影响。

如何保证缓存和数据库数据的一致性?

其实感觉聊聊 Cache Aside 这个策略就可以了,细说的话没啥太大必要。

下面来说说 Cache Aside 策略:

Cache Aside 中遇到写请求是这样的,更新数据库,然后直接删除缓存。

但是必须是这两步都成功,才能解决缓存和数据库数据不一致的问题。

关于更新数据库成功,而删除缓存这一步失败的这种情况,是可能发生的,简单说有两个解决方案:

  • 缓存失效时间变短(不推荐,治标不治本):我们让缓存数据的过期时间变短,这样的话缓存就会从数据库中加载数据。用户会反馈在一段时间后,才能更新数据哦!!!

  • 增加缓存更新重试机制(常用):如果缓存服务当前不可用导致缓存删除失败的话,我们就隔一段时间进行重试,重试次数可以自己定。不过,这里更适合引入消息队列实现异步重试,将删除缓存重试的消息投递到消息队列,然后由专门的消费者来重试,直到成功。

恭喜你,面试通过!!!

就业陪跑训练营学员投稿

欢迎关注 ❤

我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。

没准能让你能刷到自己意向公司的最新面试题呢。

感兴趣的朋友们可以私信我,备注:面试群。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2279265.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DDD - 微服务落地的技术实践

文章目录 Pre概述如何发挥微服务的优势怎样提供微服务接口原则微服务的拆分与防腐层的设计 去中心化的数据管理数据关联查询的难题Case 1Case 2Case 3 总结 Pre DDD - 软件退化原因及案例分析 DDD - 如何运用 DDD 进行软件设计 DDD - 如何运用 DDD 进行数据库设计 DDD - 服…

闪豆多平台视频批量下载器

1. 视频链接获取与解析 首先,在哔哩哔哩网页中随意点击一个视频,比如你最近迷上了一个UP主的美食制作视频,想要下载下来慢慢学。点击视频后,复制视频页面的链接。复制完成后,不要急着关闭浏览器,因为接下来…

【STM32-学习笔记-14-】FLASH闪存

文章目录 FALSH闪存一、FLASH简介二、FLASH基本结构三、FLASH解锁四、使用指针访问存储器五、FLASH擦除以及编程流程Ⅰ、程序存储器全擦除1. 读取FLASH_CR的LOCK位2. 检查LOCK位是否为13. 设置FLASH_CR的MER 1和STRT 1(如果LOCK位0)4. 检查FLASH_SR的B…

微信消息群发(定时群发)-UI自动化产品(基于.Net平台+C#)

整理 | 小耕家的喵大仙 出品 | CSDN(ID:lichao19897314) 关联源码及工具下载https://download.csdn.net/download/lichao19897314/90096681https://download.csdn.net/download/lichao19897314/90096681https://download.csdn.net/download/…

FPGA产业全景扫描

随着芯片种类日益丰富、功能日益强大,人们不禁好奇:一块FPGA是如何从最初的概念一步步呈现在我们面前的? FPGA设计、FPGA原型验证/仿真、FPGA板级调试和应用,是FPGA从概念到应用的必经之路。本文将围绕这几个核心环节&#xff0c…

SW - 钣金零件保存成DWG时,需要将折弯线去掉

文章目录 SW - 钣金零件保存成DWG时,需要将折弯线去掉概述笔记备注END SW - 钣金零件保存成DWG时,需要将折弯线去掉 概述 如果做需要弯折的切割件,最好做成钣金零件。 最近做了几个小钣金(将钣金展开,建立新草图,在2…

git系列之revert回滚

1. Git 使用cherry-pick“摘樱桃” step 1: 本地切到远程分支,对齐要对齐的base分支,举例子 localmap git pull git reset --hard localmap 对应的commit idstep 2: 执行cherry-pick命令 git cherry-pick abc123这样就会将远程…

Excel重新踩坑6:工作实战总结之根据筛选条件求平均成绩

一、前言: 这个博客的实战场景:给了一组学生数据,这些数据中,有全市20个社区,1-9年级的学生各科成绩。要求按照各社区统计1-9年级的所有学生各科平均值。下面首先介绍会用到的一些函数,然后再简单说明实战…

【数据分析】02- A/B 测试:玩转假设检验、t 检验与卡方检验

一、背景:当“审判”成为科学 1.1 虚拟场景——法庭审判 想象这样一个场景:有一天,你在王国里担任“首席审判官”。你面前站着一位嫌疑人,有人指控他说“偷了国王珍贵的金冠”。但究竟是他干的,还是他是被冤枉的&…

SpringMVC 实战指南:打造高效 Web 应用的秘籍

第一章:三层架构和MVC 三层架构: 开发服务器端,一般基于两种形式,一种 C/S 架构程序,一种 B/S 架构程序使用 Java 语言基本上都是开发 B/S 架构的程序,B/S 架构又分成了三层架构三层架构: 表现…

通过idea创建的springmvc工程需要的配置

在创建的spring mvc工程中&#xff0c;使用idea开发之前需要配置文件包括porm.xml、web.xml、springmvc.xml 1、porm.xml 工程以来的spring库&#xff0c;主要包括spring-aop、spring-web、spring-webmvc&#xff0c;示例配置如下&#xff1a; <project xmlns"http:/…

二、点灯基础实验

嵌入式基础实验第一个就是点灯&#xff0c;地位相当于编程界的hello world。 如下为LED原理图&#xff0c;要让相应LED发光&#xff0c;需要给I/O口设置输出引脚&#xff0c;低电平&#xff0c;二极管才会导通 2.1 打开初始工程&#xff0c;编写代码 以下会实现BLINKY常亮&…

搭建一个基于Spring Boot的数码分享网站

搭建一个基于Spring Boot的数码分享网站可以涵盖多个功能模块&#xff0c;例如用户管理、数码产品分享、评论、点赞、收藏、搜索等。以下是一个简化的步骤指南&#xff0c;帮助你快速搭建一个基础的数码分享平台。 — 1. 项目初始化 使用 Spring Initializr 生成一个Spring …

迅为RK3576开发板Android 多屏显示

迅为iTOP-3576开发板采用瑞芯微RK3576高性能、低功耗的应用处理芯片&#xff0c;集成了4个Cortex-A72和4个Cortex-A53核心&#xff0c;以及独立的NEON协处理器。它适用于ARM PC、边缘计算、个人移动互联网设备及其他多媒体产品。 1.1 Android 多屏同显 iTOP-RK3576 开发板支持…

gather算子的CUDA编程和算子测试

知乎介绍参考添加链接描述 完整测试框架参考本人仓库 添加链接描述 gather算子的onnx定义参考添加链接描述,该算子的主要变换参考下图: 这里我们不妨以input = [A, dimsize, D], indices = [B,C], axis = 1举例子,此时对应的output形状是[A,B,C,D],并且根据gather算子定…

深度学习 Pytorch 张量的线性代数运算

pytorch中并未设置单独的矩阵对象类型&#xff0c;因此pytorch中&#xff0c;二维张量就相当于矩阵对象&#xff0c;并且拥有一系列线性代数相关函数和方法。 在实际机器学习和深度学习建模过程中&#xff0c;矩阵或者高维张量都是基本对象类型&#xff0c;而矩阵所涉及到的线…

Linux下构建OpenEuler22.03+Nginx的Docker镜像

1. 制作OpenEuler22.03的Docker镜像 首先&#xff0c;下载OpenEuler20.03的镜像压缩包&#xff1a; 下载链接为&#xff1a; https://mirrors.aliyun.com/openeuler/openEuler-22.03-LTS/docker_img/x86_64/openEuler-docker.x86_64.tar.xz 这里我们可以顺便下载一下对应的…

Coder星球-测试用例设计

项目介绍 Coder星球是一个前后端分离的开源技术交流平台&#xff0c;包括管理后台和web前端&#xff0c;旨在打造一个互相交流技术并共同进步的平台。 项目功能结构图 测试用例 1.登录 2.注册 3.文章发布 4.点赞 5.评论

wow-agent---task2使用llama-index创建Agent

一&#xff1a;创造俩个函数&#xff0c;multiply和add作为fuction calling被LLM当做工具来使用&#xff0c;实现计算一个简单的计算题&#xff1a; from llama_index.llms.ollama import Ollama from llama_index.core.agent import ReActAgent from llama_index.core.tools …

React的应用级框架推荐——Next、Modern、Blitz等,快速搭建React项目

在 React 企业级应用开发中&#xff0c;Next.js、Modern.js 和 Blitz 是三个常见的框架&#xff0c;它们提供了不同的特性和功能&#xff0c;旨在简化开发流程并提高应用的性能和扩展性。以下是它们的详解与比较&#xff1a; Next、Modern、Blitz 1. Next.js Next.js 是由 Ve…