最近参加了几场后端开发的面试,Redis是必问的技术点。而且,因为Redis 7.4在2024年发布了,面试官特别喜欢问7.4的新特性和相关问题。
这篇文章就来整理一下我被问到的Redis 7.4面试题,附上我的回答思路和相关知识点。如果你也在准备面试,或者想深入了解Redis,希望这篇文章能帮到你。
问题一:Redis 7.4有哪些新特性?
这是被问得最多的一个问题。面试官想知道你有没有关注Redis的最新版本。
我的回答思路是:
Redis 7.4在2024年发布,主要有这些新特性:
第一,集群模式的增强。Redis 7.4改进了集群的故障检测和故障转移机制,减少了故障转移的时间。同时,优化了集群的分片迁移,支持更平滑的slot迁移,减少了迁移过程中的性能影响。
第二,性能优化。Redis 7.4优化了多线程IO的性能,在高并发场景下吞吐量提升了约20%。同时,优化了内存分配器,减少了内存碎片。还优化了大key的处理,大key的删除和迁移不再阻塞主线程。
第三,新的数据结构和命令。Redis 7.4增加了一些新的命令和功能,比如对Hash类型的增强,支持更高效的批量操作;对Stream类型的优化,支持更灵活的消费者组管理。
第四,安全增强。Redis 7.4增强了访问控制,支持更细粒度的权限管理。同时,改进了TLS支持,性能更好,配置更灵活。
第五,可观测性增强。Redis 7.4增加了更多的监控指标,比如更详细的慢查询日志、内存使用分析、命令统计等。同时,改进了INFO命令的输出,提供了更多有用的信息。
第六,客户端缓存的增强。Redis 7.4改进了客户端缓存(Client-side caching)机制,支持更高效的缓存失效通知,减少了服务端的开销。
回答这个问题的时候,不用把所有新特性都列出来,挑几个重要的、你熟悉的说就行。关键是要让面试官知道,你确实关注了Redis的最新发展。
问题二:Redis的数据结构有哪些?分别用在什么场景?
这是Redis的基础问题,但面试官会追问得比较深。
我的回答:
Redis有五种基础数据结构:String、Hash、List、Set、Sorted Set,还有几种高级数据结构:Bitmap、HyperLogLog、Geo、Stream、Bloom Filter(Redis 7.4中作为模块内置)。
String:最基础的类型,二进制安全,可以存字符串、数字、二进制数据。常用场景:缓存用户信息、计数器、分布式锁、Session存储。
Hash:键值对的集合,适合存储对象。常用场景:存储用户属性、商品信息、配置项。相比把对象序列化成String,Hash可以单独修改某个字段,开销更小。
List:有序的字符串列表,底层是双向链表。常用场景:消息队列、最新列表、任务队列。支持左右两端的push和pop,可以实现栈和队列。
Set:无序的字符串集合,元素不重复。常用场景:标签系统、共同好友、去重、抽奖。支持交集、并集、差集等集合运算。
Sorted Set:有序的集合,每个元素有一个score,按score排序。常用场景:排行榜、带权重的任务队列、范围查找。
Bitmap:位图,用位来存储数据。常用场景:用户签到、在线状态统计、布隆过滤器。空间效率很高,一亿个用户的签到数据只需要12.5MB。
HyperLogLog:基数统计的数据结构,用很小的空间统计不重复元素的数量。常用场景:UV统计、独立访客统计。有一定的误差(约0.81%),但空间效率极高。
Geo:地理位置数据结构,存储经纬度,支持距离计算和范围查找。常用场景:附近的人、附近的商家、距离计算。
Stream:Redis 5.0引入的消息队列类型,支持消费者组。常用场景:消息队列、事件流、日志收集。比List更专业,支持消息确认、消费组、消息回溯等。
Bloom Filter:布隆过滤器,Redis 7.4中作为内置模块。常用场景:缓存穿透防护、去重、垃圾邮件过滤。有一定的误判率,但空间效率很高。
回答这个问题的时候,不仅要说数据结构的名字,还要说底层实现和适用场景。面试官可能会追问某个数据结构的底层实现,比如Hash的底层是哈希表+链表,List的底层是quicklist,Sorted Set的底层是跳表+哈希表。
问题三:Redis的持久化机制有哪些?有什么区别?
这也是高频面试题。
我的回答:
Redis有两种持久化机制:RDB和AOF。
RDB(Redis Database):在指定的时间间隔内,将内存中的数据生成快照,保存到磁盘。RDB文件是一个压缩的二进制文件,包含了某个时间点的完整数据。
RDB的优点:
- 文件紧凑,适合备份和灾难恢复
- 恢复速度快,直接加载RDB文件就能恢复数据
- 对性能影响小,fork子进程来做持久化,主进程继续处理请求
RDB的缺点:
- 数据安全性较低,如果Redis宕机,会丢失最后一次快照之后的数据
- 大数据量时,fork子进程可能会阻塞主线程,导致短暂的服务不可用
AOF(Append Only File):将每个写命令都记录到日志文件中,恢复的时候重新执行这些命令来恢复数据。
AOF的优点:
- 数据安全性高,可以配置每秒同步或者每次写都同步,最多丢失1秒的数据
- AOF文件是文本格式,可读性好,容易修复
- 支持后台重写(AOF rewrite),自动压缩AOF文件
AOF的缺点:
- AOF文件通常比RDB文件大
- 恢复速度比RDB慢,因为要重新执行所有命令
- 每次写都要记录日志,对性能有一定影响
Redis 4.0之后,支持混合持久化(RDB-AOF hybrid),就是在AOF重写的时候,把当前数据以RDB格式写入AOF文件,之后的写命令以AOF格式追加。这样结合了RDB恢复快和AOF数据安全的优点。Redis 7.4中,混合持久化是默认开启的。
实际生产中,一般是RDB和AOF同时开启,既保证数据安全,又有较快的恢复速度。
问题四:Redis的过期键删除策略是什么?
这个问题考察对Redis内部机制的理解。
我的回答:
Redis的过期键删除策略有三种:定时删除、惰性删除、定期删除。
定时删除:在设置键的过期时间时,同时创建一个定时器,到时间就删除键。优点是内存释放及时,缺点是如果过期键很多,定时器会占用大量CPU资源,影响性能。Redis没有采用这种策略。
惰性删除:键过期了不主动删除,等下次访问的时候,检查是否过期,如果过期了就删除。优点是对CPU友好,只在访问的时候才检查,缺点是如果过期键一直不被访问,就会一直占用内存,造成内存泄漏。
定期删除:每隔一段时间,随机检查一批设置了过期时间的键,如果过期了就删除。优点是通过控制删除的频率和时长,平衡了CPU和内存的使用,缺点是可能还有一些过期键没被检查到,继续占用内存。
Redis实际采用的是惰性删除 + 定期删除的组合策略。这样既不会因为定时删除占用太多CPU,也不会因为惰性删除导致太多内存浪费。
另外,当内存达到maxmemory限制时,Redis会触发内存淘汰策略,删除一些键来释放内存。淘汰策略有:noeviction(不删除,返回错误)、allkeys-lru(删除最近最少使用的键)、volatile-lru(在设置了过期时间的键中删除最近最少使用的)、allkeys-lfu(删除最不经常使用的)、volatile-lfu、allkeys-random(随机删除)、volatile-random、volatile-ttl(删除即将过期的)。
Redis 7.4中,对LRU和LFU算法做了优化,淘汰更精准,内存使用更高效。
问题五:缓存穿透、缓存击穿、缓存雪崩分别是什么?怎么解决?
这是Redis缓存相关的经典面试题,几乎每场面试都会问。
我的回答:
缓存穿透:查询一个数据库中不存在的数据,缓存中也没有,每次请求都会打到数据库。比如黑客用不存在的ID频繁查询,导致数据库压力过大。
解决方案:
- 缓存空值:查询不到的数据,也在缓存中存一个空值,设置较短的过期时间
- 布隆过滤器:在缓存前面加一层布隆过滤器,不存在的数据直接拦截,不查询数据库
- 参数校验:对请求参数做校验,非法参数直接拒绝
缓存击穿:一个热点key,在缓存过期的瞬间,大量并发请求同时打到数据库,导致数据库压力骤增。
解决方案:
- 互斥锁:缓存失效时,用分布式锁控制只有一个请求去查数据库并更新缓存,其他请求等待
- 逻辑过期:不设置实际的过期时间,而是在value中存一个逻辑过期时间,发现过期后异步更新缓存,同时返回旧数据
- 热点key永不过期:对于特别热的key,设置为永不过期,后台异步更新
缓存雪崩:大量的key在同一时间过期,或者Redis宕机,导致大量请求同时打到数据库,导致数据库压力过大甚至崩溃。
解决方案:
- 过期时间加随机值:给key的过期时间加上一个随机值,避免大量key同时过期
- 多级缓存:本地缓存 + Redis缓存,Redis挂了还有本地缓存
- 高可用集群:用Redis集群或者哨兵,避免单点故障
- 限流降级:在缓存失效时,限制请求量,或者返回默认值,保护数据库
- 预热:在流量高峰前,提前把热点数据加载到缓存中
回答这个问题的时候,要把三种问题的区别说清楚,然后分别说解决方案。面试官可能会追问某个方案的具体实现,比如互斥锁怎么实现,布隆过滤器的原理等。
问题六:Redis集群的原理是什么?
这个问题考察对Redis集群的理解。
我的回答:
Redis集群(Redis Cluster)是Redis的分布式方案,通过数据分片来实现横向扩展。
Redis集群的核心原理:
第一,数据分片。Redis集群有16384个哈希槽(hash slot),每个key通过CRC16算法计算出一个值,然后对16384取模,确定这个key属于哪个槽。每个节点负责一部分槽,数据就分散到不同的节点上。
第二,节点通信。集群中的每个节点都和其他节点保持通信,通过Gossip协议交换节点状态、槽分配等信息。每个节点都知道整个集群的状态,知道每个槽在哪个节点上。
第三,请求路由。客户端请求某个key时,先计算这个key属于哪个槽,然后找到负责这个槽的节点,直接请求那个节点。如果请求的key不在当前节点,节点会返回MOVED重定向,告诉客户端应该去哪个节点。
第四,高可用。每个主节点可以有多个从节点,主节点宕机时,从节点会自动选举出新的主节点,继续提供服务。故障检测是通过节点之间的心跳和投票来完成的。
第五,扩容缩容。增加节点时,把其他节点上的槽迁移到新节点;减少节点时,把该节点的槽迁移到其他节点。迁移过程中,集群继续提供服务。
Redis 7.4对集群做了不少优化:
- 故障转移速度更快,减少了不可用时间
- 槽迁移更平滑,减少了迁移过程中的性能影响
- 优化了集群的网络通信,减少了Gossip协议的带宽占用
回答这个问题的时候,要把分片、路由、高可用这几个核心点说清楚。面试官可能会追问哈希槽的数量为什么是16384,或者故障转移的具体流程。
问题七:Redis为什么这么快?
这是一个经典的开放性问题。
我的回答:
Redis之所以快,主要有几个原因:
第一,纯内存操作。Redis的数据都存在内存中,读写都是内存操作,速度非常快,不像数据库需要磁盘IO。内存的读写速度是磁盘的几百倍甚至上千倍。
第二,单线程模型。Redis的核心是单线程的,避免了多线程的上下文切换和锁竞争。虽然是单线程,但因为内存操作很快,加上IO多路复用,单线程也能处理很高的并发。
第三,IO多路复用。Redis用了epoll(Linux)或者kqueue(BSD)的IO多路复用机制,一个线程就能处理大量的并发连接。不需要为每个连接创建一个线程,节省了线程创建和切换的开销。
第四,高效的数据结构。Redis的每种数据结构,底层都用了高效的实现。比如String用了SDS(简单动态字符串),Hash用了哈希表+压缩列表,List用了quicklist,Sorted Set用了跳表。这些数据结构的操作时间复杂度都很低。
第五,持久化优化。Redis的持久化是在后台做的,fork子进程来写RDB或者AOF,不影响主线程的处理。而且AOF是追加写,顺序写磁盘,速度很快。
第六,Redis 7.4的多线程优化。虽然核心是单线程,但Redis 6.0之后引入了多线程IO,网络IO的读写用多线程处理,命令执行还是单线程。Redis 7.4进一步优化了多线程IO,高并发下性能提升明显。
回答这个问题的时候,要从内存、线程模型、IO模型、数据结构等几个方面来说。面试官可能会追问单线程的优缺点,或者IO多路复用的具体原理。
问题八:Redis 7.4中,你觉得最实用的新特性是什么?
这个问题考察你对Redis 7.4的深入理解,以及实际使用经验。
我的回答:
我觉得Redis 7.4最实用的新特性是客户端缓存(Client-side caching)的增强。
客户端缓存的原理是:Redis服务端通知客户端,哪些key被修改了,客户端可以把这些key的本地缓存失效。这样,客户端可以在本地缓存热点数据,大部分请求不需要访问Redis,直接从本地缓存读取,大大降低了Redis的压力和请求延迟。
在Redis 7.4之前,客户端缓存已经有了,但有一些问题:比如服务端维护客户端的缓存key列表开销大,通知机制不够灵活。Redis 7.4做了优化:
- 支持更细粒度的缓存失效通知,可以按key前缀或者模式通知
- 减少了服务端的内存开销,用更高效的数据结构管理客户端缓存
- 支持广播模式,一个key修改时,通知所有订阅了的客户端
- 优化了断线重连后的缓存同步
这个特性在高并发场景下非常实用。比如,我们的业务中有一些配置数据和字典数据,读多写少,非常适合用客户端缓存。开启客户端缓存之后,这些数据的请求大部分在本地就命中了,Redis的QPS降低了60%以上,请求延迟也从几毫秒降到了微秒级。
当然,客户端缓存也不是万能的,它适合读多写少、对一致性要求不那么高的数据。对于写多或者要求强一致性的数据,还是要直接访问Redis。
回答这个问题的时候,选一个你真正了解的特性,说清楚它的原理、使用场景和实际效果。不要选一个你只是听说过但不了解的特性,面试官一追问就露馅了。
一些面试建议
最后,给一些Redis面试的建议。
第一,基础要扎实。数据结构、持久化、过期策略、淘汰策略、集群原理,这些是必问的,一定要理解透彻,不要只背答案。
第二,关注新版本。Redis更新很快,面试官喜欢问新版本的特性。平时要关注Redis的release notes,了解新特性和改进。
第三,结合实际经验。回答问题的时候,尽量结合自己的实际项目经验。比如说到缓存穿透,就说你在项目中是怎么解决的,用了什么方案,效果如何。这样比单纯背理论更有说服力。
第四,理解原理,不要只记结论。比如问到缓存雪崩,不要只说"加随机值",要说清楚为什么加随机值能解决问题,背后的原理是什么。
第五,了解生态。Redis不只是一个缓存,它还有很多周边工具和生态,比如Redisson、Lettuce、RedisInsight、Redis Stack等。了解这些,能体现你的知识面。
写在最后
Redis是后端开发的必备技能,也是面试的高频考点。Redis 7.4的发布,带来了很多新特性和改进,也成为了面试的新热点。
这篇文章整理了我被问到的一些Redis 7.4面试题,附上了回答思路。希望能帮正在准备面试的你。
但面试题只是一个参考,真正重要的是理解原理、积累经验。把Redis的核心机制搞懂了,不管面试官怎么问,都能从容应对。
如果你也在准备Redis相关的面试,祝你面试顺利,拿到心仪的offer。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录