Skip to content

💎 Redis 面试题集合

本文档涵盖了 Redis 核心知识点,包括持久化机制、过期策略、内存淘汰、缓存问题、哨兵机制、分布式锁等面试高频考点。


📑 目录

  1. Redis 持久化机制(RDB 与 AOF)
  2. Redis 过期策略
  3. Redis 内存淘汰策略
  4. 缓存击穿、穿透、雪崩
  5. Redis 哨兵机制
  6. 数据库和缓存一致性问题
  7. Redis 分布式锁
  8. Redis 大 Key 问题

1. Redis 持久化机制(RDB 与 AOF)

1.1 为什么需要持久化?

Redis 之所以能够提供高速读写操作是因为数据存储在内存中,但这也带来了一个风险:在服务器宕机或断电的情况下,内存中的数据会丢失。为了解决这个问题,Redis 提供了持久化机制来确保数据的持久性和可靠性。

1.2 Redis 持久化机制概览

持久化方式说明
RDB (Redis Data Base)内存快照,全量备份
AOF (Append Only File)增量日志,记录写命令
混合持久化RDB + AOF 结合

1.3 RDB 持久化

1.3.1 什么是 RDB?

在指定的时间间隔内将内存中的数据集快照写入磁盘。RDB 是内存快照(内存数据的二进制序列化形式)的方式持久化,每次都是从 Redis 中生成一个快照进行数据的全量备份。

1.3.2 RDB 持久化流程

┌─────────────┐
│   主进程    │
│  继续处理   │
│ 客户端请求  │
└──────┬──────┘
       │ 1. Fork 子进程

┌─────────────┐     ┌─────────────┐
│   子进程    │────▶│  共享内存    │
│  备份数据   │     │  (COW机制)  │
└──────┬──────┘     └─────────────┘

       │ 2. 将共享内存数据
       │    写到临时 RDB 文件

┌─────────────┐
│ 临时 RDB 文件 │
└──────┬──────┘
       │ 3. 完成写入,
       │    替换旧 RDB 文件

┌─────────────┐
│   dump.rdb  │
└─────────────┘

RDB 持久化方案进行备份时,Redis 会单独 fork 一个子进程来进行持久化,会将数据写入一个临时文件中,持久化完成后替换旧的 RDB 文件。

在整个持久化过程中,主进程(为客户端提供服务的进程)不参与 IO 操作,这样能确保 Redis 服务的高性能。RDB 持久化机制适合对数据完整性要求不高但追求高效恢复的使用场景。

1.3.3 RDB 触发规则

手动触发

命令说明特点
SAVE阻塞当前 Redis 进程,直到 RDB 持久化过程完成如果内存实例较大会造成长时间阻塞,不建议使用
BGSAVERedis 主进程 fork 创建子进程,由子进程完成持久化阻塞时间很短(微秒级),推荐使用

自动触发 - 配置触发

在 Redis 安装目录下的 redis.conf 配置文件中搜索 /snapshot 即可快速定位:

conf
# 默认配置(注释状态)
# save 3600 1    # 3600 秒内有 1 个 key 被修改,触发 RDB
# save 300 100   # 300 秒内有 100 个 key 被修改,触发 RDB
# save 60 10000  # 60 秒内有 10000 个 key 被修改,触发 RDB

自动触发 - shutdown 触发

在客户端执行 SHUTDOWN 命令时会触发 RDB 持久化:

bash
# 删除已存在的 RDB 文件
rm -rf dump.rdb

# 连接 Redis
redis-cli -p 6379

# 执行 shutdown
127.0.0.1:6379> SHUTDOWN

# 退出
not connected> QUIT

# 查看目录,会重新生成 dump.rdb
ll

自动触发 - flushall 触发

执行 FLUSHALL 命令会清空 Redis 所有数据库的数据(16 个库数据都会被删除):

bash
# 删除 RDB 文件
rm -rf dump.rdb

# 连接 Redis
redis-cli -p 6379

# 查看数据量
127.0.0.1:6379> DBSIZE
(integer) 7

# 执行 FLUSHALL
127.0.0.1:6379> FLUSHALL
OK

# 退出
127.0.0.1:6379> QUIT

# 查看目录,会生成空的 dump.rdb
ll

1.3.4 RDB 优缺点

✅ 优点

  • 性能高:RDB 持久化是通过生成一个快照文件来保存数据,因此在恢复数据时速度非常快
  • 文件紧凑:RDB 文件是二进制格式的数据库文件,相对于 AOF 文件来说,文件体积较小

❌ 缺点

  • 可能丢失数据:由于 RDB 是定期生成的快照文件,如果 Redis 意外宕机,最近一次的修改可能会丢失

💡 提示:Redis 持久化默认开启为 RDB 持久化

1.4 AOF 持久化

1.4.1 什么是 AOF?

AOF 持久化需要手动修改配置文件开启。AOF 持久化方案进行备份时,客户端所有请求的写命令都会被追加到 AOF 缓冲区中,缓冲区中的数据会根据 Redis 配置文件中配置的同步策略来同步到磁盘上的 AOF 文件中。

1.4.2 AOF 持久化流程

客户端写请求 ──▶ Redis 进程 ──▶ AOF 缓冲区 ──▶ AOF 日志文件


                            AOF 日志重写(瘦身)


                            启动时读取 AOF 恢复数据

当 AOF 的文件达到重写策略配置的阈值时,Redis 会对 AOF 日志文件进行重写,给 AOF 日志文件瘦身。Redis 服务重启的时候,通过加载 AOF 日志文件来恢复数据。

1.4.3 AOF 配置

AOF 默认不开启,需要修改为 appendonly yes

conf
# 开启 AOF
appendonly yes

# 关闭 AOF+RDB 混合模式(设为 no)
aof-use-rdb-preamble no

1.4.4 AOF 同步策略

conf
# 可选值:always | everysec | no
appendfsync everysec
策略说明特点
always每次 Redis 写操作都写入 AOF 日志非常耗性能,数据最安全
everysec每秒刷新一次缓冲区中的数据到 AOF 文件默认策略,兼容性能和数据完整性的折中方案,理论上丢失数据在一秒钟左右
no交给操作系统判断何时刷新不推荐使用,丢失数据可能性大

1.4.5 AOF 修复功能

Redis 7 版本,AOF 文件存储在 appendonlydir 文件夹下:

  • base:基准文件
  • incr:追加数据

修复步骤

bash
# 1. 启动 Redis
redis-server conf/redis-config.conf

# 2. 连接 Redis 并写入数据
redis-cli -p 6379
127.0.0.1:6379> SET aa aa
OK
127.0.0.1:6379> SET bb bb
OK
127.0.0.1:6379> SET cc cc
OK

# 3. 如果 AOF 文件损坏,重启会报错
# 使用 redis-check-aof 修复
redis-check-aof --fix appendonlydir/appendonly.aof.1.incr.aof

# 4. 重新启动 Redis
redis-server conf/redis-config.conf

# 5. 验证数据
redis-cli -p 6379
127.0.0.1:6379> KEYS *

1.4.6 AOF 重写

重写其实是针对 AOF 存储的重复性冗余指令进行整理,比如有些 key 反复修改,又或者 key 反复修改后最终被删除,这些过程中的指令都是冗余且不需要存储的。

自动重写

当 AOF 日志文件达到阈值时会触发自动重写。

conf
# 当 AOF 文件体积达到上次重写之后的体积的 100% 时,会触发 AOF 重写
auto-aof-rewrite-percentage 100

# 当 AOF 文件体积超过这个阈值时,会触发 AOF 重写
auto-aof-rewrite-min-size 64mb

手动重写

bash
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started

1.4.7 AOF 优缺点

✅ 优点

  • 数据更加可靠:AOF 持久化记录了每个写命令的操作,因此在出现故障时,可以通过重新执行 AOF 文件来保证数据的完整性
  • 可以保留写命令历史:AOF 文件是一个追加日志文件,可以用于回放过去的写操作

❌ 缺点

  • 文件较大:由于记录了每个写命令,AOF 文件体积通常比 RDB 文件要大
  • 恢复速度较慢:当 AOF 文件较大时,Redis 重启时需要重新执行整个 AOF 文件,恢复速度相对较慢

1.5 混合持久化

Redis 4.0 版本开始支持混合持久化,因为 RDB 虽然加载快但是存在数据丢失,AOF 数据安全但是加载缓慢。

混合持久化通过以下配置开启(Redis 4.0 以上版本默认开启):

conf
aof-use-rdb-preamble yes

开启混合持久化之后,appendonlydir 文件夹下会同时存在一个 RDB 文件与一个 AOF 文件。

1.6 持久化方案总结

方案推荐度适用场景
RDB + AOF 混合⭐⭐⭐⭐⭐推荐两者均开启
单独 RDB⭐⭐⭐对数据不敏感的场景
单独 AOF⭐⭐不建议单独使用,因为可能会出现 Bug
都不开启纯内存缓存场景

2. Redis 过期策略

2.1 惰性删除(Lazy Expiration)

当客户端尝试访问某个键时,Redis 会先检查该键是否设置了过期时间,并判断是否过期。如果键已过期,则 Redis 会立即将其删除。

⚠️ 注意:该策略可以最大化地节省 CPU 资源,却对内存非常不友好。极端情况可能出现大量的过期 key 没有再次被访问,从而不会被清除,占用大量内存。

2.2 定期删除(Active Expiration)

Redis 会每隔一段时间(默认 100 毫秒)随机检查一部分设置了过期时间的键,通过循环遍历方式,逐个检查键是否过期,并删除已过期的键值对。

通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得 CPU 和内存资源达到最优的平衡效果。

2.3 过期策略总结

Redis 中同时使用了惰性过期和定期过期两种过期策略:

  1. 假设 Redis 当前存放 20 万个 key,并且都设置了过期时间,如果每隔 100ms 就去检查这全部的 key,CPU 负载会特别高,最后可能会挂掉
  2. 因此 Redis 采取的是定期过期,每隔 100ms 就随机抽取一定数量的 key 来检查和删除
  3. 最后可能会有很多已经过期的 key 没被删除,这时候 Redis 采用惰性删除,在获取某个 key 的时候,Redis 会检查这个 key 如果设置了过期时间并且已经过期了,此时就会删除

⚠️ 注意:如果定期删除漏掉了很多过期的 key,然后也没走惰性删除,就会有很多过期 key 积在内存中,可能会导致内存溢出。为了应对这个问题,Redis 引入了内存淘汰策略进行优化。


3. Redis 内存淘汰策略

内存淘汰策略允许 Redis 在内存资源紧张时,根据一定的策略主动删除一些键值对,以释放内存空间并保持系统的稳定性。

3.1 内存淘汰策略类型

策略说明
noeviction不淘汰策略。当内存不足以容纳新写入数据时,Redis 将新写入的命令返回错误
volatile-lru从设置了过期时间的键中选择最近最少使用的键进行删除
volatile-ttl从设置了过期时间的键中选择剩余时间最短的键进行删除
volatile-random从设置了过期时间的键中随机选择一个键进行删除
allkeys-lru所有键中选择最近最少使用的键进行删除
allkeys-random所有键中随机选择一个键进行删除

4. 缓存击穿、缓存穿透、缓存雪崩

缓存击穿、缓存雪崩和缓存穿透是日常开发与面试过程中必须掌握的常见问题。

4.1 缓存击穿(Cache Breakdown)

4.1.1 什么是缓存击穿?

缓存击穿是指在高并发访问下,一个热点数据失效时,大量请求会直接绕过缓存,直接查询数据库,导致数据库压力剧增。

通常情况下,缓存是为了减轻数据库的负载,提高读取性能而设置的。当某个特定的缓存键(key)失效后,在下一次请求该缓存时,由于缓存中没有对应的数据,因此会去数据库中查询。

4.1.2 解决方案

方案说明
合理的过期时间设置热点数据永不过期,或者设置较长的过期时间,以免频繁失效
互斥锁当缓存失效时,使用互斥锁保证只有一个线程去查询数据库并更新缓存
热点数据预加载系统启动时或定时任务预加载热点数据到缓存

4.2 缓存穿透(Cache Penetration)

4.2.1 什么是缓存穿透?

缓存穿透是指查询一个不存在的数据,由于缓存中没有该数据,每次请求都会直接查询数据库,而数据库中也没有该数据,导致每次请求都绕过缓存直接访问数据库。

4.2.2 解决方案

方案说明
布隆过滤器在缓存之前加一层布隆过滤器,快速判断 key 是否存在
缓存空值将不存在的数据也缓存起来,设置较短的过期时间
参数校验对用户输入进行合法性校验,过滤无效请求

4.3 缓存雪崩(Cache Avalanche)

4.3.1 什么是缓存雪崩?

缓存雪崩是指在某一个时间段,缓存集中过期失效,或者 Redis 宕机,导致所有请求都直接访问数据库,数据库压力瞬间增大,甚至宕机。

4.3.2 解决方案

方案说明
过期时间加随机值在设置缓存过期时间时,加上一个随机值,避免大量 key 同时过期
多级缓存使用本地缓存 + Redis 缓存的多级架构
Redis 高可用使用 Redis 哨兵或集群模式,保证 Redis 服务的高可用
熔断降级当数据库压力过大时,进行熔断降级,保护数据库

4.4 三者对比

问题原因特点
缓存击穿热点 key 过期单个热点数据
缓存穿透查询不存在的数据数据库也没有该数据
缓存雪崩大量 key 同时过期 / Redis 宕机大面积缓存失效

5. Redis 哨兵机制

5.1 为什么需要哨兵机制?

Redis 的主从复制主要用于实现数据的冗余备份和读分担,并不是为了提供高可用性。因此在系统高可用方面,单纯的主从架构无法很好地保证整个系统高可用:

  • 需要人工介入:当主节点发生故障时,主从复制无法自动进行主节点的切换,需要管理员手动干预
  • 主节点写能力有限:所有写操作都必须发送给主节点处理,主节点成为写入瓶颈
  • 单机节点存储能力有限:所有数据都存储在主节点上,存储容量受限

因此通常使用 Redis 哨兵机制Redis 集群模式来提高整个系统的可用性、扩展性和负载均衡能力。

5.2 哨兵机制(Sentinel)原理

Redis 哨兵机制是通过在独立的哨兵节点上运行特定的哨兵进程来实现的。这些哨兵进程监控主从节点的状态,并在发现故障时自动完成故障发现和转移。

        ┌─────────────┐
        │  哨兵集群    │
        │  Sentinel   │
        └──────┬──────┘
               │ 监控
       ┌───────┴───────┐
       ▼               ▼
┌─────────────┐  ┌─────────────┐
│   Master    │  │   Slave     │
│   主节点     │  │   从节点     │
└─────────────┘  └─────────────┘


┌─────────────┐
│   Slave     │
│   从节点     │
└─────────────┘

5.3 哨兵选举

在启动时,每个哨兵节点会执行选举过程,其中一个哨兵节点被选为领导者(leader),负责协调其他哨兵节点。

选举过程

  1. 每个在线的哨兵节点都可以成为领导者,每个哨兵节点会向其它哨兵发 is-master-down-by-addr 命令,征求判断并要求将自己设置为领导者
  2. 当其它哨兵收到此命令时,可以同意或者拒绝它成为领导者
  3. 如果哨兵发现自己在选举的票数大于等于 num(sentinels)/2+1 时,将成为领导者

5.4 故障转移

一旦主节点被判定为不可用,哨兵节点会执行故障转移操作:

  1. 发现故障:Sentinel 节点定期监控发现主节点是否出现了故障,sentinel 会向 master 发送心跳 PING 来确认 master 是否存活
  2. 选择新主节点
    • 过滤掉不健康的(下线或断线),没有回复过哨兵 ping 响应的从节点
    • 选择从节点优先级最高
    • 选择复制偏移量最大的从节点(复制最完整的)
  3. 切换主节点:将选中的从节点提升为新的主节点,并将其他从节点切换到新的主节点
  4. 通知客户端:哨兵节点会通知客户端新的主节点的位置

5.5 客观下线

当主观下线的节点是主节点时,该哨兵节点会通过指令 sentinel is-master-down-by-addr 寻求其它哨兵节点对主节点的判断,当超过 quorum(选举)个数,此时哨兵节点则认为该主节点确实有问题,这样就客观下线了。

5.6 哨兵机制总结

Redis 哨兵的作用:

  • 监控主数据库和从数据库是否正常运行
  • 主数据库出现故障时,可以自动将从数据库转换为主数据库,实现自动切换

6. 数据库和缓存一致性问题

6.1 问题来源

使用 Redis 做一个缓冲操作,让请求先访问到 Redis,而不是直接访问 MySQL 等数据库:

客户端 ──▶ Redis 缓存 ──▶ MySQL 数据库


           读取缓存

读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MySQL)间的数据一致性问题。

不管是先写 MySQL 数据库,再删除 Redis 缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。

6.2 问题示例

方案问题
先更新 MySQL,再更新 Redis如果更新 Redis 失败,可能仍然不一致
先删除 Redis 缓存,再更新 MySQL高并发下性能较低,仍然会出现数据不一致的问题

6.3 解决方案

6.3.1 延时双删

先删除 Redis 缓存数据,再更新 MySQL,延迟几百毫秒再删除 Redis 缓存数据,这样就算在更新 MySQL 时,有其他线程读了 MySQL,把老数据读到了 Redis 中,那么也会被删除掉,从而把数据保持一致。

删除缓存 ──▶ 更新数据库 ──▶ 延迟几百毫秒 ──▶ 再次删除缓存

6.3.2 队列 + 重试机制

1. 更新数据库数据
2. 缓存因为种种问题删除失败
3. 将需要删除的 key 发送至消息队列(MQ)
4. 自己消费消息,获得需要删除的 key
5. 继续重试删除操作,直到成功

缺陷:对业务线代码造成大量的侵入。

6.3.3 异步更新缓存(基于订阅 binlog 的同步机制)

MySQL ──▶ 写入 Binlog ──▶ 订阅 Binlog 程序 ──▶ MQ ──▶ Redis 更新

MySQL 中产生了新的写入、更新、删除等操作,就可以把 binlog 相关的消息推送至 Redis,Redis 再根据 binlog 中的记录,对 Redis 进行更新。

实际应用:使用阿里的开源框架 Canal,通过该框架可以对 MySQL 的 binlog 进行订阅,而 Canal 正是模仿了 MySQL 的 slave 数据库的备份请求,使得 Redis 的数据更新达到了相同的效果。


7. Redis 实现分布式锁的 6 种方案

7.1 什么是分布式锁?

分布式锁是一种机制,用于确保在分布式系统中,多个节点在同一时刻只能有一个节点对共享资源进行操作。

分布式锁的特征

特征说明
互斥性任意时刻,只有一个客户端能持有锁
锁超时释放持有锁超时,可以释放,防止不必要的资源浪费,也可以防止死锁
可重入性一个线程如果获取了锁之后,可以再次对其请求加锁
高性能和高可用加锁和解锁需要开销尽可能低,同时也要保证高可用
安全性锁只能被持有的客户端删除,不能被其他客户端删除

7.2 方案一:SETNX + EXPIRE

提到 Redis 的分布式锁,很多小伙伴马上就会想到 setnx + expire 命令。即先用 setnx 来抢锁,如果抢到之后,再用 expire 给锁设置一个过期时间,防止锁忘记了释放。

bash
SETNX key value    # 如果 key 不存在,则设置成功返回 1;如果 key 已存在,返回 0
EXPIRE key 30      # 设置 30 秒过期时间

❌ 缺陷:加锁与设置过期时间是非原子操作,如果加锁后未来得及设置过期时间系统异常等,会导致其他线程永远获取不到锁。

7.3 方案二:SETNX + Value 值(系统时间+过期时间)

为了解决方案一「发生异常锁得不到释放的场景」,可以把过期时间放到 setnx 的 value 值里面:

value = 当前系统时间 + 过期时间

❌ 缺点

  • 过期时间是客户端自己生成的,必须要求分布式环境下,每个客户端的时间必须同步
  • 如果锁过期的时候,并发多个客户端同时请求过来,都执行 jedis.getSet(),最终只能有一个客户端加锁成功,但是该客户端锁的过期时间,可能被别的客户端覆盖
  • 该锁没有保存持有者的唯一标识,可能被别的客户端释放/解锁

7.4 方案三:使用 Lua 脚本(包含 SETNX + EXPIRE 两条指令)

使用 Lua 脚本来保证原子性(包含 setnxexpire 两条指令):

lua
if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then
    redis.call('expire', KEYS[1], ARGV[2])
    return 1
else
    return 0
end

7.5 方案四:SET 的扩展命令(SET EX PX NX)

巧用 Redis 的 SET 指令扩展参数:SET key value [EX seconds] [PX milliseconds] [NX|XX]

参数说明
NX仅当 key 不存在时,才能 set 成功
EX seconds设定 key 的过期时间,时间单位是秒
PX milliseconds设定 key 的过期时间,单位为毫秒
XX仅当 key 存在时设置值
bash
SET key value EX 30 NX

❌ 可能存在的问题

  1. 锁过期释放了,业务还没执行完:假设线程 A 获取锁成功,一直在执行临界区的代码,但是锁过期了,此时线程 B 又请求过来获得锁
  2. 锁被别的线程误删:假设线程 A 执行完后去释放锁,但它不知道当前的锁可能是线程 B 持有的

解决方案:给 value 值设置一个标记当前线程唯一的随机数,在删除的时候校验:

lua
-- 加锁
SET resource_name my_random_value NX PX 30000

-- 解锁(使用 Lua 脚本保证原子性)
if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end

7.6 方案五:Redisson 框架

方案四还是可能存在「锁过期释放,业务没执行完」的问题。

Redisson 解决了这个问题:

┌─────────────┐
│   线程 A    │
│  加锁 LOCK  │
└──────┬──────┘


┌─────────────┐     ┌─────────────┐
│  Redisson   │────▶│    Redis    │
│  看门狗线程  │     │   (Master)  │
│ 每10秒检查  │     └─────────────┘
│ 延长锁时间  │
└─────────────┘

只要线程一加锁成功,就会启动一个 watch dog 看门狗,它是一个后台线程,会每隔 10 秒检查一下,如果线程 1 还持有锁,那么就会不断的延长锁 key 的生存时间。

7.7 方案六:多机实现的分布式锁 Redlock + Redisson

如果线程一在 Redis 的 master 节点上拿到了锁,但是加锁的 key 还没同步到 slave 节点。恰好这时,master 节点发生故障,一个 slave 节点就会升级为 master 节点。线程二就可以获取同个 key 的锁了,但线程一也已经拿到锁了,锁的安全性就没了。

为了解决这个问题,Redis 作者 antirez 提出一种高级的分布式锁算法:Redlock

Redlock 核心思想

搞多个 Redis master 部署(推荐 5 个),以保证它们不会同时宕掉。并且这些 master 节点是完全相互独立的,相互之间不存在数据同步。

Redlock 实现步骤

  1. 获取当前时间,以毫秒为单位
  2. 按顺序向 5 个 master 节点请求加锁。客户端设置网络连接和响应超时时间,并且超时时间要小于锁的失效时间
  3. 客户端使用当前时间减去开始获取锁时间,得到获取锁使用的时间
  4. 当且仅当超过一半(N/2+1,这里是 3 个节点)的 Redis master 节点都获得锁,并且使用的时间小于锁失效时间时,锁才算获取成功
  5. 如果获取锁失败,客户端要在所有的 master 节点上解锁

8. Redis 大 Key 问题

8.1 什么是大 Key?

Redis 没有显式定义大 Key,这是一个通用的术语,用来描述那些在存储和性能方面可能引起问题的键。

大 Key 的判断标准

类型判断标准
String单个 key 的 value 大小超过 5MB
ZSET成员数量超过 1 万个
Hash成员数量虽然只有 1K,但成员的 Value 总大小超过 100MB

8.2 大 Key 引发的问题

  • 内存占用过高:大 Key 会占用大量内存,可能导致内存不足
  • 阻塞 Redis:删除大 Key 时会导致 Redis 阻塞,影响其他请求
  • 网络拥塞:获取大 Key 时会产生大量网络流量
  • 主从同步延迟:大 Key 会导致主从复制延迟增加

8.3 如何发现大 Key

bash
# 使用 redis-cli 的 --bigkeys 参数
redis-cli --bigkeys

# 使用 MEMORY USAGE 命令查看 key 的内存占用
MEMORY USAGE key_name

8.4 大 Key 的解决方案

方案说明
拆分将大 Key 拆分成多个小 Key
压缩对 value 进行压缩存储
异步删除使用 UNLINK 命令异步删除大 Key
定期清理设置合理的过期时间,定期清理

📌 总结

本文档涵盖了 Redis 面试中的核心知识点:

  1. 持久化机制:理解 RDB 和 AOF 的原理、优缺点和使用场景
  2. 过期策略:惰性删除 + 定期删除的组合策略
  3. 内存淘汰:6 种淘汰策略的特点和选择
  4. 缓存问题:击穿、穿透、雪崩的区别和解决方案
  5. 哨兵机制:实现 Redis 高可用的关键
  6. 一致性:数据库和缓存一致性的解决方案
  7. 分布式锁:从简单到复杂的 6 种实现方案
  8. 大 Key:识别和解决大 Key 问题

掌握这些知识点,可以帮助你在面试中更好地展示对 Redis 的深入理解。

不知道说啥了很无语了