JAVA面试专题-Redis

你在最近的项目中哪些场景使用了Redis

缓存

缓存穿透

缓存穿透:查询一个不存在的数据,mysql查询不到数据也不好直接写入缓存,导致每次请求都查数据库。
解决方案一:缓存空数据,即使查询返回的数据为空,也把这个空结果进行缓存(如key:1,value:null)。
优点:简单
缺点:消耗内存(总有空数据),不一致问题(来真的数据了)

解决方案二:布隆过滤器(可以使用redisson实现):查询之前先访问布隆过滤器,如果不存在就直接返回

优点:内存占用少,没有多余key
缺点:实现复杂,存在误判(bitmap位图越小误判越大,数组越大误判越小,但有内存消耗,一半百分之五以内的误判都可以接收)

布隆过滤器作用:可以用于检索一个元素是否在一个集合中(bitmap位图,数组每个单元只能存储0/1)。

 缓存击穿

缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这个时间点对这个key有大量的并发请求,只能访问数据库,会把db压垮。

解决方案一:互斥锁
未命中后获取互斥锁(如setnx),处理完后释放锁,其他线程拿到锁才能运行

解决方案二:逻辑过期
在设置key时设置过期时间字段存入缓存,查询时如果过期,获取互斥锁后直接返回过期数据,同时开启新线程进行缓存重建释放锁,其他线程如果获取互斥锁失败后,仍然返回过期数据。

 缓存雪崩

缓存雪崩:同一时间大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库

 解决方案:
1. 给不同的Key的TTL添加随机值,避免同时过期
2. 利用Redis集群提高服务的可用性(哨兵模式,集群模式)
3. 给缓存业务添加降级限流策略(nginx或Spring cloud gateway)
4. 给业务添加多级缓存

《缓存三兄弟》

穿透无中生有key,布隆过滤null隔离。
缓存击穿过期key,锁与非期解难题。
雪崩大量过期key,过期时间要随机。
面试必考三兄弟,可用限流来保底。

先删除缓存还是先修改数据库-双写一致性

读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间

写操作:延迟双删:先删除缓存,修改数据库,延时一段时间再删除缓存

分布式锁(强一致性,性能低)

共享锁:读锁readLock,加锁之后,其他线程可以共享读操作
排他锁:独占锁write,加锁之后,阻塞其他线程读写操作

 异步通知(允许延时一致的业务):

修改数据后写入数据库同时发送消息到MQ,受到MQ消息后更新缓存,主要依赖于MQ的可靠性。

阿里的组件canal组件也可以实现数据同步,不需要更改业务代码,部署服务后,它会把自己伪装成mysql的一个从节点,mysql数据更新后,canal会读取binlog数据,然后通过canal客户端获取到数据,更新缓存即可。

Redis持久化

RDB

RDB(Redis Database Backup file)Redis数据备份文件,也叫Redis数据快照,可以把内存中的所有数据记录到磁盘中,当Redis故障时,从磁盘读取快照文件,恢复数据。

主动备份:save bgsave(不影响主进程,一般用这个)
被动备份:redis.conf修改文件

RDB执行原理:物理内存通过进程中的页表交换数据,bgsave开始时会fork主进程得到子进程(复制页表),子进程完成fork后读取内存数据并写入RDB文件,fork采用copy-on-write技术(主进程读取内存时,访问共享内存;主进程执行写操作时,从内存中拷贝一份数据副本执行写操作,以后主进程读也从副本读)

AOF

AOF(Append Only File)追加文件,redis处理的每一个写命令都会记录在AOF文件中,可以看做是命令日志文件。

因为是记录命令,所以AOF文件会很大,通过bgrewriteaof命令,让AOF执行重写功能,只有最后一次有意义。也可以在配置文件里设置触发阈值自动重写。

Redis过期策略

惰性删除

设置key过期时间后,不去管它,下次使用该key时,检查是否过期,过期删除。
优点:CPU友好,不用浪费时间检查
缺点:内存不友好,不用就永远不会释放

定期删除

每隔一段时间对key检查,从一定数量的数据库中取出一定数量的随机key进行检查,并删除其中的过期key。氛围SLOW(执行频率10hz,每次不超过25ms)和FAST(每次时间循环尝试执行,间隔不低于2ms,耗时不超过1ms)两种模式。
优点:可以通过限制删除操作执行的时长和频率来减少删除操作对cpu的影响,也能释放过期key占用的内存
缺点:难以确定删除操作的时长和频率

所以:Redis的过期删除策略为:惰性删除+定期删除配合使用

数据淘汰策略

使用建议:
1. 优先使用allkeys-lru策略,把最近最常访问的数据留在缓存中,如果业务有明显的冷热数据区分建议使用。
2. 访问数据频率差别不大,没有明显冷热区分,建议使用allkeys-random随机淘汰
3. 如果有置顶要求,使用volatile-lru策略,同时置顶数据不设置过期时间
4. 如果业务有短时高频访问的数据,建议使用lfu策略

分布式锁

可以使用setnx命令,或者直接用redisson(底层是setnx和lua脚本)

看门狗机制

每隔一段时间自动做一次续期(默认每隔十秒续期一次)

 可重入性

 基于redssion实现的分布式锁可重入,利用hash结构记录线程id和重入次数

主从一致性

RedLock(红锁):布置在一个redis实例上创建锁,应该实在多个redis实例上创建锁(n/2+1)。
但是红锁这个思想,实现复杂,性能差,运维繁琐,因为redis是基于AP思想啊(可用性),如果要实现主从一致,可以利用CP思想(一致性)的zookeeper来实现。

Redis集群方案

主从复制

单节点redis的并发能力是有上限的,要提高并发能力就要搭建主从集群,实现读写分离,往主节点里写,从节点里读。

 主从全量同步

slave节点执行replicaof命令建议连接,请求master数据同步(发送replid和offset),master判断是否是第一次同步(replid是否一致),如果是第一次,就向slave返回master的数据版本信息(replid,offset),slave保存版本信息,master执行bgsave生成RDB文件并向slave发送,slave清空本地数据,加载RDB文件。在这个发送期间,主节点记录RDB期间的所有命令存入到repl_baklog中发送到slave,slave执行接收到的命令。

 主从增量同步

适用于slave重启或后期数据变化,从节点发送replid和offset,主节点判断是否一致,如果不是第一次,就回复continue,之后去repl_back中获取offset后的数据,发送命令。

哨兵机制

Sentinel哨兵机制实现主从集群的自动故障恢复。

 服务状态监控

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令
主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线。
客观下线:如果超过sentinel数量一半的哨兵都认为该实例主观下线,该实例客观下线。

哨兵选主规则

判断主与从断开时间长短,超过指定值就排该从节点
然后判断从节点的slave-priority值,越小优先级越高
如果优先级一样,判断offset值,越大优先级越高
判断slave节点的运行id大小,越小优先级越高

集群脑裂

主节点和从节点和哨兵处于不同网络分区,使得哨兵灭有能够心跳感应到主节点,所以选举出了一个新的主节点,这样就存在了两个master,像大脑分裂一样,导致客户端孩子啊老主节点写入数据,新节点无法同步数据,网络恢复后,哨兵会将老的主节点降为从节点,再从新master中同步数据,导致数据丢失。
解决:修改redis配置,设置最小的从节点数量以及缩短主从数据同步的延迟时间。

 分片集群结构

主从和哨兵可以解决高可用,高并发读的问题,但是没有解决海量数据存储和高并发写问题,这时可以使用分片集群。
分片集群特征:
集群中有多个master,每个master保存不同数据
每个master有多个slave节点
master之间通过ping监测彼此健康状态
客户端请求可以访问集群任意节点,最终都会转发到正确节点

分片集群结构:数据读写

引入哈希槽概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。

 Redis是单线程的为什么速度这么快?

Redis是存内存操作,执行速度非常快
采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题
使用I/O多路复用模型,非阻塞IO

I/O多路复用模型

redis是纯内存操作,执行速度非常快,性能瓶颈是网络延迟而不是执行速度,I/O多路复用模型实现了高效的网络请求

常见的IO模型

阻塞IO:等待数据和从内核拷贝数据到用户空间都需要阻塞等待
非阻塞IO:recvform阶段立即返回结果而不阻塞第二阶段依旧阻塞
IO多路复用:利用单个线程来同时监听多个Socket,并在某个Socket可读,可写时得到通知,避免无效等待,充分利用cpu资源。

Redis网络模型

 提供了连接应答处理器,命令回复处理器(多线程回复事件),命令请求处理器(命令转换使用多线程,增加速度,命令执行依旧是单线程)。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习 Rust 第 23 天:闭包

Rust 闭包提供了简洁、富有表现力的匿名函数来捕获周围的变量。它们简化了代码,提供了存储、参数传递和函数重构方面的灵活性。它们与泛型的交互增强了灵活性,而捕获模式则促进了有效的所有权和可变性管理。从本质上讲,闭包是 Rust 的基础&am…

(7)快速调优

文章目录 前言 1 安装脚本 2 运行 QuikTune 3 高级配置 前言 VTOL QuikTune Lua 脚本简化了为多旋翼飞行器的姿态控制参数寻找最佳调整的过程。 脚本会缓慢增加相关增益,直到检测到振荡。然后,它将增益降低 60%,并进入下一个增益。所有增…

24五一杯B题思路分享+分析问题

回顾问题 ### 问题1:小型交通网络的交通需求分配 1. **理解问题**:首先,需要理解交通网络的结构和各起点-终点对之间的交通需求。 2. **建立模型**:使用线性规划、动态规划或启发式算法来分配交通量到不同的路径上。 3. **优化目…

汽车制造业安全事故频发,如何才能安全进行设计图纸文件外发?

汽车制造业产业链长,关联度高,汽车制造上游行业主要为钢铁、化工等行业,下游主要为个人消 费、基建、客运和军事等。在汽车制造的整个生命周期中,企业与上下游供应商、合作商之间有频繁、密切的数据交换,企业需要将设计…

windows11安装nginx

1.解压nginx安装包到没有中文的目录 2.双击运行nginx.exe 3.任务管理器查看是否有nginx进程 4.任务管理器->性能->资源监视器 5.网络->侦听端口,查看nginx侦听的端口,这里是90端口

吴恩达2022机器学习专项课程(一)7.2 逻辑回归的简化成本函数课后实验 Lab5

问题预览/关键词 二分类问题的训练集(多特征)绘制训练集数据的散点图自定义plot_data() Python实现逻辑回归的成本函数自定义sigmoid() 调用成本函数不同的w,b,绘制逻辑回归模型的决策边界验证哪条决策边界效果好总结 二分类问题的…

对话访谈——五问RAG与搜索引擎:探索知识检索的未来

记一次关于RAG和搜索引擎在知识检索方面的对话访谈,针对 RAG 与传统搜索引擎的异同,以及它们在知识检索领域的优劣势进行了深入的探讨。 Q:传统搜索引擎吗,通过召回-排序的两阶段模式,实现搜索逻辑的实现,当前RAG技术也…

Jetson Orin NX L4T35.5.0平台LT6911芯片 调试记录(2)vi discarding frame问题调试

基于上篇调试记录 Jetson Orin NX L4T35.5.0平台LT6911芯片 调试记录(1)MIPI问题调试-CSDN博客 1.前言 当通过gstreamer持续捕获视频设备时,帧数会下降,并且I输入越高,丢失的帧数越多。 当达到4k30hz时,它完全无法使用,系统会在几秒钟的收集后崩溃并重新启动 4k30hz …

Mac 版 安装NVM

优质博文IT-BLOG-CN NVM(Node Version Manager)是一个用于管理多个Node.js版本的工具。它允许开发者在同一台机器上安装和切换不同版本的Node.js,以便在不同的项目中使用不同的Node.js版本。macOS用户可以使用homebrew来安装NVM。 一、安装h…

VS code 同步odata服务

在做UI5得开发过程中,经常会出现odata需要更新 那么已经加载过得项目如何去跟新odata服务呢 可以通过如下步骤 1.右键打开应用信息 2.找到manage service models 3.点击编辑 4.选中 刷新并保存

DevEco Studio mac版启动不了【鸿蒙开发Bug已解决】

文章目录 项目场景:问题描述原因分析:解决方案:此Bug解决方案总结Bug解决方案寄语项目场景: 最近也是遇到了这个问题,看到网上也有人在询问这个问题,本文总结了自己和其他人的解决经验,解决了【DevEco Studio mac版启动不了】的问题。 问题描述 报错如下。 -------…

Pytorch学习笔记——认识数据

最近在跟着小土堆pytorch的视频跟着学习python,根据自己的理解和课程上面的知识,写了这一篇学习笔记。 1、加载数据 数据的加载是学习pytorch的第一步,我们需要加载数据,完成特征工程,对加载数据存在的一些特…