【Java面试】一、Redis篇(上)

文章目录

  • 0、准备
  • 1、缓存穿透:不存在的key
  • 2、缓存击穿:热点key过期
  • 3、缓存雪崩:大批key同时过期
  • 4、双写一致性
    • 4.1 要求高一致性
    • 4.2 允许一定的一致延迟
  • 5、面试

0、准备

Redis相关概览:

在这里插入图片描述

以简历上所列的项目为切入点,展开Redis相关的问题:

在这里插入图片描述

1、缓存穿透:不存在的key

Client ⇒ Redis ⇒ MySQL,缓存穿透,即中间的Redis形同虚设,请求每次过来都查库。一般是网站被攻击时,疯狂造不存在数据,然后发起请求,冲击数据库,消耗数据库连接池资源,直到服务不可用。

在这里插入图片描述

解决方案一:缓存空数据

在这里插入图片描述

查到的结果为空也写进Redis。实现简单但消耗内存,可能会发生不一致的问题(即库里有数据了,但缓存里依旧是null,导致查不到最新数据)

解决方案二:布隆过滤器

缓存预热的时候,往布隆过滤器中添加数据。后面请求过来时,先经过布隆过滤器,判断ID不存在的话,直接返回,都走不到Redis。

在这里插入图片描述
如此,内存占用少,但实现复杂,且存在误判(即有的ID不存在,但布隆过滤器会判断为存在)

在这里插入图片描述
bitmap(位图):一个bit数组,每个单元非0即1。预热ID的时候,用多个hash函数获取该ID的hash值,并把bitmap对应位置改为1。后面查数据是否存在时,就用相同的hash函数获取hash值,查看对应的位置是否都为1。由此,布隆过滤器实现了检索一个元素是否在一个集合中。

在这里插入图片描述

如上,id1和id2点亮了1、3、7和9、12、15的位置为1,id3虽然不存在,但其hash值所在位置都为1,判定为是存在的ID,即误判。数组越大,误判率越低。

2、缓存击穿:热点key过期

给一个热点key设置了过期时间,当这个key过期的时候,恰好有大量请求查这个key,这些请求自然都走到了数据库,可能导致DB服务不可用。如下图,比如查询一次MySQL再写到Redis需要50ms,热点数据过期后,这50ms内的大量请求都会冲到数据库

在这里插入图片描述

解决方案一:添加互斥锁

在这里插入图片描述
缓存未命中,查库前,获取一个互斥锁,获取不到则一直重试,如此,后面的线程走不到查库这一步,直到线程1完成查库+写入Redis,其余线程就会命中缓存。如此,保护了数据库服务且保证了数据强一致性,但性能不好

解决方案二:逻辑过期

Redis层面,不设置过期时间,但业务层面加一个过期时间,如

keyvalue
001{“id”:“123”,“title”:“标题1”,"expire":1716368322}

在这里插入图片描述
即明天16:58的时候,这条数据逻辑过期,但你在Redis中还能查到,不过是查到了过期数据,不是最新的。具体流程:

在这里插入图片描述
线程1过来查缓存,发现当前时间超过了缓存的逻辑过期时间,于是线程1获取一个互斥锁,再开启一个线程2去查库 + 更新缓存,自己则先把过期数据返回。此过程中,即使有线程3进来,并发现了已超过逻辑过期时间,它也不会重复去查库重建缓存,因为它获取不到互斥锁,此时线程3会先返回过期数据。 因此,这种方式性能好,但数据一致性不保证。

3、缓存雪崩:大批key同时过期

同一时间段,大量缓存的key过期,或者Redis服务宕机,导致大量请求冲到数据库
在这里插入图片描述

解决思路是:给不同的key添加随机的TTL(过期时间),如此,大量的key不会同时过期。至于Redis宕机,则可以用Redis哨兵模式或者集群模式、给业务添加多级缓存等方式解决。

最后,降级限流,可用于解决缓存穿透、击穿、雪崩的解决。即服务请求失败次数到一定阈值,直接走降级策略(比如不查库,直接返回空)

//Tips:

穿透无中生有key,布隆过滤null隔离

缓存击穿过期key,锁与非期解难题

雪崩大量过期key,过期时间要随机

面试必考三兄弟,可用限流来保底

4、双写一致性

相关问题:MySQL和Redis的数据如何进行同步。两种追求:

  • 一致性高
  • 允许一定的一致延迟

4.1 要求高一致性

在这里插入图片描述

读操作:命中直接返回。未命中缓存则 查库 + 写入缓存

写操作:数据库更新时,进行延时双删

在这里插入图片描述
有数据库的写操作时,为了数据一致性,如果不双删,只删一次缓存 + 改库,则实现方式可以是:

  • 先删缓存,再改库
  • 先改库,再删缓存
1)若先删缓存,再改库:

理想状态为:线程1删缓存,再更新数据库,后面请求过来(对应线程2),先查缓存,未命中,去查库 + 写入缓存,一切正常

在这里插入图片描述

再看非理想状况:线程1删除缓存后挂起,此时缓存为null,库中为10。然后新的请求进来(对应线程2),CPU切到线程2执行,查缓存未命中,线程2去查库 + 写入缓存,线程2执行结束,此时缓存为10,库中为10。最后线程1解除挂起,继续执行,线程1去更新了数据库,此时缓存为10,库中为20 ,数据不一致!

在这里插入图片描述

总之,高并发下,线程交替执行,这样实现会出现数据不一致问题。

2)若先改库,再删缓存

理想状态为:线程2更新数据库,再删缓存,此时缓存为null,库中为20。后面请求过来(对应线程1),先查缓存,未命中,去查库 + 写入缓存,一切正常

在这里插入图片描述

非理想状态下:比如一开始缓存过期,即缓存中为null,库中为10,线程1进来未命中缓存,查库得到10,然后挂起。请求2进来(对应线程2),其进行了update,改库,并删缓存,此时,库中为20,缓存中为null。线程2执行结束,线程1解除挂起继续执行,将查到的数据,写入缓存。此时缓存中为10,库中为20,数据不一致。

在这里插入图片描述

因此,不管先删缓存还是先改库,都可能出现数据不一致

==> 延时双删:先删缓存,数据库更新完后,再删一次缓存。至于为什么要延时后第二次删,是因为如果数据库是主从模式,读写分离,那就需要等主节点把数据同步到从节点。但这个延时的大小不好控制,还是可能出现脏数据。想强一致,可用分布式锁。

在这里插入图片描述
一个线程在更新数据前,加锁,update库 + 删缓存后,释放锁。期间,其余线程不能读写。以上可优化为:读数据的时候,添加共享锁,读读共享,读写互斥。写数据的时候,加排他锁,阻塞其他线程的读和写。如此,实现数据强一致性,但性能低。

4.2 允许一定的一致延迟

异步通知,保证数据的最终一致性。业务服务更新库后,发消息到MQ,缓存服务监听MQ,去更新缓存

在这里插入图片描述
以上实现对业务代码有一定的侵入性,需要添加发消息的代码。可把MQ替换为Canal:

在这里插入图片描述

阿里的Canal基于MySQL的主从同步实现。数据库一旦发生改变,二进制的binlog记录DDL语句和DML语句,Canal伪装成MySQL的一个从节点,监听读取MySQL的binlog去更新缓存。此方式不用改业务代码,无侵入性。

最后,如果不要求实时性和强一致性,如热点文章数据,可用异步方案同步数据。如果要求数据强一致性,如抢券的库存,则采用redisson提供的读写锁保证数据同步。

5、面试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言/数据结构——队列的实现

一.前言 今天我们来聊一聊数据结构的一部分——队列。今天我们主要涉及队列的基本概念结构,以及队列的基本实现。 二.正文 1.1队列 1.12队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表&#xf…

ue5 中ps使用记录贴

一、快捷键记录 放大图形 ctrlalt空格 放大图形 缩小视口 ctrl空格 ctrlD 取消选区 ctrlt缩小文字 w魔棒工具 选择魔棒的时候把容差打开的多一点 二、案例 移动文字 在相应的图层选择 移动文字 修改图片里的颜色 在通道里拷贝红色通道,复制红色通道粘贴给正常图…

【ELK日志收集过程】

文章目录 为什么要使用ELK收集日志ELK具体应用场景ELK日志收集的流程 为什么要使用ELK收集日志 使用 ELK(Elasticsearch, Logstash, Kibana)进行日志收集和分析有多种原因。ELK 堆栈提供了强大、灵活且可扩展的工具集,能够满足现代 IT 系统对…

CIM模型

CIM 是 Esri 制图信息模型。 它是一个地图内容规范,用于记录在保存、读取、引用或打开时如何永久保留描述不同项目组件的信息。 该规范以 JSON 表示,适用于 ArcGIS 应用程序和 API 中的地图、场景、布局、图层、符号和样式。 CIM 不仅限于制图设置。 要了解属性的组织方式以及…

使用vue3实现右侧瀑布流滑动时左侧菜单的固定与取消固定

实现效果 实现方法 下面展示的为关键代码,想要查看完整流程及代码可参考https://blog.csdn.net/weixin_43312391/article/details/139197550 isMenuBarFixed为控制左侧菜单是否固定的参数 // 监听滚动事件 const handleScroll () > {const scrollTopThreshol…

数据库系统基础知识

一、基本概念 二、数据库三级模式两级映像 三、数据库的分析与设计过程 四、数据模型 五、关系代数 六、数据库完整性约束 七、关系型数据库SQL简介 八、关系数据库的规范化 九、数据库的控制功能 十、数据仓库与数据挖掘基础 十一、大数据基本概念 数据库基本概念 1、数据库…

Spring 对于事务上的应用的详细说明

1. Spring 对于事务上的应用的详细说明 文章目录 1. Spring 对于事务上的应用的详细说明每博一文案2. 事务概述3. 引入事务场景3.1 第一步:准备数据库表3.2 第二步:创建包结构3.3 第三步:准备对应数据库映射的 Bean 类3.4 第四步:…

hcia datacom学习(10):交换机基础

1.二层交换机工作原理 1.1交换机的5种行为 查看mac地址表的命令为 dis mac-address *一个MAC只能关联在一个接口上,一个接口上可以学习多个MAC *mac地址漂移:mac表中,mac地址的出接口从一个端口变为另一个端口的现象。 造成mac漂移的原因…

操作系统实验四 (综合实验)设计简单的Shell程序

前言 因为是一年前的实验,很多细节还有知识点我都已经遗忘了,但我还是尽可能地把各个细节讲清楚,请见谅。 1.实验目的 综合利用进程控制的相关知识,结合对shell功能的和进程间通信手段的认知,编写简易shell程序&…

轻松拿捏C语言——【字符函数】字符分类函数、字符转换函数

🥰欢迎关注 轻松拿捏C语言系列,来和 小哇 一起进步!✊ 🌈感谢大家的阅读、点赞、收藏和关注💕 🌹如有问题,欢迎指正 感谢 目录👑 一、字符分类函数🌙 二、字符转换函数…

Spring MVC/Web

1.Spring MVC 的介绍 Spring Web MVC是基于Servlet API构建的原始Web框架,也是Spring框架的一部分。它提供了灵活可扩展的MVC架构,方便开发者构建高性能的Web应用程序,并与 Spring 生态系统无缝集成。 2.MVC 设计模式 MVC(Model…

【游戏引擎】Unity脚本基础 开启游戏开发之旅

持续更新。。。。。。。。。。。。。。。 【游戏引擎】Unity脚本基础 Unity脚本基础C#语言简介C#基础 Unity脚本基础创建和附加脚本MonoBehaviour生命周期生命周期方法 示例脚本 Unity特有的API常用Unity API 实践示例:制作一个简单的移动脚本步骤1:创建…

SpringCloud系列(30)--准备使用Hystrix的前期工作,创建服务消费者模块

前言:在上一章节中我们创建了服务提供者模块,而本节内容则是创建服务消费者模块。 1、创建一个服务提供者模块,命名为cloud-consumer-feign-hystrix-order80 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选择模块要使用的JDK版本 …

Ansible自动化运维中的Setup收集模块应用详解

作者主页:点击! Ansible专栏:点击! 创作时间:2024年5月22日13点14分 💯趣站推荐💯 前些天发现了一个巨牛的🤖人工智能学习网站,通俗易懂,风趣幽默&#xf…

分享:怎么才能保证大数据查询的准确性?

随着大数据应用到金融风控领域,大数据越来越重要了,很多朋友在查大数据的时候都会遇到一个问题,那就是自己查询的大数据什么信息都没有,要么就是很少,这是什么原因呢?要怎么才能保证大数据查询的准确性呢?下面小编就…

WordPress搭建流程

1. 简介 WordPress 是一个 PHP 编写的网站制作平台。WordPress 本身免费,并且拥有众多的主题可以使用,适合用于搭建个人博客、公司官网、独立站等。 2. 环境准备 2.1 WordPress 下载 WordPress 可以在 Worpress中文官网 下载(如果后续要将后台调成中文的话,一定要从中文…

如何通过软件SPI读写W25Q64

STM32F1之SPI通信软件SPI代码编写-CSDN博客 目录 1. W25Qxx系列简介 2. W25Q64硬件电路 3. W25Q64框图 4. Flash操作注意事项 5. 代码编写 5.1 初始化 5.2 W25Q64读取ID号 5.3 W25Q64写使能 5.4 W25Q64等待忙 5.5 W25Q64页编程 5.6 W25Q64扇区擦除&#x…

521源码-在线客服-CRMChat网页版客服系统 UNIAPP 全方位在线客服系统源码与管理体系平台

CRMChat客服系统:基于Swoole4Tp6RedisVueMysql构建的高效沟通桥梁 CRMChat是一款独立且高性能的在线客服系统,它结合了Swoole4、Tp6、Redis、Vue以及Mysql等先进技术栈,为用户提供了卓越的在线沟通体验。该系统不仅支持在Pc端、移动端、小程…

16.线性回归代码实现

线性回归的实操与理解 介绍 线性回归是一种广泛应用的统计方法,用于建模一个或多个自变量(特征)与因变量(目标)之间的线性关系。在机器学习和数据科学中,线性回归是许多入门者的第一个模型,它…

【机器学习】机器学习基础概念与初步探索

❀机器学习 📒1. 引言📒2. 机器学习概述📒3. 机器学习基础概念🎉2.1 机器学习的分类🎉2.2 数据预处理🌈数据清洗与整合🌈 特征选择和特征工程🌈数据标准化与归一化 📒4. …