java面试-redis篇(黑马)
面试-redis篇
缓存穿透
Redis的使用场景?
1、根据自己建立上的业务进行回答。
2、缓存:穿透、击穿、雪崩、双写一致、持久化、数据过期、淘汰策略。
3、分布式锁:setnx、redisson
什么是缓存穿透,怎么解决?
1、缓存穿透:查询一个不存在的数据,MySQL查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库。
2、解决方案一:缓存空数据。
3、解决方案二:布隆过滤器。
缓存击穿
什么是缓存击穿?
1、缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮。
2、解决方案一:互斥锁,强一致,性能差。
3、解决方案二:逻辑过期,高可用,性能优,不能保证数据绝对一致。
缓存雪崩
什么是缓存雪崩?
1、缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。
2、解决方案:
(1)给不同的key的TTL添加随机值。
(2)利用Redis集群提高服务的可用性。
(3)给缓存业务添加降级限流策略,降级可做为系统的保底策略,适用于穿透、击穿、雪崩。
(4)给业务添加多级缓存。
redis缓存—双写一致
redis做为缓存,MySQL的数据如何与redis进行同步呢?(双写一致性)
1、介绍自己建立上的业务,我们当时是把文章的热点数据写入到了缓存中,虽然是热点数据,但是实时要求性并没有那么高,所以,我们当时采用的是异步的方案同步的数据。
2、我们当时是把抢券的库存存入到了缓存中,这个需要实时的进行数据同步,为了保证数据的强一致,我们当时采用的是redisson提供的读写锁来保证数据的同步。
那你来介绍一下异步的方案(你来介绍一些redisson读写锁的这种方案)
1、允许延时一致的业务,采用异步通知。
①使用MQ中间件,更新数据之后,通知缓存删除。
②利用canal中间件,不需要修改业务代码,伪装成MySQL的一个从节点,canal通过读取binlog数据更新缓存。
2、强一致性的,采用Redisson提供的读写锁。
①共享锁:读锁readLock,加锁之后,其他线程可以共享读操作。
②排他锁:独占锁writeLock也叫,加锁之后,阻塞其他线程读写操作。
redis缓存-持久化
RDB与AOF对比?
redis缓存-数据过期策略
redis的数据过期策略?
- 惰性删除:访问key的时候判断是否过期,如果过期,则删除。
- 定期删除:定期检查一定量的key是否过期(SLOW模式+FAST模式)
redis的过期删除策略:惰性删除+定期删除两种策略进行配合使用
redis缓存-数据淘汰策略
什么是数据淘汰策略?
- redis提供了8种不同的数据淘汰策略,默认是noeviction不删除任何数据,内存不足直接报错。
- LRU:最少最近使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
- LFU:最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。
redis分布式锁-使用场景
redis分布式锁,是如何实现的?
- 先按照自己建立上的业务进行描述分布式锁使用的场景。
- 我们当时是使用的redisson实现的分布式锁,底层是setnx和lua脚本(保证原子性)
redisson实现分布式锁如何合理的控制锁的有效时长?
在redisson的分布式锁中,提供了一个WatchDog(看门狗),一个线程获取锁成功以后,WatchDog会给持有锁的线程续期(默认是每隔10秒续期一次)
Redisson的这个锁,可以重入吗?
可以重入,多个锁重入需要判断是否是当前线程,在redis中进行存储的时候使用的hash结构,来存储线程信息和重入的次数。
Redisson锁能解决主从数据一致的问题吗?
不能解决,但是可以使用redisson提供的红锁来解决,但是这样的话,性能就太低了,如果业务非要保证数据的强一致性,建议采用zookeeper实现的分布式锁。
redis其它面试问题-主从复制、主从同步流程
介绍一下redis的主从同步?
单节点redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。一般都是一主多从,主节点负责写数据,从节点负责读数据。
能说一下,主从同步数据的流程?
全量同步
- 从节点请求主节点同步数据(replication id、offset)
- 主节点判断是否是第一次请求,是第一次就与从节点同步版本信息(replication id和offset)
- 主节点执行bgsave,生成rdb文件后,发送给从节点去执行
- 在rdb生成执行期间,主节点会以命令的方式记录到缓冲区(一个日志文件)
- 把生成之后的命令日志文件发送给从节点进行同步
增量同步
- 从节点请求主节点同步数据,主节点判断不是第一次请求,不是第一次就获取从节点的offset值。
- 主节点从命令日志中获取offset值之后的数据,发送给从节点进行数据同步。
redis其它面试问题-哨兵模式、集群脑裂
怎么保证redis的高并发高可用?
哨兵模式:实现主从集群的自动故障恢复(监控、自动故障恢复、通知)
你们使用redis是单点还是集群,哪种集群?
主从(1主1从)+哨兵就可以了。单节点不超过10G内存,如果Redis内存不足则可以给不同服务分配独立的Redis主从节点。
redis集群脑裂,该怎么解决呢?
集群脑裂是由于主节点和从节点和sentinel处于不同的网络分区,使得sentinel没有能够心跳感知到主节点,所以通过选举的方式提升了一个从节点为主,这样就存在了两个master,就像大脑分裂了一样,这样会导致客户端还在老的主节点那里写入数据,新节点无法同步数据,当网络恢复后,sentinel会将老的主节点降为从节点,这时再从新master同步数据,就会导致数据丢失。
解决:我们可以修改redis的配置,可以设置最少的从节点数量以及缩短主从数据同步的延迟时间,达不到要求就拒绝请求,就可以避免大量的数据丢失。
redis其它面试问题-分片集群、数据读写规则
redis的分片集群有什么作用?
- 集群中有多个master,每个master保存不同数据。
- 每个master都可以有多个slave节点。
- master之间通过ping检测彼此健康状态。
- 客户端请求可以访问集群任意节点,最终都会被转发到正确节点。
redis分片集群中数据时怎么存储和读取的?
- redis分片集群引入了哈希槽的概念,redis集群有16384个哈希槽。
- 将16384个插槽分配到不同的实例。
- 读写数据:根据key的有效部分计算哈希值,对16384取余(有效部分,如果key前面有大括号,大括号的内容就是有效部分,如果没有,则以key本身做为有效部分)余数做为插槽,寻找插槽所在的实例。
redis其它面试问题-redis是单线程的,但是为什么还那么快
redis是单线程的,但是为什么还那么快?
- redis是纯内存操作,执行速度非常快。
- 采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题。
- 使用I/0多路复用模型,非阻塞的IO。
能解释一下I/O多路复用模型?
-
i/o多路复用
是指利用单个线程来同时监听多个socket,并在某个socket可读、可写时得到通知,从而避免无效等待,充分利用CPU资源。目前的I/O多路复用都是采用的epoll模式实现,它会在通知用户进程socket就绪的同时,把已就绪的socket写入用户空间,不需要挨个遍历socket来判断是否就绪,提升了性能。
-
redis网络模型
就是使用I/O多路复用结合事件的处理器来应对多个socket请求
- 连接应答处理器
- 命令回复处理器,在Redis6.0之后,为了提升更好的性能,使用了多线程来处理回复事件
- 命令请求处理器,在Redis6.0之后,将命令的转换使用了多线程,增加命令转换速度,在命令执行的时候,依然是单线程。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 易语言 —— 开山篇
· 实操Deepseek接入个人知识库
· Trae初体验