【面试题】Redis缓存设计

news2025/1/20 16:31:22

文章目录

  • Redis缓存出现的问题
    • 🙎‍♂️面试官:什么是缓存雪崩?
    • 🙎‍♂️面试官:怎样解决缓存雪崩?
    • 🙎‍♂️面试官:什么是缓存击穿?
    • 🙎‍♂️面试官:怎样解决缓存击穿?
    • 🙎‍♂️面试官:什么是缓存穿透?
    • 🙎‍♂️面试官:怎样解决缓存穿透?
    • 🙎‍♂️面试官:说说常见的缓存更新策略?/ 数据一致性问题了解吗?
    • 🙎‍♂️面试官:为什么是先更新数据库,再删除缓存中的数据,不能颠倒吗?
    • 🙎‍♂️面试官:怎样保证更新数据库和删除缓存两个操作都能成功?
    • 🙎‍♂️面试官:Cache Aside 策略是万能的吗?
    • 🙎‍♂️面试官:「更新数据库 + 更新缓存」的方案会出现数据不一致,如何防止?

在这里插入图片描述

Redis缓存出现的问题

Redis是缓存数据库,我们经常需要把MySQL中的数据缓存到Redis中,来提高查询效率。

但是随之而来也会出现一些问题,比如缓存雪崩、缓存击穿、缓存穿透,以及数据库缓存一致性问题。

🙎‍♂️面试官:什么是缓存雪崩?

🙋‍♂答:

简名达意。雪崩,就是大量缓存数据在同一时间失效,或者Redis宕机。此时有大量的用户请求无法在Redis处理。直接访问数据库,导致数据库压力剧增,可能造成数据库宕机、等一系列连锁反应,最终整个系统崩溃,这就是缓存雪崩的问题。

🙎‍♂️面试官:怎样解决缓存雪崩?

🙋‍♂答:

针对大量数据同时过期而引发的缓存雪崩问题,常见的应对方法有下面这几种:

  • 均匀设置过期时间
    由于缓存雪崩是同一时间大量数据失效,那么给这些数据的过期时间加上一个随机数,这样就保证数据不会在同一时间过期。
  • 双缓存策略
    设置两个缓存,当主缓存失效,访问备用缓存的数据。当然,备用缓存的数据过期时间要相应的长一些。
  • 构建多级缓存
    增加本地缓存,在存储层前加一级屏障,保持服务的整体可用。

针对 Redis 故障宕机而引发的缓存雪崩问题,常见的应对方法有下面这几种:

  1. 通过主从节点的方式构建Redis高可用集群。
  2. 启用服务熔断或者请求限流机制。
    • 服务熔断,就是宕机就停止服务,直接返回错误。
    • 请求限流,就是只将少部分请求发送到数据库进行处理,再多的请求就在入口直接拒绝服务。

🙎‍♂️面试官:什么是缓存击穿?

🙋‍♂答:

缓存击穿可以认为是缓存雪崩的子集。

击穿,指的是某个热点数据过期,大量请求访问该热点数据,就无法从缓存中获取,导致MySQL服务器压力剧增,可能引发宕机等一系列问题,最终导致系统崩溃,就是缓存击穿的问题。

🙎‍♂️面试官:怎样解决缓存击穿?

🙋‍♂答:

对于缓存击穿,可以采取两种方案:

  • 互斥锁方案:防止大量请求访问热点数据。
    SET KEY VALUE [EX seconds] [PX milliseconds] [NX|XX]
    EX seconds − 设置指定的到期时间(以秒为单位)。
    PX milliseconds - 设置指定的到期时间(以毫秒为单位)。
    NX - 仅在键不存在时设置键。
    XX - 只有在键已存在时才设置。
    
    返回boolean为true表示语句执行成功,那么线程就拿到了锁,并且进一步对数据库进行操作。返回为false表示加锁失败,该线程要等待锁释放或者返回默认值或空值。
  • 后台线程异步更新。不给热点数据设置过期时间,当内存删除策略删除热点数据后,主线程先返回空值,之后通知后台线程异步更新缓存;具体实现可以采用定时任务/消息队列的方式来实现。

🙎‍♂️面试官:什么是缓存穿透?

🙋‍♂答:

缓存穿透,就是大量请求访问缓存和数据库中不存在的数据。当有这样的请求到来,服务器的压力剧增,这就是缓存穿透的问题。

一般都是业务误操作或者黑客攻击才会发生这种情况。

🙎‍♂️面试官:怎样解决缓存穿透?

🙋‍♂答:

  • 限制非法请求。在API入口处,判断请求参数是否合法,如果判断出是恶意请求,就直接返回空值,避免进一步访问缓存和数据库。
  • 设置空值或默认值。当发现缓存穿透的情况时,可以针对数据设置空值,这样后续请求就可以从缓存中查找到数据,而不用进入数据库查询。
  • 使用布隆过滤器。Redis 自身是支持布隆过滤器的。布隆过滤器可以用于检索该数据是否存在于数据库中。它的优点是空间效率和查询时间都比一般的算法要好的多。从而避免缓存穿透。在写入数据库数据时,使用布隆过滤器进行标记。

🙎‍♂️面试官:说说常见的缓存更新策略?/ 数据一致性问题了解吗?

🙋‍♂答:

使用缓存更新策略可以防止出现数据库与缓存数据不一致的情况。

最常用的缓存更新策略是Cache Aside策略。该策略的具体内容如下:

  • 在向数据库读取数据时,先从缓存中获取数据,如果缓存中没有数据,就从服务器获取数据。然后将数据写入到缓存,并且返回给用户。
  • 在向数据库写入数据时,先更新数据库中的数据,再删除缓存中的数据。【懒加载的思想】

Read/Write Through 策略。该策略原则是应用程序只和缓存交互,而更新的操作交给缓存自己代理。Redis不提供这种功能,所以不常用。

Write Back 策略。该策略的原则是先更新缓存,将缓存设置为脏,之后由缓存自己批量异步更新数据库。Redis没有异步更新数据库的功能,所以不常用。

🙎‍♂️面试官:为什么是先更新数据库,再删除缓存中的数据,不能颠倒吗?

🙋‍♂答:

这样才可以保证数据库和缓存的一致性。

缓存的写入速度普遍要快于更新数据库的操作,实际很难出现请求A的写策略更新完数据库又删除缓存后,请求B的读策略才更新缓存。一旦请求A删除了缓存,请求B就需要去数据库中读取数据,更新到缓存中,最终返回。

🙎‍♂️面试官:怎样保证更新数据库和删除缓存两个操作都能成功?

🙋‍♂答:

使用消息队列的重试机制。
消息队列RocketMQ版支持消息重试功能,即Consumer消费某条消息失败或消费超时,消息队列RocketMQ版会根据消息重试机制重新投递消息。消费的消息就可以是删除缓存的操作。确保两个操作都能成功。

kafka消息队列没有重试机制。

🙎‍♂️面试官:Cache Aside 策略是万能的吗?

🙋‍♂答:

Cache Aside 策略也是存在局限性的。先更新数据库,后删除缓存。这样在写多的场景下,缓存中的数据会被频繁的清理,进而造成缓存命中率过低。

如果业务对于缓存的命中率有要求,就需要使用「更新数据库 + 更新缓存」的方案,因为更新缓存不会存在未命中的情况。

🙎‍♂️面试官:「更新数据库 + 更新缓存」的方案会出现数据不一致,如何防止?

🙋‍♂答:

  • 在更新缓存时增加分布式锁,防止多个请求更新同一份缓存。但是不支持并发操作,效率会降低。
  • 更新缓存后给缓存增加较短过期时间,即使数据不一致,也会在短时间过期。

完。

来源:Redis设计与实践、小林Coding

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

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

相关文章

Nacos集群和持久化配置

1.Nacos集群 1.1.架构说明 官方文档 集群部署架构图 因此开源的时候推荐用户把所有服务列表放到一个vip下面,然后挂到一个域名下面 http://ip1:port/openAPI直连ip模式,机器挂则需要修改ip才可以使用 http://VIP:port/openAPI挂载VIP模式,直…

【TOOLS: Linux与windows及linux与linux之间文件传输常用方法及命令】

文章目录 1.1.1 Windows和VirtualBox(Ubuntu)之间文件穿传输方法1.1.2 SCP 文件传输方法1.1.3 FTP 文件传输方法 1.1.1 Windows和VirtualBox(Ubuntu)之间文件穿传输方法 1)设置 virtualbox 中的共享文件夹,用户可以在windows某个盘下创建自己的共享文件…

chatgpt赋能Python-python_6_66_666

Python 666666:学习Python的不同层次 Python是一种高级编程语言,被广泛用于机器学习、人工智能、web开发等领域。它简单易学,具有良好的可读性和可扩展性,因此受到众多程序员的喜爱。 在学习Python的过程中,我们可以…

python面向对象知识点

因为我之前学过Java,所以下文中的python面向对象知识点会和Java面向对象知识点比较记忆; python类的定义 python类的定义个其函数的定义格式相同,为此先复习函数定义格式: def add(num1, num2){return num1 num2 } 类定义格式…

自动构建之Makefile

链接: 自动构建之CMake Makefile Makefile是用于自动化构建软件项目的工具,Makefile的优点是简单、直接,可以直接使用make工具进行构建。但是,Makefile通常需要手动编写和维护,可能会导致跨平台和跨编译器的兼容性问题。 Makef…

【SVN内网穿透】远程访问Linux SVN服务

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

.Net Core 数据校验框架使用

为了提高响应速度和界面可用性,一般在客户端都会对用户填写的数据进行校验,这样不需要把数据发送到服务端,用户就知道数据填写错误。但是也不能完全依赖客户端的校验,不仅因为恶意用户可以绕过客户端校验直接向服务器发送请求&…

YOLOv5区域检测+声音警报

YOLOv5区域检测声音警报 1. 相关配置2. 检测区域设置3. 画检测区域线(不想显示也可以不画)4. 报警模块5. 代码修改5.1 主代码5.2 细节修改(可忽略) 6. 实验效果 本篇博文工程源码下载 链接1:https://github.com/up-up-…

图片模块封装

图片模块封装 一.如何更换图片框架二.Glide配置1.依赖: 三.策略模式构建者模式图片框架搭建1.ImageOptions图片参数设置2.IImageLoader接口以及实现子类3.图片加载策略4.ImageLoader5.ImageLoaderManager6.使用:四.Bitmap三级缓存二次采样五.长图大图处理 一.如何更…

华为OD机试真题 Java 实现【任务混部】【2023Q1 200分】

一、题目描述 公司创新实验室正在研究如何最小化资源成本,最大化资源利用率,请你帮他们解决一个任务混部问题: 有taskNum项任务,每个任务有开始时间(startTime ),结束时间(endTime…

Linux系统之cut命令的基本使用

Linux系统之cut命令的基本使用 一、cut命令介绍1. cut命令简介2.cut命令的由来 二、在Linux中命令帮助1. cut的help帮助信息2. cut的选项 三、cut的基本使用1. 指定字段的内容2. 使用分隔符打印文本内容3. 显示行中指定范围的字符 四、cut命令的日常使用1. 提取IP地址2. 提取本…

position:sticky-粘性吸附布局

一、描述 就是在一个滚动的容器里,将一个子元素设置为postion:sticky 在元素显示在可视区域内,显示的效果与position:relative 一致,当元素被滑动出可视区域外是,显示效果与position:fixed一致 二、注意事项 1、父元素需要存在滚动(overflow:auto&…

快速入门Springboot整合Datagpa操作数据库

简介SpringDatagpa Spring Data JPA是Spring Data家族的一部分,可以轻松实现基于JPA的存储库。 . JPA是ORM规范,Hibernate是JPA规范的具体实现,这样的好处是开发者可以面向JPA规范进行持久层的开发,而底层的实现则是可以切换的。S…

day5 套接字属性设置

选项的级别 SOL_SOCKET 该级别的选项只作用于套接字本身 SOL_LRLMP 该级别的选项作用于IrDA协议 IPPROTO_IP 该级别的选项作用于IPv4协议 IPPROTO_IPV6 该级别的选项作用于IPv6协议 IPPROTO_RM 该级别的选项作用于可靠的多播传输 IPPROTO_TCP 该级别的选项适用于流式…

信道通信基础 - 传输介质(双绞线、光纤)

文章目录 1 概述2 传输介质2.1 双绞线2.2 光纤 3 扩展3.1 网工软考真题 1 概述 2 传输介质 2.1 双绞线 双绞线:8 根铜导线每 2 根扭在一起(百兆用 4 根,千兆必须用 8 根)分类 2.2 光纤 光纤:利用光在 玻璃或塑料纤…

很长一段时间没有用Ubuntu,无法获得锁**,锁正由进程***持有

问题分析:意思就是有另一个进程占用了apt-get,因为Ubuntu锁的访问机制是互斥的,即同一时间只能允许一个进程占用,只需要将那个占用的进程强制删除掉就行了。 使用如下两条命令即可: sudo rm /var/lib/dpkg/lock-fron…

藏在大神们收藏夹里的实用工具类网站!

今天来给大家分享几个大神们推荐的,藏在收藏夹里的宝藏工具类网站 Toolfk https://www.toolfk.com/ 一款程序员的工具箱,里面包含非常多实用工具,不仅有各种程序相关功能,还有很多不懂程序人也能用的简易功能。PHP在线加密工具、…

docker-compose 搭建maven私服 nexus与配置

目录 创建文件目录 docker-compose.yml文件 登录 配置 创建阿里云代理仓库 配置仓库顺序 maven配置文件setting.xml配置 本地jar包部署 在linux上搭建 创建文件目录 mkdir -p /apps/minio/{config,data,logs} 赋权限 chmod -R 777 data docker-compose.yml文件 version…

按键中断实验和串口中断实验

目录 【1】按键中断实验 【2】串口中断实验 【1】按键中断实验 实验要求:STM32上电LED(PB0)灯灭 ,当检测到按键(PA8)按下时处理中断事件,变量i 扩展:知识点 响应优先级-》在两个中断…