Redis面试题

1.Redis的使用场景

  • 缓存
    • 缓存三兄弟(穿透、击穿、雪崩)
    • 双写一致
    • 持久化
    • 数据过期策略
    • 数据淘汰策略
  • 分布式锁
    • setnx
    • redisson
  • 消息队列、延迟队列
    • 何种数据类型

2.什么是缓存穿透,怎么解决

  • 缓存穿透:查询一个不存在数据,MySQL查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库,这种情况大概率是遭到了攻击。
  • 解决方案:
    • 1.缓存空数据:查询结果为空时,仍把这个空结果存入缓存。
      • 优:简单
      • 缺:消耗内存,可能发生不一致的问题
    • 2.布隆过滤器

什么是布隆过滤器?

  • 布隆过滤器:用于检索一个元素是否在一个集合中,拦截不存在的数据。我们当时使用的是redisson实现的布隆过滤器。
  • 底层原理:
    • 初始化一个bitmap(位图)的数组,默认为0
    • 存储时通过多次hash计算,根据哈希值将对应数据改为1
    • 查找时根据计算的hash判断位置是否为1
  • 缺:可能会产生一定的误判、实现复杂
  • 解决方案:
    • 1.设置误判率,不会超过5%
    • 2.增加数组的长度

误判率:数组越小误判率越大,数组越大误判率越小,但同时带来了很大内存消耗

3.什么缓存击穿,怎么解决

  • 缓存击穿:给某个key设置了过期时间,当key过期时,恰好这时对这个key有大量的并发请求,这些并发请求可能会瞬间将DB压垮
  • 解决方案:
    • 1.互斥锁,强一致性,性能差
    • 2.逻辑过期,高可用,性能优,不能保证数据绝对一致

4.什么时缓存雪崩,怎么解决

  • 缓存雪崩:在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力
  • 解决方案:
    • 1.给不同的key的TTL添加随机值,让失效时间重复率降低
    • 2.利用Redis集群提高服务的可用性
      • 哨兵模式
      • 集群模式
    • 3.给缓存业务添加降级限流策略(是保底策略,适用穿透、击穿、雪崩)
      • ngxin
      • spring cloud gateway
    • 4.给业务添加多级缓存
      • Guava
      • Caffeine

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

5.Redis作为缓存,MySQL的数据如何与Redis进行同步(双写一致性)

  • 双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要求要一致
  • 读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间
  • 写操作:延迟双删

1.什么使延时双删?
先删缓存,再修改数据库,再延时后删除缓存

2.先删缓存还是先修改数据库?
都会导致脏数据的出现,使数据库与缓存不一致

3.为什么要删除两次缓存?
降低脏数据的出现

4.为什么要延时删除?
一般是为了等待主从节点同步数据,防止脏数据出现
延时双删可以极大控制风险,但是延时时间不好确定,依旧有脏数据风险

  • 1.业务背景:一致性要求高(抢券)

  • 解决方案:

    • 共享锁:读锁readLock,加锁后,其他线程可以共享读操作
    • 排他锁:也叫独占锁writeLock,加锁后,阻塞其他线程读写操作
  • 2.业务背景:允许延迟一致

  • 解决方案:异步通知保证数据最终一致性

    • 1.使用MQ中间件:更新数据后,通知缓存删除,需要MQ的可靠性
    • 2.使用Canal中间件:基于MySQL的主从同步来实现的。不需要修改业务代码,伪装为MySQL的一个从节点,通过读取binlog数据更新缓存

6.Redis做为缓存,数据的持久化怎么做

  • RDB:数据快照,把Redis内存存储的数据写到磁盘上,当Redis实例宕机恢复数据的时候,方便从RDB的快照文件中恢复数据
  • AOF:追加文件,当Redis操作写命令的时候,都会存储到这个文件中,当Redis实例宕机恢复数据的时候,会从这个文件中,再执行一遍命令来恢复数据
  • 二者对比:数据完整性,文件大小,宕机恢复速度,数据恢复优先级,系统资源占用,使用场景

7.Redis中的key过期后,会立即删除吗(数据过期策略)

  • 数据过期策略:Redis对数据设有数据的有效时间,数据过期以后就要从内存中删除掉,删除时要有数据删除规则,这种删除规则就是数据过期策略
  • 惰性删除:访问key时判断是否过期,过期了就删除
    • 优:对cpu友好,不浪费性能
    • 缺:对内存不友好,容易积攒
  • 定期删除:定期随机删除一定量的key中过期的key
    • 1.slow模式:定时任务,执行频率10hz,每次不超过25ms,以通过修改配置文件redis.conf的hz选项来调整这个次数
    • 2.fast模式:执行频率不固定,每次事件循环都会尝试执行,但两次间隔不低于2ms,每次耗时不超过1ms
    • 优:既能通过限制时长和频率减少操作对cpu影响,也能定时释放过期占用的内存
    • 缺:难以确定删除操作时长和频率

8.假如缓存过多,内存是有限的,内存占满了怎么办(数据淘汰策略)

  • 数据淘汰策略:当Redis的内存不够用时,此时再向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据淘汰掉
    • noeviction:不淘汰任何key,内存满了不写入新数据(默认)
    • volatile-ttl:对所有TTL的key,TTL剩余的越少越先淘汰
    • allkeys-random:全体,随机淘汰
    • volatile-random:有TTL的,随机淘汰
    • allkeys-lru:全体,LRU(最近最少使用)淘汰
    • volatile-lru:有TTL的,LRU(最近最少使用)淘汰
    • allkeys-lfu:全体,LFU(最少频率使用)淘汰
    • volatile-lfu:有TTL的,LFU(最少频率使用)淘汰

9.Redis分布式锁,是如何实现的

  • 使用场景:集群情况下定时任务,抢单,幂等性
  • setnx:如果不存在则SET
  • redisson:底层实现是使用了setnx和lua脚本(保证原子性)

1.Redisson实现的分布式锁如何合理控制锁的有效时长?
在redisson中提供了WatchDog(看门狗),一个线程获取锁成功以后,WatchDog会给持有锁的线程续期(默认时每隔十秒续期一次)
由于高并发下,业务执行的很快,新来的业务想要获取锁,不会马上被拒绝,会自动不断尝试,性能得到一定的提升

2.Redisson锁可以重入吗?
可以,多个锁重入需要判断是否是当前线程,在redis中进行存储的时候使用hash结构,来存储线程信息和重入的次数

3.Redisson可以解决主从数据一致的问题吗?
不可以,但是可以使用redisson提供的红锁来解决,但是这样的话,性能就太低了,如果非要保证数据的强一致性,建议采用zookeeper实现的分布式锁

10.Redis集群有哪些方案

  • 主从集群

1.介绍一下redis的主从同步
单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,搭建主从集群,实现读写分离。一般是一主多从,主节点负责写数据,从节点负责读数据

2.说一下主从同步数据的流程
全量同步
增量同步

  • 哨兵模式
    • 功能: 监控、自动故障恢复、通知
    • 服务状态监控:主观下线、客观下线
    • 哨兵选主规则:断开时间、slave-priority、offset值、运行id大小

1.脑裂问题怎么解决
由于网络等原因,使master和salve、sentinel处于不同的网络分区,使得sentinel没有能够心跳感知到master,所以通过选举的方式提升了一个salve为master,这样就存在了两个master,就像大脑分裂了一样,这样会导致客户端还在old master那里写入数据,新节点无法同步数据,当网络恢复后,sentinel会将old master降为salve,这时再从新master同步数据,这会导致old master中的大量数据丢失。
解决方案:
1.设置最少的salve节点个数
2.设置主从数据复制和同步的延迟时间,达不到要求就拒绝请求

  • 分片集群:解决的是,海量数据存储的问题
    • 功能:
      • 1.集群中有多个master,每个master保存不同数据
      • 2.每个master设置多个slave节点,就可以继续增大集群的高并发能力
      • 3.每个master之间通过ping监测彼此健康状态,就类似于哨兵模式了
      • 4.客户端请求可以访问集群任意节点,最终都会被转发到正确节点
    • 读写数据:哈希槽
      • 有 16384 个哈希槽
      • key通过 CRC16 校验后对 16384 取模来决定放置哪个槽,通过槽找到对应的节点进行存储

11.Redis是单线程为什么还那么快

  • 纯内存
  • 单线程,避免不必要的线程上下文切换和安全问题
  • I/O多路复用模型,非阻塞值I/O

1.解释一下I/O复用模型
Redis的性能瓶颈是网络延迟,I/O多路复用模型主要就实现了高效的网络请求
用户空间和内核空间
常见IO模型

  • 阻塞IO:等待和拷贝都阻塞
  • 非阻塞式IO:拷贝阻塞
  • IO多路复用:利用单线程来监听多个Socket,并在某个Socket可读,可写时得到通知,从而避免无效的等待,充分利用cpu资源
    • 实现方式:
      • select,poll:不知道已就绪的Socket是哪一个,要逐渐遍历Socket来确认
      • epoll:在通知用户进程Socket就绪的同时,把已就绪的Socket写入用户空间,不需要挨个遍历Socket来判断是否就绪,提升了性能。

Redis网络模型:使用I/O多路复用结合事件的处理器来应对多个Socket请求

  • 连接应答处理器
  • 命令回复处理器:在Redis6.0之后,使用了多线程来处理回复事件
  • 命令请求处理器:在Redis6.0之后,将命令的转换使用了多线程,增加命令转换速度,在命令执行的时候,依然是单线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暖阳爱学计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值