当前位置: 首页 > news >正文

java八股文之Redis

1.Rdis常见的使用场景

  1. 缓存
  2. 分布式锁(redision,setnx)
  3. 计数器
  4. 保存token
  5. 消息队列
  6. 延迟队列

2.说明一下缓存雪崩,缓存穿透和缓存击穿以及解决方式

1.缓存雪崩

定义: 缓存雪崩指的是当大量的缓存数据同时失效,或者Redis服务器突然宕机,导致后端数据库突然承受大量请求的压力,从而可能导致数据库崩溃的情况。
解决:
1. 分散缓存过期时间:给缓存设置不同的过期时间,避免同时失效。
2. 使用Rdis集群: 如果是Redis服务器突然宕机导致的雪崩,可以使用Redis集群提高服务的可用性,如(哨兵模式或集群模式)
3. 限流降级:在访问量剧增时,采用限流策略,限制数据库的请求频率;或者采用降级策略,返回备选数据或默认值。

2.缓存穿透

定义:缓存穿透指的是查询一个一定不存在的数据,该数据不存在,每次请求都要到数据库去查询取数据并返回空值。
解决:
1. 布隆过滤器(Bloom Filter):预先判断key是否可能存在,如果布隆过滤器判断key不存在,则直接返回,减少无效查询。
2. 缓存空值:对于查询不存在的数据,也设置一个空值缓存,并设置合理的过期时间。

3. 缓存击穿

定义:缓存击穿是指缓存中某个key在失效的一瞬间,有大量的并发请求过来,这些请求发现缓存过期,就直接请求数据库,从而给数据库带来很大压力。
解决:
1.互斥锁:使用如Redis的setnx命令或其他方式来实现分布式锁,确保同一时间内只有一个线程去加载数据。
2.设置热点数据永不过期:对于热点数据,可以考虑设置永不过期,或者设置一个逻辑过期时间,如果查询发现数据逻辑过期,返回逻辑过期数据,同时开启互斥锁,另起一个线程更新最新热点数据,更新完毕释放锁。

3. 介绍一下双写一致性,并回答如何保证Redis和数据库双写一致性

双写一致性: 当修改了数据库的数据同时也要同时更新redis缓存的数据,缓存好数据库的数据要保持一致
保证双写一致:
1. 延时双删:更新数据前先删除缓存,数据更新完成后,等一会儿再删除一次缓存,但是延时多少不好确定,依然有不一致的可能。
2. 使用读写锁: 当一直性要求较高时,可以使用Redis提供的读写锁。在进行读操作时添加共享锁,可以保证读读不互斥,读写互斥。当进行写操作时,使用排它锁,读写,读读都互斥,来保证双写一致。需要注意的是,读方法和写方法需要使用的是同一把锁。
3. 使用MQ通知:一致性要求不是特别高时,可以使用异步通知的思想。如:数据更新完成之后,使用MQ通知缓存进行删除。保证最终一致。

4.介绍一下Redis的持久化

Redis提供了两种持久化数据的方式,分别是RDB和AOF,实际项目中是两者混用。
RDB: RDB是一个快照文件,将redis存储的数据放到磁盘上,当Redis宕机恢复数据时,方便从RDB的快照文件里面恢复数据。优点是体积小,恢复速度更快,但是有丢失几分钟数据的风险。
AOF: AOF含义是追加文件,他会将redis操作的命令都存储到这个文件中,当Rdis宕机恢复的时候。从这个文件在再次执行一遍命令来恢复数据。优点是丢失数据的风险更小,可以设置刷盘策略,让他每秒批量写入一次命令,这样最多只会丢失一秒的数据。

5.介绍一下Redis数据过期策略

Rdis对数据设置的有效时间过期之后不会立即删除,会按照不同的过期策略进行删除,过期策略有惰性删除和定期删除两种,一般项目中是混用。
惰性删除: redis的key过期后,不会去管他,当使用key时,检查是否过期,如果过期就删除,反之返回key。
定期删除: 每隔一段时间,对一些key进行检查,删除里面过期的key。(每次检查不会全查,只会随机检查一部分,删除其中过期的key)。定期删除有两种模式,SLOW和FAST模式,SLOW模式默认是定时任务,执行频率是10hz,每次不超过25s。FAST模式频率不固定,两次间隔不低于2ms,每次耗时不超过1ms。

6.介绍Redis的数据淘汰策略

先介绍两个概念:LRU和LFU
LRU(Least Recently Used ): 最近最少使用。用当前时间减去最
后一次访问时间,这个值越大则淘汰优先级越高。
LFU(Least Frequently Used): 最少频率使用。会统计每个kev的
访问频率,值越小淘汰优先级越高。

八种淘汰策略

  • noeviction:不淘汰任何key,但是内存满时不允许写入新数据,默认就是这种策略。
  • volatile-ttl:对设置了过期时间的key,比较key的剩余过期时间值,过期时间越小越先被淘汰
  • allkeys-random:对全体key,随机进行淘汰。
  • volatile-random:对设置了过期时间的key,随机进行淘汰。
  • allkeys-lru:对全体key,基于LRU算法进行淘汰。
  • volatile-lru:对设置了过期时间的key,基于LRU算法进行淘汰。
  • allkeys-lfu:对全体key,基于LFU算法进行淘汰。(项目中最常用)
  • volatile-lfu:对设置了过期时间的key,基于LFU算法进行淘汰。

7.介绍一下Redis分布式锁

  1. Redis分布式锁第底层实现是使用了setnx命令去实现的,因为redis底层是单线程的,使用的这个命令之后,只能有一个客户端对某一个key设置值,在没有过期或者删除这个key之前,其他客户端无法设置这个key。
  2. Rdis分布式锁的有效时长,是通过一个叫WatchDog(看门狗)的机制控制的。这个机制每隔一段时间会检查当前业务是否还有锁,如果有则增加持有锁的时间。业务执行完成后释放锁即可。
  3. Redission分布式锁是可以重入的。重入锁的时候,会判断是否是当前线程持有的锁,如果是则将当前线程的锁计数。如果是释放锁,则会在计算上减一。在存储数据的时候采用的是hash结构,大key按照自己的业务规则制定,小key是当前的线程唯一标识,value是当前线程重入的次数。
  4. Redission不能解决主从数据一致性的问题,但是可以用redission提供的红锁来降低这个事情发生的可能。但是这样性能就太低了,如果业务要强一致性,建议采用zookeeper实现的分布式锁。

8.说一下Redis集群

主从复制: Redis集群中有一个主节点和多个从节点,主节点只负责写数据然后同步给从节点,从节点只负责读数据。
哨兵模式: 主要负责实现主从集群的自动故障恢复(监控,自动故障恢复,通知)。主从加哨兵可以解决解决高可用,高并发读的问题,不能解决海量数据存储,高并发写。
分片集群: 集群中有多个master,每个master保存不同数据,同时每个master有自己的从节点。

9.说一下主从同步过程

概念介绍: 主从同步是主节点往从节点同步数据的过程,主从同步分全量同步和增量同步两种,全量同步在第一次同步时使用,之后再同步就是增量同步。
1.Replication Id: 简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid
2.offset: 偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

全量同步:

  1. 从节点请求主节点同步数据(replication id、.offset)
  2. 主节点判断是否是第一次请求,是第一次就与从节点同步版本信息(replication id和offset)
  3. 主节点执行bgsave命令,生成rdb文件后,发送给从节点去执行
  4. 在db生成执行期间,主节点变更的数据会以命令的方式记录到缓冲区(一个日志文件)
  5. 主节点把生成之后的命令日志文件发送给从节点进行同步

增量同步

  1. 从节点请求主节点同步数据,主节点判断不是第一次请求,不是第一次就获取从节点的ofst值
  2. 主节点从命令日志中获取offset值之后的数据,发送给从节点进行数据同步

10. 说一下Redis集群脑裂及解决

定义: 集群脑裂是由于主节点和从节点和sentinel(哨兵)处于不同的网络分区,使得sentinel没有能够心跳感知到主节点,所以通过选举的方式提升了一个从节点为主节点,这样就存在了两个主节点,就像大脑分裂了一样,这样会导致客户端还在老的主节点那里写入数据,新节点无法同步数据,当网络恢复后,sentinel会将老的主节点降为从节点,然后再从新masterl同步数据,就会导致老的主节点在网络中断脱离集群到网络恢复加入集群期间写入的的客户端数据丢失。
解决: 我们可以修改rdis的配置,设置最少的能感知到的从节点数量,主节点达不到要求就拒绝客户端请求。同时缩短主从数据同步的延迟时间,避免大量的数据丢失。

11.介绍一下redis分片集群

  • 集群中有多个master,每个master保存不同数据
  • 每个master都可以有多个slave节点
  • master之间通过ping监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点
  • 解决高可用,高并发读,海量数据存储,高并发写的问题

12. 说一下Redis分片集群中的数据如何存储和读取

  • Redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽
  • 将16384个插槽分配给不同的实例。(实例指的是主节点)
  • 读写数据:根据key的有效部分计算哈希值,对16384取余(有效部分:如果key前面有大括号,大活号的内容就是有效部分,如果没有,则以key本身做为有效部分)余数做为插槽,寻找插槽所在的实例。

13. Redis是单线程的,为什么那么快

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

14. 解释一下I/O多路复用模型

名词解释:
socket:客户端的连接
epoll模式: 是指监听Socket,通知的用户socket就绪的一种实现方式,常见实现的有:select,poll,epoll
用户空间:

  1. Liux系统中一个进程使用的内存情况划分两部分:内核空间、用户空间。用户空间只能执行受限的命令(Rig3),而且不能直接调用系统资源,必须通过内核提供的接口来访问 。内核空间 可以执行特权命令(Ring0),调用一切系统资源。
  2. Liux系统为了提高IO效率,会在用户空间和内核空间都加入缓冲区,写数据时,要把用户缓冲数据拷贝到内核缓冲区,然后写入设备。读数据时,要从设备读取数据到内核缓冲区,然后拷贝到用户缓冲区。

1.I/O多路复用
是指利用单个线程来同时监听多个Socket,并在某个Socket可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。目前的l/O多路复用都是采用的epoll模式实现,epoll模式会在通知用户进程Socket就绪的同时,把已就绪的Socket写入用户空间,不需要挨个遍历Socket来判断是否就绪,提升了性能。

2.Redis网络模型
就是使用l/O多路复用结合事件的处理器来应对多个Socket请求

  • 连接应答处理器
  • 命令回复处理器,在Rdis6.0之后,为了提升更好的性能,使用了多线程来处理回复事件
  • 命令请求处理器,在Rdis6.0之后,将命令的转换使用了多线程,增加命令转换速度,在命令执行的时候,依然是单线程

相关文章:

  • 政务浏览器API文档及Demo大升级
  • uniapp二次封装组件(py组件)
  • SQL复习
  • 微调codegeex
  • 跟着AI学习vue3第二章
  • 机器视觉--switch语句
  • 基于N-gram模型的中文文本分析系统设计与实现
  • 什么是关系数据库理论?(函数依赖,范式)
  • 轻量级5G核心网:适应未来网络需求的关键方案
  • 【第11章:生成式AI与创意应用—11.2 音频与音乐生成的探索与实践】
  • C程序设计(第5版)——谭浩强(1)
  • lazarus 从资源文件中加载PNG图片
  • 【SpringBoot】深度解析 Spring Boot 拦截器:实现统一功能处理的关键路径
  • 跟着李沐老师学习深度学习(十)
  • LabVIEW开发CANopen的TPDO数据读取
  • IDEA集成DeepSeek
  • [特殊字符] 用Rust重塑Web开发速度极限:Hyperlane框架——开启高性能服务的「光年时代」[特殊字符]
  • 模型GPU->NPU(Ascend)迁移训练简述
  • 为AI聊天工具添加一个知识系统 之106 详细设计之47 Lattice
  • 【第13章:自监督学习与少样本学习—13.2 少样本学习(FSL)与元学习(Meta-Learning)的基础理论与应用案例】
  • 央行设立服务消费与养老再贷款,额度5000亿元
  • 江西暴雨强对流明显,专家:落雨区高度重叠,地质灾害风险高
  • 71岁导演詹姆斯・弗雷病逝,曾执导《纸牌屋》、麦当娜MV
  • Meta正为AI眼镜开发人脸识别功能
  • 成都公积金新政征求意见:购买保障性住房最高贷款额度上浮50%
  • 中国以“大幅开放市场”回应贸易保护主义