Redis面试总结

redis使用场景

 

1.redis缓存穿透问题:

    什么是缓存穿透:

查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库

解决方案:

方案一:

缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存

优点:简单

缺点:消耗内存,可能会发生不一致的问题。

方案二:

布隆过滤器

优点:内存占用较少,没有多余的key

缺点:实现复杂,存在误判

 bitmap(位图):相当于是以一个(bit)位为单位的数组,数组中每个单元只能存储二进制数0或1

布隆过滤器作用:布隆过滤器可以用于检索一个元素是否在一个集合中。

 

 会产生误判(不能被消除):

误判率:数组越小误判率就越大,数组越大误判率就越小,但是同时带来了更多的内存消耗。

 减小误判:

2.redis缓存击穿问题

 什么是缓存击穿:

给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮。

 解决方案一:互斥锁(分布式锁)(强一致性:性能比较差)

 解决方案二:逻辑过期(高可用,性能优,不能保证数据绝对一致)

 3.redis缓存雪崩问题

        缓存雪崩:

        是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。

 

 

 4.redis缓存双写一致性问题

双写一致性:

当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致。

方案一:

先删除缓存还是先修改数据库?

 都会出现问题(脏数据问题)

为什么要删除两次?

为什么要延时一会?

控制一部分脏数据问题,不能保证强一致性。

方案二(一致性要求高):

加互斥锁(强一致性,性能低)

读锁

 写锁(排它锁):

方案二 (异步通知保证数据的最终一致性):

1.mq

2.canal

 面试问题:

redis作为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)

1.介绍自己简历上的业务,我们当时是把文章的热点数据存入到了缓存中,虽然是热点数据,但是实时要求性并没有那么高,所以,我们当时采用的是异步的方案同步的数据。

2.我们当时是把抢券的库存存入到了缓存中,这个需要实时的进行数据同步,为了保证数据的强一致性,我们当时采用的是redisson提供的读写锁来保证数据的同步。

那你来介绍一下异步的方案(你来介绍一下redisson读写锁的这种方案)

 1.允许延时一致的业务,采用异步通知

        使用mq中间中间件,更新数据之后,通知缓存删除

        利用canal中间件,不需要修改业务代码,伪装为mysql的一个从节点,canal通过读取binlog数据更新缓存

2.强一致性,采用Redisson提供的读写锁

        共享锁:读锁readLock,加锁之后,其他线程可以共享读操作

        排他锁:独占锁writeLock也叫加锁之后阻塞其他线程读写操作

面试回答:

 Redis持久化

 RDB:

RDB全称Redis Database Backup life(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。

    Redis内部有出发RDB的机制,可以在redis.conf文件中找到,格式如下:

 RDB执行原理:

bgsave开始时会fork(克隆)主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入RDB文件。

 

AOF:

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

 

 因为是记录命令,AOF文件会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意思。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。

 

 面试问题:

Redis数据过期策略 

 Redis数据删除策略-惰性删除

惰性删除:设置该key过期时间后,我们不管它,当需要key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。

 

优点:对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查

缺点:对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放。

Redis数据删除策略-定期删除

定期删除:每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机key进行检查,并删除其中过期key)

定期清理有两种模式:

SLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf的hz选项来调整这个次数

FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

优点:可以通过限制删除操作执行的时长和频率来减少删除操作对CPU的影响。另外定期删除,也能有效释放过期键占用的内存。

缺点:难以确定删除操作执行的时长和频率。

Redis的过期删除策略:惰性删除 + 定期删除两种策略进行配合使用。

面试问题:

 Redis数据淘汰策略

 数据淘汰策略:当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一规则将内存中的数据删除掉,这种数据的删除规则则被称之为内存的淘汰策略。

Redis'支持8种不同策略来选择要删除的key

 数据淘汰策略-使用建议

1.优先使用allkeys-lru策略。充分利用LRU算法的优势,把最近最常访问的数据留在缓存中。如果业务有明显的冷热数据区分,建议使用。

2.如果业务中数据访问频率差别不大,没有明显冷热数据区分,建议使用allkeys-random,随机选择淘汰。

3.如果业务中有置顶的需求,可以使用volatile-lru策略,同时置顶数据不设置过期时间,这些数据就一直不被删除,会淘汰其他设置过期时间的数据。

4.如果业务中有短时高频访问的数据,可以使用allkeys-ifu或volatile-lfu策略

有关数据淘汰策略其他的面试问题

1.数据库中有1000万数据,Redis只能缓存20W数据,如何保证Redis中的数据都是热点数据?

使用allkeys-lru(挑选最近最少使用的数据淘汰)淘汰策略,留下来的都是经常访问的热点数据

2.Redis的内存用完了会发生什么?

主要看数据淘汰策略是什么?如果是默认的配置(noeviction),会直接报错。

总结:

1.Redis提供了8种不同的数据淘汰策略,默认是noeviction不删除任何数据,内存不足直接报错。

2.LRU:最近最少使用。用当前时间减去最后一次的访问时间,这个值越大则淘汰优先级越高。

3.LFU:最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。

平时开发过程中用的比较多的就是allkeys-lru(结合自己的业务场景)

面试问题:

 

Redis分布式锁:

 

 

 Redis实现分布式锁主要利用Redis的sentnx命令。setnx是SET if not exists(如果不存在,则SET)的简写

 

 代码实现:

 

 redisson实现的分布式锁-可重入

 redisson实现的分布式锁-主从一致性

 

Redis分布式锁是如何实现的:

 面试问题:

 

Redis其他面试问题: 

主从复制

主从数据同步原理:

主从全量同步:

 

主从增量同步(slave(从节点)重启或后期数据变化):

 

 

 面试问题:

 

 

Redis哨兵模式:

 

 服务状态监控:

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例都发送ping命令:

主观下线:如果sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线。

客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

 

哨兵选主规则:

首先判断主与从节点断开时间长短,如超过指定值就排该从节点

然后判断从节点的slave-priority值,越小优先级越高。

如果slave-priority一样,则判断slave节点的offset值,越大优先级越高、

最后是判断slave节点的运行id大小,越小优先级越高。

面试问题:

 

 

分片集群结构 

主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决;

海量数据存储问题

高并发写的问题

使用分片集群可以解决上述问题,分片集群特征:

集群中有多个master,每个master保存不同的数据

每个master都可以有多个slave节点

master之前通过ping检测彼此健康状态

客户端请求可以访问集群任意节点,最终都会被转发到正确节点。

分片集群结构-数据读写: 

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

面试问题: 

 

 Redis是单线程的,但是为什么还那么快

        Redis是纯内存操作,执行速度非常快

        采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题

        采用I/O多路复用模型,非阻塞I/O

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

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

        用户空间和内核空间

        常见的IO模型

                        阻塞IO(Blocking IO)

                        非阻塞IO(Nonblocking IO)

                        IO多路复用(IO Multiplexing)

        Redis网络模型

 

 

 

 IO多路复用:selelct模式一次性传递多个socket进程,只要有就绪的数据就会返回readable然后调用recvfrom函数,IO和阻塞IO直接调用recvfrom函数

IO多路复用:

IO多路复用是利用单个线程来同时监听多个Socket,并在某个Socket可读,可写时得到通知,从而避免无效的等待,充分利用CPU资源。不过监听Socket的方式,通知的方式又有多种实现,常见的有:

        select

        poll

        epoll

差异:

         select和poll只会通知用户进程有Socket就绪,但不确定具体是哪个Socket,需要用户进程逐个遍历Socket来确认

        epoll则会在通知用户进程Socket就绪的同时,把已就绪的Socket写入用户空间

面试题:

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
关于Java和Redis面试题,你可以参考以下资源: 1. "Java基础教程(入门篇)"这本书中可能包含与Java和Redis相关的基础知识点,例如如何连接和操作Redis以及在Java中使用Redis的常见场景。 2. "java面试大集合"这本书中可能包含Java和Redis面试题,涵盖了Java技术栈以及与Redis相关的问题。你可以浏览这本书中的相关章节以寻找你感兴趣的Java和Redis面试题。 3. "Java基础教程(进阶篇)"这本书可能包含更深入的Java和Redis面试题,例如Java高并发和如何在Java中使用Redis进行缓存。 这些资源可能会给你提供一些有关Java和Redis面试题的参考。你可以根据自己的需求和兴趣选择适合的资源进行学习。希望这些资源能帮助到你。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [redis面试总结(附答案)](https://blog.csdn.net/guorui_java/article/details/117194603)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [java面试大集合一共485页](https://download.csdn.net/download/wm9028/88268176)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值