大厂面试Redis高频15问:数据结构+持久化+集群全覆盖
涵盖Redis数据结构、持久化、集群、缓存问题等15道大厂高频面试题,每题含考察点与答案方向,助你全面备战Redis面试。
背景介绍
Redis这块我是真的踩过坑。之前在一家创业公司做项目,缓存方案全靠自己摸索,出了好几次线上事故——缓存雪崩那次直接导致服务不可用半小时。后来跳槽准备大厂面试的时候,我花了两周时间把Redis从数据结构到集群方案全部梳理了一遍,整理出这15道最常考的题目。说实话,Redis面试的套路性很强,准备到位了基本都能答上来。
一、数据结构(4题)
1. Redis的5种基本数据类型及底层实现?
考察点:数据结构底层原理
String底层是SDS(Simple Dynamic String),相比C字符串多了len和free字段,O(1)获取长度,二进制安全,支持动态扩容。List底层3.2版本前是ziplist+linkedlist,之后统一用quicklist(ziplist+双向链表)。Hash底层ziplist或hashtable,元素少时用ziplist省内存。Set底层intset或hashtable,全是整数且数量少时用intset。ZSet底层ziplist或skiplist+hashtable。面试官最爱追问的是:什么时候从ziplist转换成其他结构?答案是元素数量或单个元素大小超过阈值时。
2. 跳表是什么?为什么Redis用跳表不用红黑树?
考察点:有序集合底层实现
跳表是一种多层链表结构,通过随机层数实现O(logN)的查找、插入、删除。Redis用跳表而不用红黑树的原因:实现更简单,代码可读性好;范围查询更方便,链表结构天然支持顺序遍历;并发场景下更容易修改(虽然Redis是单线程)。跳表每个节点随机生成1-32层,层越高概率越低。面试的时候我把跳表的查找过程画出来,面试官直接说"理解得很清楚"。
3. 压缩列表(ziplist)是什么?
考察点:内存优化机制
ziplist是一块连续内存存储的列表结构,为了节省内存设计的。每个entry包含prevlen(前一个节点长度,用于反向遍历)和encoding(编码方式)。优点是内存紧凑,缓存友好;缺点是连锁更新问题——中间某个节点长度变化可能导致后续所有节点的prevlen字段都需要扩展。Redis 7.0用listpack替代了ziplist,解决了连锁更新问题。这个细节面试官很爱问。
4. Redis Stream是什么?
考察点:新数据结构了解
Stream是Redis 5.0引入的数据类型,类似于Kafka的消息队列设计。支持消费组、消息确认、持久化,比Pub/Sub更可靠。核心概念:消息ID(时间戳+序号)、Consumer Group、Pending Entries List(PEL)。适合轻量级消息队列场景,不需要引入Kafka或RabbitMQ。但要注意:Stream的消息堆积会影响内存,需要设置MAXLEN限制。
二、持久化(3题)
5. RDB和AOF的区别?
考察点:持久化方案对比
RDB是二进制快照文件,fork子进程生成,恢复速度快,但可能丢失最后一次快照后的数据。AOF是追加写入的操作日志,默认每秒fsync,数据安全性更高,但文件体积大、恢复慢。RDB适合做冷备份,AOF适合做热备份。面试官经常问:如果同时开启RDB和AOF,Redis重启时加载哪个?答案是AOF,因为AOF的数据更完整。
6. 混合持久化是什么?
考察点:持久化优化方案
Redis 4.0引入混合持久化:AOF重写时把RDB格式的数据写在AOF文件前面,后面的增量数据用AOF格式。这样既保证了恢复速度(RDB部分加载快),又保证了数据完整性(AOF部分记录增量)。混合持久化通过aof-use-rdb-preamble yes开启。面试官追问:AOF重写的过程是什么?主进程fork子进程→子进程重写→主进程同时将新命令写入AOF重写缓冲区→子进程完成后主进程将缓冲区数据追加到新AOF文件→替换旧文件。
7. 生产环境如何选择持久化方案?
考察点:实际运维经验
纯缓存场景可以关闭持久化,获得最佳性能;需要数据安全性的场景推荐混合持久化;如果对数据丢失极度敏感,用AOF+每秒fsync。关键配置建议:RDB的save策略根据业务调整;AOF的fsync策略选everysec(兼顾性能和安全);开启混合持久化;定期备份RDB文件到远程存储。我之前在生产环境就是因为AOF文件太大导致重启恢复慢,后来开启了混合持久化,恢复时间从30分钟降到了2分钟。
三、集群(3题)
8. Redis主从复制原理?
考察点:高可用基础架构
全量复制:从库首次连接或断开太久,主库生成RDB发送给从库,发送期间的新命令写入replication buffer,RDB发送完后发送buffer中的命令。部分复制:从库短暂断开,主库维护repl_backlog环形缓冲区,从库携带offset请求增量数据。关键参数:repl-backlog-size默认1MB,建议调大到256MB以上避免频繁全量复制。面试官会追问:主从延迟怎么处理?读写分离时从库可能读到旧数据,关键业务可以强制读主库。
9. 哨兵模式原理?
考察点:自动故障转移
哨兵集群监控Redis主从节点,通过心跳检测判断主库是否下线。主观下线:单个哨兵认为主库不可用;客观下线:超过半数哨兵认为主库不可用。故障转移流程:选举领头哨兵→选择新主库(优先级>复制偏移量>runid最小)→通知从库复制新主库→通知客户端新主库地址。面试官最爱问:哨兵之间如何发现彼此?通过主库的pub/sub频道__sentinel__:hello互相发现。
10. Redis Cluster分片原理?
考察点:分布式架构
Redis Cluster有16384个哈希槽,每个主节点负责一部分槽。key通过CRC16(key) % 16384计算所属槽位。客户端访问时如果key不在当前节点,会返回MOVED重定向。集群至少需要6个节点(3主3从)保证高可用。常见问题:集群不支持多key操作(除非key在同一槽位,可以用hash tag解决);扩缩容需要手动迁移槽位。面试官追问:为什么是16384个槽?因为节点间心跳包需要携带槽位信息,16384个槽用2KB就能表示,更大的槽数会增加网络开销。
四、应用(3题)
11. 缓存穿透、击穿、雪崩分别是什么?怎么解决?
考察点:缓存常见问题
穿透:查询不存在的数据,缓存和数据库都没有,请求直达数据库。解决方案:布隆过滤器、缓存空值。击穿:热点key过期瞬间,大量请求打到数据库。解决方案:互斥锁、热点key永不过期。雪崩:大量key同时过期或Redis宕机,请求全部打到数据库。解决方案:过期时间加随机值、Redis集群高可用、限流降级。我之前遇到的线上事故就是雪崩——大量key同一时间过期,后来给过期时间加了随机偏移量就解决了。
12. Redis分布式锁怎么实现?
考察点:分布式锁方案
基础方案:SET key value NX EX seconds,NX保证互斥,EX设置过期时间防止死锁。释放锁时用Lua脚本保证原子性(判断value是否是自己设置的再删除)。Redlock算法:在多个独立Redis实例上同时加锁,超过半数成功才算获取锁。生产环境建议用Redisson框架,它封装了看门狗机制自动续期,解决了锁过期但业务未完成的问题。面试官追问:Redlock一定安全吗?Martin Kleppmann曾发文质疑,认为在时钟跳变等场景下不安全。这个争议点了解即可。
13. Redis做消息队列怎么做?
考察点:消息队列方案
三种方案:List+LPUSH/BRPOP实现简单队列,支持阻塞等待但不支持消费组;Pub/Sub支持多消费者但不持久化,消息丢失无法恢复;Stream支持消费组、消息确认、持久化,是Redis 5.0+推荐方案。选择建议:简单场景用List,需要发布订阅用Pub/Sub,需要可靠消息用Stream。但Redis做消息队列只适合轻量场景,量大了还是上Kafka或RabbitMQ。
五、其他(2题)
14. 内存淘汰策略有哪些?
考察点:内存管理机制
8种策略:noeviction(默认,不淘汰直接报错);allkeys-lru(所有key中淘汰最近最少使用的);volatile-lru(过期key中淘汰LRU);allkeys-lfu(所有key中淘汰使用频率最低的,Redis 4.0+);volatile-lfu(过期key中淘汰LFU);allkeys-random(随机淘汰);volatile-random(过期key中随机淘汰);volatile-ttl(淘汰剩余时间最短的)。生产环境推荐allkeys-lru或allkeys-lfu。LFU比LRU更优,因为它考虑了访问频率而不只是最近访问时间。
15. 过期删除机制是什么?
考察点:key过期处理
Redis采用惰性删除+定期删除双重策略。惰性删除:访问key时才检查是否过期,过期则删除。定期删除:每100ms随机抽取一批设置了过期时间的key检查,过期则删除,如果过期key超过25%则继续检查。这种组合方式在CPU和内存之间做了平衡——如果只用惰性删除,过期key长期不访问会浪费内存;如果只用定期删除,全量扫描太耗CPU。面试官可能追问:如果大量key同时过期会怎样?定期删除会持续执行多轮,可能影响正常请求的响应时间。
心得建议
Redis面试准备的关键是:数据结构要理解底层实现,不能只停留在"5种类型"的表面;持久化和集群方案要结合实际运维经验来答,最好能说出自己踩过的坑;缓存问题(穿透/击穿/雪崩)是必考题,解决方案要能脱口而出。另外,Redis 7.0的新特性(Function替代Lua脚本、listpack替代ziplist、多AOF文件)也值得关注,能体现你的技术前沿性。
FAQ
Q:Redis面试需要了解源码吗?
不需要深入源码,但了解关键数据结构的实现(如SDS、跳表、ziplist)会非常加分。
Q:Redis单线程为什么这么快?
纯内存操作、IO多路复用、避免上下文切换和锁竞争。注意:Redis 6.0引入多线程处理网络IO,但命令执行仍是单线程。
Q:生产环境Redis怎么监控?
重点关注:内存使用率、命中率、连接数、慢查询、主从延迟。可以用Redis Exporter+Prometheus+Grafana搭建监控。