> 技术文档 > 常见 Redis 面试题_redis面试题

常见 Redis 面试题_redis面试题


1. 基础概念与数据类型

1.1 Redis 支持哪些数据类型?还有哪些“其他”数据结构?

典型问题:

Redis 数据类型有哪几种?除了常见的 String、List、Set、ZSet、Hash 之外,还有哪些数据结构?

回答思路:

  • 列举五大基础类型:

    1. String

    2. List

    3. Set

    4. Hash

    5. ZSet(Sorted Set)

  • 补充其他内置/特殊结构:

    • Bitmaps:用 String 底层位图实现,常做统计(签到、布隆过滤器)。

    • HyperLogLog:基于概率算法的基数估算,仅需 12KB 存储即能统计海量元素的基数。

    • Streams(自 Redis 5 以来):日志型、消息队列式的数据结构,支持消费者组(Consumer Group)。

    • Geospatial(地理位置):基于 Sorted Set,存储经纬度并提供距离计算、附近搜索等。

    • Pub/Sub:虽不算“存储类型”,但 Redis 提供内置发布/订阅消息机制。

    • 模块扩展:如 RedisJSON、RedisGraph、RedisTimeSeries 等,如果考官提到可以说明知道 Redis 模块化生态。

要点提示:

  • 五大类型区别:

    • String:二进制安全,最大 512MB。

    • List:链表或 ziplist(小规模时),双端队列,可用做消息队列。

    • Set:无序集合,底层实现为哈希表,可做交并差等集合运算。

    • Hash:字段-值对集合,底层是 ziplist 或 hashtable,适合存储对象。

    • ZSet:带排序分数的集合,底层可为 skiplist+hashmap。

  • “其他”类型通常基于这几种底层结构衍生,面试中若问到“Redis 除了 5 种常见类型,还有哪些?”可提到 Bitmaps、HyperLogLog、Streams、Geo。


1.2 String 类型的底层数据结构

典型问题:

String 类型底层数据结构是什么?

回答思路:

  • 早期(Redis < 3.2)SDS(Simple Dynamic String)。

    • SDS 是 Redis 对 C 语言 char * 的封装,记录字符串长度 len、空闲空间 free,并以 \'\\0\' 结尾,避免了多次 strlen

    • SDS 结构示例:

      struct sdshdr {    int len;        // 已用长度    int free;       // 空闲剩余空间    char buf[];     // 字符数组,紧跟在结构体后};
    • 优势:追加操作 O(1)(有预留空间时),二进制安全,避免缓冲区溢出。

  • Redis 3.2 之后SDS 变为多种 header 类型,根据字符串长度自动选用,例如 sds16sds32sds64 等。

    • 小字符串(< 2^8)用 8 位 len;更大的则用 16/32/64 位长度字段。

    • 这保证了内存占用更紧凑,同时依然保留动态扩容能力。

要点提示:

  • 面试中只要提到“SDS”,并说明它保存了 lenfree、以 \'\\0\' 结尾,就足够得分。

  • 若深入追问不同版本的 header,可简单提到从 sds.h 中可以看到 SDS_HDR_VAR 宏动态配置 header 长度。


2. 持久化与 AOF/RDB 区别

2.1 Redis 的持久化方式有哪些?默认使用哪种?

典型问题:

Redis 持久化方式是什么?默认的是 RDB 还是 AOF?

回答思路:

  • RDB(快照持久化)

    • 定时将内存中的数据写成快照(dump.rdb),触发条件由 save 配置决定。

    • 触发时 Redis 主进程 fork 出子进程,子进程进行写盘,主进程继续提供服务。

    • 优势:文件紧凑,加载速度快;劣势:可能丢失最后一次快照之后的写操作(数据丢失窗口)。

  • AOF(Append-Only File,追加写日志)

    • 每当有写命令(SETLPUSH 等)时以 Redis 协议格式追加到 appendonly.aof 文件。

    • 同步策略由 appendfsync 决定:

      • always:每条命令写盘时 fsync(最安全,最慢)。

      • everysec:每秒 fsync 一次(折中,默认)。

      • no:由操作系统决定何时落盘(最快,但可能丢失几秒数据)。

    • 优势:持久性最强,可接近 0 丢失;劣势:文件膨胀大、重写过程占资源。

  • 默认方式

    • Redis 默认开启 RDB,AOF 默认关闭。若需要 AOF,可手动在配置文件中开启 appendonly yes

要点提示:

  • 面试官如果继续追问“RDB 写盘会阻塞吗?”,答“RDB 是写在子进程,主进程继续服务,只有少许 fork 延迟”。

  • 如果问“AOF 过期键是否立即写入?”,指出是写命令到 AOF,不是过期事件本身。


3. 主从复制与高可用

3.1 Redis 主从复制原理

典型问题:

Redis 集群主从复制是怎么做的?

回答思路:

  • 全量复制 + 增量同步(基于 PSYNC 命令):

    1. 初次复制或断线重连时

      • 节点发送 PSYNC ? -1 或者 PSYNC

      • 主节点如果无法满足增量复制条件,就触发全量复制,生成 RDB 快照并发送给从节点,从节点加载后进入同步状态。

    2. 全量复制完成后:主节点会将自己的写命令不断记录到缓冲区(replication backlog),并异步发送给从节点;从节点接收写命令并执行,实现增量同步

    3. 断线恢复:如果从节点断线后重连,且主节点 backlog 里仍保留它最后的 offset,对应增量同步就可继续,否则再走全量同步。

  • 复制流程关键点

    • replication backlog:一个循环 buffer,保存最近几 MB 的写命令。

    • 从节点与主节点维护一个 replication offset,用于 PSYNC 判断是否能增量同步。

要点提示:

  • 重点强调 全量 + PSYNC,以及怎样判断“增量可用/不可用”。

  • 如果问到“主节点如何知道哪些写命令发给哪些从节点?”,可提“主节点为每个从节点开启一个专属输出缓存(output buffer)”,通过 replication backlog 复制。


3.2 Redis 如何保证高可用?(哨兵与集群)

典型问题:

Redis 如何保证高可用性?除了 AOF 和 RDB 之外,比如哨兵模式、集群模式是如何保证高可用的?如果集群挂了,业务如何尽快恢复?

回答思路:

  • 单机 + 备份(主从复制)仅能读可用,真正故障自动化切换需要Sentinel(哨兵)

  • 哨兵模式(Sentinel)

    1. Sentinel 监控:多台 Sentinel 相互感知,一旦检测到主节点下线,启动投票。

    2. 自动故障转移:超过半数 Sentinel 判定主不可用后,选举新主从节点中最优节点进行升级,然后通知其他从节点改为该新主。

    3. 客户端感知:客户端通过哨兵获取当前主节点地址,实现自动重连。

  • 集群模式(Cluster)

    1. 数据分片:将 16384 个 slot 分布到各个主节点上。

    2. 每个主节点配 1+ 个从节点,一旦主节点故障,从节点接替;其他从节点重新分配备份。

    3. 节点之间 Gossip 协议:互相传播健康信息。

    4. 故障状态判定:当超过 50% 的主节点都认为主不可用,集群进入无法写状态;写保护机制(only-read questionable)。

    5. 自动切换:当一个主节点不可用时,集群在其分片的从节点集群内选举新的主。

  • 业务恢复策略

    1. 快速切换:客户端应使用 Redis 客户端库的内置 Sentinel/Cluster 支持,自动感知主变更。

    2. 双机房/多机房:若跨机房部署,则使用最合适的复制延迟容忍策略,或者用 Proxy+多活方案。

    3. 备用集群:若整个集群挂掉,可切到冷备集群或读取主库快照。

要点提示:

  • 答案要点在于哨兵投票原理和Cluster slot 分片与自动故障转移

  • 补充“哨兵模式只是管理主从切换,集群模式则是原生分片+高可用一体化方案”。


4. 过期策略与内存淘汰

4.1 如何给 Key 设置过期时间?过期策略是怎样触发回收的?

典型问题:

Redis 是怎样设置过期时间的?如果不明确设置过期时间,key 会怎样?如果内存没满只过期了,Redis 怎么回收内存?

回答思路:

  • 设置过期时间

    • EXPIRE key seconds:为 key 设置生存时间(秒)。

    • PEXPIRE key milliseconds:设置毫秒级过期。

    • EXPIREAT key timestamp/PEXPIREAT:设置到某个时间戳过期。

    • 在创建时直接设置 TTL:SET key value EX seconds PX milliseconds NX|XX

  • 过期回收方式

    1. 惰性删除:当客户端访问 key 时,检查 TTL:若已过期就删除并返回不存在。

    2. 定期删除:每隔 100ms,随机抽样一批带 TTL 的 key(默认 20 个),检查并删除过期的。若比例过多(> 25% 过期),则缩短下一次定期删除的间隔,直到达到目标。

    3. 内存淘汰:只有当 Redis 内存使用接近 maxmemory 时,才根据配置的淘汰策略移除 key(即使没到 TTL,也会被删除)。

  • 不设置过期

    • 默认 key 永不过期,除非显式调用 EXPIRE

要点提示:

  • 面试时重点说出“三种回收模型”(惰性、定期、主动淘汰)以及定期删除时的动态调整策略。

  • 如果考官继续追“定期删除如何避免一次性消耗过多 CPU?”,答“Redis 限制每次只随机检查 20 个 key,并在过期比率高时重复短期快速执行,保证回收效率与性能平衡”。


4.2 内存淘汰策略与 LRU 实现

典型问题:

Redis 缓存淘汰策略有哪些?LRU 算法具体怎样删除“冷数据”?

回答思路:

  • 常见淘汰策略maxmemory-policy):

    1. volatile-lru:只对设了 TTL 的 key,用 LRU 算法淘汰。

    2. volatile-lfu:只淘汰带 TTL 的 key,用 LFU(最不常用)。

    3. volatile-ttl:优先淘汰最近要过期的 key。

    4. volatile-random:从带 TTL 的 key 随机淘汰。

    5. allkeys-lru:对所有 key,用 LRU 淘汰。

    6. allkeys-lfu:对所有 key,用 LFU 淘汰。

    7. allkeys-random:对所有 key 随机淘汰。

    8. noeviction:达到内存上限后,后续写操作返回错误。

  • LRU 实现细节

    • 经典 LRU 要求链表记录访问顺序,开销大。Redis 采用 近似 LRU随机抽样 + 访问计数/更新 方式:

      1. 当需要淘汰时,随机从数据集中(如所有 key 或带 TTL 的 key)抽取 N(默认为 5)个样本。

      2. 计算这批样本中最旧的 key,淘汰它。

      3. 这样既近似 LRU,又避免了链表维护的高昂开销。

    • LFU(Redis 4.0+)同理,用计数器加随机淘汰近似实现频率最低优先淘汰。

要点提示:

  • 面试可重点提“Redis 的 LRU 只是近似,随机抽样+淘汰最旧的样本”。

  • 如果进一步问“为何不直接用链表实现精确 LRU?”,可说“内存成本高、性能开销大,不适合高并发场景”。


5. 缓存策略与常见问题

5.1 缓存雪崩

典型问题:

如何防止 Redis 出现缓存雪崩?

回答思路:

  • 缓存雪崩含义

    • 指大量 key 在同一时间过期,当后端 DB 瞬时压力增大,造成系统崩溃。

  • 常见解决办法:

    1. TTL 随机化:为各个缓存 key 设置一个随机的过期时间偏移量(如 TTL = 10min ± 0~5min),避免集中同时过期。

    2. 热点 key 永不过期:对于必须稳定命中的热 key,可不设置过期,或在访问时动态刷新过期。

    3. 对缓存失效做降级处理:当检测到后端压力高时,可临时返回旧数据、限流或熔断。

    4. 多级缓存/本地缓存:Redis 缓存失效时,先从本地缓存(如 Guava)取,减轻瞬时压力。

    5. 预热缓存:应用启动或发生批量刷新时,提前加载常用 key。

    6. 限流熔断:使用限流/熔断框架(如 Sentinel、Resilience4j),保护后端。

要点提示:

  • 重点讲“随机化 TTL”“限制集中失效”和“热 key 永不过期或提前刷新的策略”。

  • 如果问“缓存穿透与雪崩区别是什么?”,可快速区分:穿透是查询不存在的 key;雪崩是大量 key 同时失效。


5.2 缓存穿透

典型问题:

如何防止缓存穿透?

回答思路:

  • 缓存穿透含义

    • 指客户端频繁查询不存在的 key,每次都穿过 Redis 直接打到 DB,使后端压力过大。

  • 常见解决办法:

    1. 布隆过滤器(Bloom Filter):提前将所有合法 key 记录到布隆过滤器,只有通过过滤器检查的 key 才查询缓存/DB,否则直接返回空。

    2. 缓存空对象/Null 值:当 DB 查询到 null 时,将空值(或特殊标志)写入缓存(TTL 设短,如 60 秒),防止再次穿透。

    3. 校验参数合法性:在上层对 userId、产品 ID 等参数做严格校验,阻止恶意 / 异常请求。

    4. 请求限流:对同一黑客 IP 或相同 key 的请求限速,防止恶意爆破。

要点提示:

  • 面试可重点强调“使用布隆过滤器” 和 “缓存空对象”的结合,使得不存在的数据不会反复打到 DB。


5.3 热点 Key(热 key)与高并发

典型问题:

Redis 热点 key 怎么解决?如何保证热点 key 的命中率?

回答思路:

  • 热点 key 问题

    • 单个 key 被大量并发访问,会导致该 key 的对应命令过度落在同一个 CPU 或同一个实例上,引发单点瓶颈。

  • 常见解决办法:

    1. 本地缓存 + 双写/双删:将热点数据缓存在应用进程(如 Guava、Caffeine),同时异步刷新/双删。

    2. 读写分离(多副本):针对热点 key,建立多个读副本(读实例或只读主从),让不同客户端读不同副本。

    3. 缓存分片:将单一 key 拆分为多个热点子 key,如 hotKey:1hotKey:2 …,取模到不同 Redis 实例。

    4. 使用 Redis Cluster 分片:Cluster 会根据 hash slot 将 key 分散到不同节点,天然分散并发。

    5. Geo/Sorted Set 分散:若查询模式可分散,则设计索引,减少集中访问。

    6. 热点补偿策略:若热点 key 突然超高并发,先限流或熔断(如请求 Queue 排队、返回降级缓存)。

要点提示:

  • 面试时最好举“电商秒杀”场景:将商品库存拆分为多份缓存,或使用“预减库存 + 异步补偿”模式,避免单点刷爆。

  • 还可以补充“使用 Lua 脚本保证原子操作 + 限流”来保护热点。


6. 锁与分布式锁

6.1 Redis 实现分布式锁的常见方式

典型问题:

Redis 做分布式锁应该注意哪些?如何实现加锁、解锁,如何续期?如果锁超时了怎么办?

回答思路:

  • 最简单的实现

    1. SETNXSET resource_name token NX PX 30000

      • NX 参数:只有当 key 不存在时才设置,保证原子性。

      • PX 设置过期时间,防止死锁。

    2. 解锁:使用 Lua 脚本检查 token 是否与自己的一致,若相同才 DEL key,以保证解锁安全性。 

      if redis.call(\"get\", KEYS[1]) == ARGV[1] then return redis.call(\"del\", KEYS[1])else return 0end
  • 续期

    • 如果业务执行时间超过了锁的过期时间,需要在锁快过期前,由持有锁者定时调用 Lua 脚本判断并重新设置过期时间

    • 或者使用 Redisson 等客户端库,它内置了“看门狗”机制,自动续期。

  • 注意事项

    1. 锁的唯一标识:使用 UUID 等作为 token,确保不同客户端不会误解锁。

    2. 过期时间设置:要大于业务执行时间,边界情况可用“看门狗”或单独线程续期。

    3. 解锁安全性:必须在脚本中判断 token 再删除,否则可能删了他人锁。

    4. 防止死锁:即使客户端崩溃,过期时间保证最终能释放锁。

  • Redlock 算法(选答亮点):

    • 基于五台独立 Redis 实例,以多数节点加锁成功为准,保证跨机房高不可用时仍能获取到锁。

    • 如果多个节点加锁耗时过长,会自动回退已加锁的节点。

要点提示:

  • 面试可提到“单点 Redis 出问题的风险”,补充 Redlock 工作原理。

  • 续期一定要说明“在业务执行前要计算剩余 TTL,多次调用脚本延长”,否则容易死锁。


7. 高并发与性能优化

7.1 Redis 是单线程还是多线程?为什么能高并发?

典型问题:

Redis 是单线程还是多线程?为什么使用单线程也能做到高并发?

回答思路:

  • 核心执行模型

    • 自 Redis 采用 IO 多路复用 + 单线程事件驱动,主线程负责所有客户端连接的网络 I/O 和命令处理。

    • 内存操作速度远高于磁盘 I/O,加上无锁设计,单线程执行也能达到极高的 QPS。

  • 多线程部分(Redis 6+):

    • I/O 线程:可选开启 io-threads,让主线程专注于命令执行,其他线程负责网络读写,缓解多 CPU 核心的网络收发瓶颈。

    • 异步删除大对象:后台线程异步删除大键值对象,避免在主线程做阻塞操作。

    • AOF 重写和 RDB 子进程 本身在子进程或后台线程执行,不阻塞主线程命令处理。

  • 高并发的基础

    1. 所有数据驻留内存,对比传统数据库无磁盘随机读写开销。

    2. 零拷贝网络、高效的协议解析(RESP)。

    3. 单线程避免锁竞争、减少上下文切换。

要点提示:

  • 面试可提及“Redis 6 中 I/O 线程只在网络收发,命令执行仍在主线程”,表现出对细节的掌握。


7.2 多路复用(IO Multiplexing)原理

典型问题:

Redis 多路复用为何可以提高查询速度?多路复用是什么原理?

回答思路:

  • 多路复用模型:Redis 使用 epoll(Linux)、kqueue(macOS)或 select 来实现 IO 多路复用。

  • 工作原理

    1. 主线程调用 epoll_wait,等待多个客户端套接字 FD 上的读写事件。

    2. 当某个连接有数据可读时,epoll_wait 返回,就在同一个线程中读取数据并解析命令。

    3. 不需要为每个连接创建一个线程,大大减少了线程切换和资源占用。

  • 提高并发能力

    • 即使成千上万个连接处于空闲状态,epoll 也能高效地管理,仅在真正有数据就绪时才调用回调。

    • 避免了大规模线程/进程上下文切换成本。

要点提示:

  • 面试可补充“Linux 下 epoll 支持边沿触发(edge-triggered)和水平触发(level-triggered)模式”,Redis 默认使用水平触发。


8. 哨兵模式与集群模式

8.1 哨兵模式(Sentinel)

典型问题:

Redis 哨兵模式是怎么配的?哨兵模式如何保证高可用?

回答思路:

  • 配置要点示例sentinel.conf):

    sentinel monitor mymaster 127.0.0.1 6379 2sentinel down-after-milliseconds mymaster 5000sentinel failover-timeout mymaster 10000sentinel parallel-syncs mymaster 1
    • monitor :监控名称为 mymaster 的主节点,至少 2 个 Sentinel 同意才判定主不可用。

    • down-after-milliseconds:节点在毫秒级别内无应答,就认为下线。

    • failover-timeout:故障转移超时时间。

    • parallel-syncs:故障转移时并行同步的从节点个数。

  • 故障转移流程

    1. 主观下线:Sentinel 通过 PING/PONG 检测,若 5000ms 内无响应,就标记为主观下线(Subjectively Down)。

    2. 客观下线:若多数 Sentinel 都认为主不可用,则标记为客观下线(Objectively Down)。

    3. 选举新的主节点:在从节点中选一个同步进度最新、优先级高的,从节点晋升为主。

    4. 重配置:其他从节点指向新主,从新主处同步数据,旧主恢复后自动成为从节点。

    5. 通知客户端:Sentinel 会推送变更消息给订阅的客户端(如 Lettuce、Jedis),客户端自动切换。

要点提示:

  • 面试要点在于“Sentinel 之间通过 Gossip 协议相互通信,共同做投票选举”。

  • 若问“如何避免脑裂”,可答“超过半数 Sentinel 判断才触发故障转移”;“Sentinel 本身的高可用”可用 3+ 个 Sentinel 部署。


8.2 集群模式(Cluster)

典型问题:

Redis 集群模式是如何保证高可用的?如果主库挂了,数据会同步到从库吗?集群挂了业务怎么办?

回答思路:

  • 架构概览

    • 一般采用至少 6 个节点:3 主 3 从,分别负责 16384 个 slot。

    • 每个主节点负责一段 slot(槽)范围,读写请求 Hash 到对应 slot。

    • 每个主节点至少有一个从节点,当主节点挂掉时,从节点接管该 slot。

  • 高可用保证

    1. 复制机制:主节点将写命令同步到其从节点。

    2. 故障检测:Cluster 节点彼此通过 Gossip 协议检测健康状态。

    3. 故障转移:某主节点被多数节点判定为“下线”,集群从该主的从节点中投票选出新的主。

    4. 故障恢复:原主恢复后作为从节点回归并与新主同步。

  • 业务影响 & 快速恢复

    1. 读写请求路由:客户端在收到 -MOVED 重定向后,会更新本地槽位缓存并重试。

    2. 减少跨机房延迟:设计分片策略时可将主从分布在同一机房或不同机房,权衡网络分区影响。

    3. 熔断降级:业务可检测集群状态,如集群失效则回退到 DB 或二级缓存。

    4. 备份 & 快照:即使整个集群不可用,可用备份节点或 RDB 快照恢复。

要点提示:

  • 面试可补充“slot rebalancing”“resharding”时如何保证数据迁移中一致性。


9. 批量操作与管道(Pipeline)

典型问题:

Redis 如何批量保存数据?批量读取数据?MGETPipeline 的区别是什么?

回答思路:

  • 批量保存

    • 使用 MSET key1 val1 key2 val2 …,但注意 MSET 不是原子性的事务(其实在底层命令序列化时会一次性写入多个 key,性能较好)。

    • 对于更复杂的批量逻辑,可用 Pipeline:将多条 SET 命令打包后一次性发送给 Redis,减少网络往返。

  • 批量读取

    • MGET key1 key2 key3 …:一次性获取多个 key 的值。

    • Pipeline:逐条 GET 命令打包,Redis 端串行执行然后打包返回。

  • 区别对比

    1. MGET/MSET:在服务器端一次性解析并执行多个 key 操作,速度很快,但如果需要中间对每条命令做业务判断,就不灵活。

    2. Pipeline:客户端打包 N 条命令后一次性发送,服务器依次串行执行并将 N 条回复打成一个包回传。主要减少网络往返(RTT)

    3. 事务(MULTI/EXEC)+ Pipeline:若需要原子性,可在 Pipeline 中加入 MULTI; …; EXEC,确保原子执行,但会加锁。

要点提示:

  • 面试若再追问“性能瓶颈在哪?”可答“网络延迟、序列化反序列化、服务器执行”三部分,Pipeline 主要缓解第一部分。

 10.使用分布式锁注意事项

关注点 说明及最佳实践 锁的粒度 锁的范围要尽量小,避免锁过大导致系统吞吐量下降或死锁风险。 锁的超时机制 必须设置合理的锁过期时间,防止持锁线程异常挂掉导致死锁。 锁的释放安全 释放锁时要确认当前持锁者身份,避免误释放其他线程持有的锁(如使用唯一标识)。 可重入性 一些业务场景需支持同线程可重入锁,分布式锁本身一般不支持重入。需额外设计。 锁的公平性 根据业务需要判断是否需要公平锁,避免饥饿现象。 高可用与锁失效 使用 Redisson 等高可用客户端,避免单点故障导致锁失效或误释放。 锁的性能开销 锁的获取、释放频率不可过高,避免因锁操作导致性能瓶颈。 锁超时续期 需要长时间操作时考虑自动续期,防止锁意外过期被其他线程抢占。 异常处理 确保异常情况下锁能被正确释放,防止死锁。 锁的实现选择 选用合适的实现方案(Redis、Zookeeper、Etcd等),根据业务需求权衡一致性和性能。

简单面试答题模板

使用分布式锁时,最关键的是保证锁的安全释放和超时释放,防止死锁和误删锁。同时需要控制锁粒度,避免影响系统吞吐。对于 Redis 分布式锁,还要考虑锁续期和锁的持有者校验。选用高可用客户端减少单点故障风险。异常路径确保释放锁,保障系统稳定运行。


附:按主题再罗列一次所有小问题及简要提示

由于问题量很大,下表仅做快速查阅,具体答案可见上文对应分类。

分类 问题 简要提示 基础 + 数据类型 Redis 数据类型有哪几种?除了五种常见,还有哪些? 五种 + Bitmaps/HyperLogLog/Streams/Geo 等 String 类型底层数据结构是什么? SDS,多种 header (sds8/sds16/sds32/sds64) 持久化 持久化方式有哪些?默认使用 RDB 还是 AOF? RDB + AOF,默认 RDB AOF 与 RDB 内部原理对比? AOF 逐条写命令、可配置 fsync;RDB fork 子进程写快照 主从复制 + HA 主从复制原理?全量 + 增量 + PSYNC replication backlog + offset Redis 如何保证高可用?哨兵模式如何配置? Sentinel 投票机制 + 故障转移 集群模式如何保证高可用?主故障怎么切换? Slot 分片 + Gossip + 从节点投票选举主 过期 + 淘汰 Redis 是怎样设置过期时间的?不设置过期会怎样?如何回收过期 key? EXPIRE / PEXPIRE / PERIODIC + LAZY + EVICTION Redis 缓存淘汰策略有哪些?LRU 如何近似实现? volatile/all keys + LRU/LFU/RANDOM/TTL/noeviction 缓存策略 缓存雪崩怎么防? 随机 TTL / 热 key 永不过期 / 降级 / 多级缓存 缓存穿透怎么防? 布隆过滤器 / 缓存空对象 / 参数校验 / 限流 Redis 热点 key 怎么解决?如何保证命中率? 本地缓存 + 多副本 / 分片 / Redis Cluster / Lua 限流 锁 + 分布式锁 Redis 分布式锁怎么实现加锁解锁?如何续期?如果锁超时怎么办? SETNX+PX + Lua 解锁脚本 + 看门狗续期或 Redisson Redlock 算法原理? 多节点投票,多节点加锁,再统一过期 高并发 + 性能优化 Redis 是单线程还是多线程?为什么高并发? 单线程 + IO 多路复用 ;Redis 6 可选 I/O 线程处理网络 多路复用原理? epoll/kqueue + 事件驱动 哨兵 + 集群模式 Sentinel 配置示例?工作流程? monitor/down-after/parallel-syncs/failover-timeout + Gossip/投票 集群模式 slot 概念?Hash slot 数据环是什么意思? 16384 个 slot,CRC16(key)%16384,数据环分片路由 批量操作 + 管道 批量保存/批量读取怎么做?MGET 与 Pipeline 区别? MGET 一次返回多个值;Pipeline 批量发送多条命令,减少 RTT 其他实用问题 如果 List 数据量很大该怎么删除? 用 LTRIM 裁剪边界(O(1)),避免 DEL 全量删除导致阻塞 如何批量删除 key? SCAN + DEL,避免 KEYS 全表扫描造成阻塞 Redis 多路复用为何能提高查询速度? 避免每个连接都创建线程,减少上下文切换 热 key 模式下如何限流? Lua 脚本计数器加限流、令牌桶算法或漏桶算法 如何保证缓存与数据库一致性?(双删策略,延迟双删) 写 DB 之后删 Redis,删 DB 之后删一次 Redis + 延迟再删一次 Redis Redis 如果发现内存满了,会如何处理? 根据 maxmemory-policy 具体淘汰策略,如 allkeys-lru/noeviction 等 如果锁的过期时间要超过业务执行时间,如何续期? 在业务端用定时任务或单独线程调用 Lua 脚本延长 TTL,或使用 Redisson

最后一点:

  • 面试时回答要有思路

    1. 定义概念(什么是 X,X 有什么作用)。

    2. 然后阐述原理(原理模型、实现思路)。

    3. 最后给出工程实践(常见配置、常用命令、注意事项、场景案例)。

  • 切忌空讲概念,一定要结合“Redis 在生产中怎样使用”来落地回答,才更能打动面试官。

祝你面试顺利,通过率飙升!

麦克风网