Redis面试题及详细答案100道(86-100) --- 综合篇
《前后端面试题
》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。
文章目录
- 一、本文面试题目录
- 86. 能说说布隆过滤器吗?它在Redis中有什么应用?
- 87. 说说Redis哈希槽的概念。
- 88. Redis回收进程如何工作的?
- 89. 修改配置不重启Redis会实时生效吗?哪些配置可以?哪些不行?
- 90. 假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?
- 91. 一个Redis实例最多能存放多少的keys?List、Set、Sorted Set它们最多能存放多少元素?
- 92. Redis的链表数据结构的特征有哪些?
- 93. 怎么提高缓存命中率?
- 94. Redis中key已经过期了,但为什么内存并没有释放?
- 95. 说说你对Redis中的I/O多路复用模型的理解。
- 96. Redis支持的发布订阅功能原理是什么?常用命令有哪些?
- 97. Redis主从复制过程中,从节点宕机重启后如何恢复数据?
- 98. Redis的AOF文件过大时,除了自动重写,还可以手动触发重写吗?如何操作?
- 99. Redis的SDS(简单动态字符串)与C语言字符串相比,优势在哪里?
- 100. Redis在高并发场景下,如何保证数据的一致性和准确性?
- 二、100道面试题目录列表
一、本文面试题目录
86. 能说说布隆过滤器吗?它在Redis中有什么应用?
-
原理说明:
布隆过滤器是一种空间高效的概率性数据结构,用于判断一个元素是否在集合中。它通过多个哈希函数将元素映射到一个位数组的多个位上,若所有位均为1,则元素“可能存在”;若有位为0,则元素“一定不存在”。存在假阳性(误判存在),但无假阴性(误判不存在)。 -
Redis中的应用:
Redis通过bfadd
、bfexists
等命令支持布隆过滤器(需加载RedisBloom
模块),主要用于:- 缓存穿透防护:过滤不存在的key,避免请求穿透到数据库。
- 去重场景:如判断用户是否已浏览过某内容。
- 黑名单校验:快速判断IP、手机号是否在黑名单中。
-
示例代码:
# 添加元素到布隆过滤器 BF.ADD user:visited 1001 BF.ADD user:visited 1002# 检查元素是否存在 BF.EXISTS user:visited 1001 # 返回1(可能存在) BF.EXISTS user:visited 2000 # 返回0(一定不存在)
87. 说说Redis哈希槽的概念。
-
原理说明:
哈希槽(Hash Slot)是Redis集群用于数据分片的核心机制。Redis集群将所有数据划分为16384个哈希槽(编号0-16383),每个键通过CRC16(key) % 16384
计算所属的哈希槽,再由集群节点负责处理对应的槽。- 集群中每个主节点负责一部分哈希槽(可配置分配)。
- 哈希槽的分配和迁移由集群自动管理,实现数据的分布式存储和负载均衡。
-
特点:
- 简化数据分片逻辑,无需手动指定键到节点的映射。
- 支持节点动态扩容/缩容,通过迁移哈希槽实现数据迁移。
- 客户端可直接计算键所属槽,与对应节点通信,减少转发开销。
88. Redis回收进程如何工作的?
-
原理说明:
当Redis内存达到maxmemory
配置的上限时,会触发内存回收(淘汰)策略,通过以下步骤工作:- 检测内存超限:定期检查当前内存使用量是否超过
maxmemory
。 - 选择淘汰策略:根据
maxmemory-policy
配置的策略筛选待淘汰键,常见策略包括:volatile-lru
:淘汰设置了过期时间的键中最近最少使用的。allkeys-lru
:淘汰所有键中最近最少使用的。volatile-ttl
:淘汰设置了过期时间的键中剩余过期时间最短的。
- 执行淘汰:删除选中的键,释放内存,直到内存使用量低于
maxmemory
。
- 检测内存超限:定期检查当前内存使用量是否超过
-
注意:
- 若所有键都不满足淘汰条件(如无过期键且策略为
volatile-*
),Redis可能拒绝写入操作。
- 若所有键都不满足淘汰条件(如无过期键且策略为
89. 修改配置不重启Redis会实时生效吗?哪些配置可以?哪些不行?
-
原理说明:
Redis配置分为动态配置(无需重启生效)和静态配置(需重启生效),通过CONFIG SET
命令修改动态配置,CONFIG GET
查看配置。 -
可动态生效的配置(示例):
maxmemory
:内存上限。maxmemory-policy
:内存淘汰策略。slowlog-log-slower-than
:慢查询阈值。client-output-buffer-limit
:客户端输出缓冲区限制。
-
需重启生效的配置(示例):
port
:端口号。bind
:绑定的IP地址。dir
:持久化文件存储目录。appendonly
:是否开启AOF持久化(修改后需手动执行BGREWRITEAOF
初始化)。
-
示例代码:
# 动态修改慢查询阈值为1000微秒 CONFIG SET slowlog-log-slower-than 1000# 查看当前配置 CONFIG GET slowlog-log-slower-than
90. 假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?
-
解决方案:
需高效筛选特定前缀的key,避免全量扫描(如KEYS
命令,会阻塞Redis)。推荐方法:-
使用
SCAN
命令(推荐):
渐进式迭代扫描键,通过游标分批返回结果,不阻塞服务。# 扫描前缀为"prefix:"的key,每次返回100个 SCAN 0 MATCH prefix:* COUNT 100 # 重复执行,直到游标返回0(扫描完成)
-
使用
KEYS
命令(不推荐,仅测试环境):
全量匹配,但会阻塞Redis,适合数据量小的场景。KEYS prefix:*
-
通过Redis集群扫描:
若为集群,需在每个节点分别执行SCAN
,汇总结果。
-
91. 一个Redis实例最多能存放多少的keys?List、Set、Sorted Set它们最多能存放多少元素?
-
容量限制:
Redis对key的数量和数据结构的元素数量没有硬性限制,主要受限于可用内存和操作系统的文件描述符限制。- 理论上,一个Redis实例可存储2^32 - 1个key(约40亿)。
- List、Set、Sorted Set等集合类型,每个结构最多可存储2^32 - 1个元素(约40亿)。
-
实际限制:
实际使用中,需考虑内存消耗和性能。例如,一个包含1亿元素的List会占用大量内存,且操作效率可能下降。
92. Redis的链表数据结构的特征有哪些?
-
特征说明:
Redis的链表是双向链表,用于实现List等数据结构,主要特征包括:- 双向节点:每个节点包含
prev
(前驱)和next
(后继)指针,支持双向遍历。 - 表头表尾指针:链表维护
head
(头节点)和tail
(尾节点),便于快速获取首尾元素。 - 长度计数:链表记录
len
属性,可O(1)时间获取元素数量。 - 无环结构:表头的
prev
和表尾的next
均为NULL
,避免环形引用。 - 多态兼容:链表节点可存储任意类型数据,通过
void*
指针实现。
- 双向节点:每个节点包含
-
优势:
支持高效的首尾插入/删除操作(O(1)),适合实现队列、栈等场景。
93. 怎么提高缓存命中率?
- 关键措施:
缓存命中率是缓存有效利用的核心指标,提升方法包括:- 合理的缓存粒度:避免缓存过大或过小的数据(如缓存用户详情而非整个表)。
- 优化缓存键设计:使用唯一且易命中的键(如
user:{id}
而非模糊前缀)。 - 设置合适的过期时间:避免缓存过期导致频繁回源,可结合业务设置TTL(如热点数据延长过期时间)。
- 预热缓存:系统启动或流量低谷时,主动加载热点数据到缓存。
- 避免缓存穿透:用布隆过滤器过滤不存在的key,减少无效请求。
- 处理缓存雪崩:过期时间加随机偏移量,避免大量key同时失效。
- 缓存热点数据:识别并优先缓存访问频率高的数据(如首页商品、热门文章)。
94. Redis中key已经过期了,但为什么内存并没有释放?
-
可能原因:
- 惰性删除机制:Redis不会主动删除过期键,而是在访问时才检查是否过期(删除)。若过期键未被访问,可能长期驻留内存。
- 定期删除未触发:Redis每秒会随机抽查部分过期键并删除,但存在漏删概率,尤其过期键数量多时。
- 内存淘汰策略未触发:若内存未达
maxmemory
,即使键过期,也不会被淘汰释放内存。 - 键被引用:若过期键被作为其他数据结构(如List、Hash)的元素引用,可能不会被删除。
-
解决方法:
手动执行FLUSHDB
(清空当前库)或DEL key
删除过期键,或调整maxmemory-policy
和定期删除频率。
95. 说说你对Redis中的I/O多路复用模型的理解。
-
原理说明:
Redis是单线程模型,但通过I/O多路复用(如select
、poll
、epoll
、kqueue
)实现高效处理多客户端请求,核心机制:- 事件分离器:内核负责监听多个套接字(socket)的I/O事件(如连接、读、写)。
- 单线程处理:Redis主线程通过I/O多路复用接口(如
epoll_wait
)阻塞等待事件,当事件触发(如客户端发送请求),主线程批量处理就绪事件。 - 非阻塞I/O:避免单个请求的I/O操作阻塞整个线程,提升并发处理能力。
-
优势:
单线程避免线程切换开销,I/O多路复用实现高并发,适合Redis的内存操作(速度快,I/O等待占比高)场景。
96. Redis支持的发布订阅功能原理是什么?常用命令有哪些?
-
原理说明:
Redis的发布订阅(Pub/Sub)是一种消息通信模式,包含发布者(Publish)和订阅者(Subscribe):- 订阅者通过订阅频道(Channel)接收消息,发布者向频道发送消息。
- Redis作为中介,将发布者的消息实时推送给所有订阅该频道的客户端。
- 消息不持久化,若订阅者离线,期间的消息会丢失。
-
常用命令:
# 订阅频道 SUBSCRIBE channel1 channel2 # 订阅channel1和channel2# 发布消息 PUBLISH channel1 "hello" # 向channel1发送消息"hello"# 取消订阅 UNSUBSCRIBE channel1 # 取消订阅channel1# 订阅模式(通配符匹配) PSUBSCRIBE "news:*" # 订阅所有以"news:"开头的频道
97. Redis主从复制过程中,从节点宕机重启后如何恢复数据?
-
恢复流程:
从节点宕机重启后,会自动重新连接主节点并同步数据,具体步骤:- 重连主节点:从节点读取配置中的
masterhost
和masterport
,重新建立连接。 - 同步策略选择:
- 若从节点宕机前已有
replid
和offset
(复制偏移量),主节点会检查是否存在对应的备份日志(如RDB或部分AOF),若存在则执行部分重同步(仅传输宕机期间的增量数据)。 - 若主节点无对应的日志(如主节点重启过),则执行全量重同步:主节点生成RDB文件发送给从节点,从节点加载RDB后,再同步后续增量数据。
- 若从节点宕机前已有
- 重连主节点:从节点读取配置中的
-
注意:
开启主节点的AOF或RDB持久化,确保数据可恢复;从节点配置replica-replica-offline-behavior
控制重连期间的行为(如拒绝写入)。
98. Redis的AOF文件过大时,除了自动重写,还可以手动触发重写吗?如何操作?
-
手动触发方法:
可以手动触发AOF重写,通过BGREWRITEAOF
命令:# 后台执行AOF重写,不阻塞Redis服务 BGREWRITEAOF
-
原理:
重写过程中,Redis会创建一个新的AOF文件,仅包含当前数据库状态的最小命令集(去除冗余命令),完成后替换旧文件。手动触发适用于自动重写条件未满足(如auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
未达标)但文件已过大的场景。
99. Redis的SDS(简单动态字符串)与C语言字符串相比,优势在哪里?
- SDS的优势:
Redis使用SDS作为字符串的底层实现,相比C语言字符串(以\0
结尾的字符数组),优势包括:- 长度获取O(1):SDS通过
len
属性记录长度,无需遍历字符数组。 - 杜绝缓冲区溢出:修改字符串时,SDS会先检查空间是否足够,不足则自动扩容。
- 减少内存重分配:通过预分配(增长时多分配空间)和惰性释放(缩短时不立即回收空间)优化性能。
- 二进制安全:SDS不依赖
\0
判断结束,可存储图片、视频等二进制数据。 - 兼容部分C函数:SDS末尾仍保留
\0
,可复用部分C语言字符串函数。
- 长度获取O(1):SDS通过
100. Redis在高并发场景下,如何保证数据的一致性和准确性?
- 关键措施:
- 使用事务:通过
MULTI
、EXEC
包裹命令,确保批量操作的原子性(要么全执行,要么全不执行)。 - 分布式锁:用
SET key value NX PX
实现分布式锁,避免并发修改冲突。 - 乐观锁:基于
WATCH
命令监控键,若键被修改则事务取消,适合读多写少场景。 - 缓存更新策略:
- 写操作:先更新数据库,再删除缓存(避免缓存脏数据)。
- 读操作:缓存未命中时,加锁防止缓存击穿,再回源数据库更新缓存。
- 主从同步:开启
repl-diskless-sync
减少同步延迟,确保从节点数据准确性。 - 避免bigkey和热key:减少操作阻塞和竞争,提升并发处理稳定性。
- 持久化配置:合理配置AOF(
appendfsync everysec
)和RDB,避免数据丢失。
- 使用事务:通过
二、100道面试题目录列表
文章序号 | Redis面试题100道 |
---|---|
1 | Redis面试题及详细答案100道(01-15) |
2 | Redis面试题及详细答案100道(16-32) |
3 | Redis面试题及详细答案100道(33-48) |
4 | Redis面试题及详细答案100道(49-60) |
5 | Redis面试题及详细答案100道(61-70) |
6 | Redis面试题及详细答案100道(71-85) |
7 | Redis面试题及详细答案100道(86-100) |