Redis 面试知识点
本页只放 Redis 面试标准回答、常见追问、项目表达和知识点跳转。详细原理、流程图、Demo、排查流程放在知识点页:
- Redis 总览
- Redis 从零到生产级掌握
- Redis 从零到精通验收清单
- Redis 商业场景训练营
- Redis 基础
- 命令执行与数据结构原理
- 过期删除与内存淘汰原理
- Redis 高级
- 缓存问题
- 缓存一致性
- 高并发缓存治理
- 主从、哨兵与集群
- 主从哨兵 Cluster 全过程原理
- 分布式锁
- 红锁 Redlock
- 锁扩展点
使用方式
flowchart TD
A["面试题"] --> B["先答结论"]
B --> C["补关键原理"]
C --> D["说生产方案"]
D --> E["跳知识点复盘"]回答 Redis 问题时,建议按这个顺序组织:
- 先说明问题本质,例如“热 Key 是流量集中,大 Key 是单次操作太重”。
- 再说为什么会出问题,例如“Redis 命令线程顺序执行,一个慢命令会影响后续请求”。
- 再说怎么发现,例如
SLOWLOG、INFO、MEMORY USAGE、--bigkeys、应用埋点。 - 最后说怎么治理,例如拆 Key、本地缓存、逻辑过期、限流、异步删除、连接池保护。
高频索引
| 方向 | 高频题 | 原理页 |
|---|---|---|
| 基础原理 | Redis 为什么快、为什么单线程还能高并发、Redis 6/7 多线程是什么 | Redis 总览、命令执行与数据结构原理、高并发缓存治理 |
| 高并发缓存 | 穿透、击穿、雪崩、布隆过滤器、大 Key、热 Key、缓存一致性 | 缓存问题、缓存一致性、布隆过滤器原理、高并发缓存治理 |
| 生产排查 | timeout、慢命令、连接池耗尽、CPU 高、内存高、淘汰、KEYS 风险 | 高并发缓存治理、命令执行与数据结构原理、过期删除与内存淘汰原理 |
| 高可用 | RDB、AOF、主从、哨兵、Cluster、MOVED、ASK、数据丢失 | 持久化、主从、哨兵与集群、主从哨兵 Cluster 全过程原理 |
| 分布式锁 | SET NX PX、Lua 释放、Redisson、看门狗、Redlock、Fencing Token | 分布式锁、红锁、锁扩展点 |
基础原理类
Redis 怎么从零学到生产可用
标准回答:
Redis 要按数据结构、缓存模式、高并发问题、内存治理、持久化、高可用、分布式锁和生产排查这条线学习。先掌握 String、Hash、List、Set、ZSet、Bitmap、HyperLogLog 适合什么场景,再理解 Redis 为什么快、为什么单线程下慢命令会阻塞。缓存使用 Cache Aside,要处理穿透、击穿、雪崩、TTL、空值缓存和布隆过滤器。生产还要理解 RDB/AOF、主从、哨兵、Cluster、大 Key、热 Key、缓存一致性、分布式锁和 timeout 排查。
追问要点:
| 追问 | 回答方向 |
|---|---|
| Redis 能不能替代 MySQL | 不能。Redis 适合缓存和临时状态,核心事实数据仍应落数据库 |
| 生产 Redis 问题从哪里排查 | 先看应用连接池和超时,再看 slowlog、bigkeys、info、命中率、主从延迟 |
原理跳转:Redis 从零到生产级掌握、Redis 从零到精通验收清单、命令执行与数据结构原理、高并发缓存治理。
Redis 为什么快
标准回答:
Redis 快不是单纯因为“基于内存”。它主要快在五点:数据在内存中,避免大量磁盘 IO;核心命令执行线程模型简单,减少锁竞争;使用 IO 多路复用处理大量连接;内置数据结构针对场景优化,例如 Hash、ZSet、Bitmap;很多命令复杂度低,单条命令执行时间短。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 只要内存就一定快吗 | 不是。大 Key、慢命令、长 Lua、网络传输、持久化、主从同步都会让 Redis 变慢 |
| Redis 快能不能代替 MySQL | 不能。Redis 更适合缓存、临时状态、计数、排行榜;核心事实数据仍应以数据库为准 |
原理跳转:Redis 总览:为什么需要 Redis、命令执行与数据结构原理、高并发缓存治理:Redis 为什么高并发下也会慢。
Redis 单线程为什么还能高并发
标准回答:
Redis 常说的单线程,主要指核心命令执行是单线程顺序执行。它还能高并发,是因为大多数命令是内存操作,执行很短;IO 多路复用可以让少量线程监听大量连接事件;单线程避免了多线程加锁和上下文切换开销。但单线程也意味着一个慢命令会阻塞后续命令,所以高并发下必须避免大 Key、全量查询和长 Lua。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 单线程是不是不会有并发问题 | 命令执行顺序是单线程,但客户端并发请求、业务超时、锁过期、缓存一致性仍然会有并发问题 |
| 一个命令慢会怎样 | 后续命令排队,表现为 Redis 延迟升高、应用 timeout |
原理跳转:命令执行与数据结构原理、高并发缓存治理:单线程、多线程和 IO 多路复用。
Redis 6/7 的多线程是什么
标准回答:
Redis 6 之后引入多线程主要是为了优化网络 IO 读写等部分开销,不是让多个线程同时并发执行所有命令。核心数据结构的命令执行仍保持相对简单的线程模型,所以 Redis 不会因为开启 IO 多线程就可以随意执行大 Key 或慢命令。Redis 7 继续增强很多能力,但面试回答重点仍是:多线程主要优化 IO 和后台任务,命令本身仍要关注复杂度。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 开启多线程后慢命令还会阻塞吗 | 会。命令执行慢仍然会影响后续请求 |
| Redis 多线程能解决热 Key 吗 | 不能根治。热 Key 是流量集中,需要本地缓存、拆 Key、限流等治理 |
原理跳转:高并发缓存治理:单线程、多线程和 IO 多路复用。
Redis 常见数据结构怎么选
标准回答:
String 适合普通缓存、计数器、分布式锁;Hash 适合对象字段和购物车;List 适合简单队列和时间线;Set 适合去重、标签、共同好友;ZSet 适合排行榜、延迟任务;Bitmap 适合签到和布尔状态统计;HyperLogLog 适合 UV 估算。选择时不只看能不能存,还要看命令复杂度、查询方式、数据增长上限和是否可能形成大 Key。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 为什么对象不一定都用大 JSON String | 大 JSON 更新和传输成本高,字段级更新差,容易形成大 Key |
| ZSet 排行榜为什么快 | 按 score 维护有序结构,天然支持区间和 TopN 查询 |
原理跳转:Redis 基础、Redis 总览:常见数据结构怎么选、命令执行与数据结构原理。
Redis 事务和 Lua 怎么理解
标准回答:
Redis 事务通过 MULTI、EXEC 把命令按顺序排队执行,但它不像 MySQL 事务那样支持完整回滚。Redis 单条命令是原子的,Lua 脚本执行期间也具有原子性,适合把“判断再修改”的短逻辑合并到 Redis 端执行,例如释放分布式锁、限流扣减。但 Lua 不能写太重,否则会阻塞 Redis。
追问要点:
| 追问 | 回答方向 |
|---|---|
| Lua 为什么能防锁误删 | 判断 value 和删除 key 在 Redis 端一次执行,避免中间被其他客户端插入 |
| Lua 能不能写复杂业务 | 不建议。长脚本会阻塞命令线程,复杂业务应放应用或数据库 |
原理跳转:Redis 基础:事务、分布式锁。
高并发缓存类
缓存穿透、击穿、雪崩区别
标准回答:
缓存穿透是查询不存在的数据,缓存和数据库都没有,导致每次请求都打数据库;缓存击穿是某个热点 Key 过期,大量请求同时回源数据库;缓存雪崩是大量 Key 同时过期或 Redis 整体故障,导致大面积请求打到数据库。穿透治理靠参数校验、空值缓存、布隆过滤器;击穿靠互斥锁、逻辑过期、热点预热;雪崩靠 TTL 随机、高可用、多级缓存、限流降级。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 缓存空值有什么风险 | 无效 Key 太多会占内存,所以 TTL 要短,还要配合参数校验 |
| 布隆过滤器有什么缺点 | 可能误判存在,删除困难,适合相对稳定的数据集合 |
原理跳转:缓存问题、布隆过滤器原理、高并发缓存治理:缓存穿透治理。
布隆过滤器原理是什么
标准回答:
布隆过滤器由一个位数组和多个哈希函数组成。添加元素时,用多个哈希函数算出多个位置,把这些 bit 置为 1;查询元素时,再算出这些位置,只要有任意一个 bit 是 0,就说明这个元素一定不存在;如果所有 bit 都是 1,只能说明可能存在。它适合防缓存穿透,因为能用很小内存拦截大量随机不存在的 ID。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 为什么会误判 | 不同元素的哈希位置可能碰撞,不存在的元素也可能刚好对应一组全是 1 的 bit |
| 为什么不会漏判 | 已添加元素对应的 bit 都被置为 1;只要不错误删除,就不会被判断为不存在 |
| 为什么不能直接删除 | 多个元素可能共享同一个 bit,清零会影响其他元素 |
| 参数怎么定 | 根据预计元素数量和期望误判率计算位数组长度和哈希函数数量 |
| 项目里怎么更新 | 启动或定时全量构建,新数据写库成功后增量加入,删除多时定期重建 |
项目表达:
资产平台里可以把有效 asset_id、table_id、field_id 加入布隆过滤器。查询时先做参数校验,再查布隆过滤器;如果判断一定不存在,就直接返回空,不查 Redis 和 MySQL;如果可能存在,再走缓存和数据库。新增资产成功后增量加入过滤器,删除较多时定期从数据库全量重建。原理跳转:布隆过滤器原理。
什么是大 Key
标准回答:
大 Key 指一个 Key 对应的 value 太大,不是 Key 名字长。比如一个 String 存几 MB JSON,一个 Hash 有几十万 field,一个 List/Set/ZSet 有大量元素。大 Key 会导致网络传输慢、命令执行慢、删除阻塞、AOF 和主从复制压力大、Cluster 分片内存不均。发现方式有 redis-cli --bigkeys、MEMORY USAGE key、SCAN 分批扫描、SLOWLOG 和监控。治理方式是拆 Key、分页取、限制集合大小、避免全量命令、删除用 UNLINK。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 大 Key 为什么会拖慢 Redis | 单线程执行命令,大 Key 的读取、序列化、网络返回、删除释放内存都会变重 |
DEL 大 Key 有什么问题 | DEL 同步释放内存可能阻塞主线程,应优先用 UNLINK 异步释放 |
| Hash 很大怎么办 | 按业务维度拆 Hash,或者用 HSCAN 分批,禁止 HGETALL 全量 |
项目表达:
我们会把资产详情、字段元数据这类缓存控制大小,不把一个机构或一张表的全部字段塞进一个 Key。排查时先看 slowlog、bigkeys 和 memory usage,治理上按表、字段、分页拆 Key,大 Key 删除使用 UNLINK。原理跳转:大 Key 与热 Key 全过程治理:大 Key、治理决策表。
什么是热 Key
标准回答:
热 Key 是访问频率远高于其他 Key 的 Key,比如秒杀库存、热门商品详情、热门资产详情、全站字典配置。Redis Cluster 中一个 Key 只能落到一个 slot,而一个 slot 只由一个主节点负责,所以热 Key 会把单个节点打满,其他节点可能还很空。发现方式包括应用侧 Key 访问统计、网关接口统计、Redis --hotkeys、代理层统计、监控单节点 CPU 和网络。治理方式是本地缓存、多级缓存、热点预热、逻辑过期、拆分 Key、限流降级、请求合并。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 热 Key 和大 Key 区别 | 热 Key 是访问量太高,大 Key 是单次数据太大。一个 Key 可以同时又热又大 |
| Cluster 为什么解决不了单个热 Key | 单个 Key 只能落到一个 slot,不能天然分摊到多个 Master |
| 热 Key 能不能简单加机器解决 | 加机器只能扩整体容量,单 Key 热点仍要靠本地缓存、拆 Key、限流 |
项目表达:
热门资产、字典配置、首页统计这类数据会做本地缓存和短 TTL,多实例先命中本地缓存,降低 Redis 单点压力;强一致数据比如权限、库存不会随便用本地缓存,需要按业务一致性要求设计。原理跳转:大 Key 与热 Key 全过程治理:热 Key、Cluster 下的热点问题、热 Key 治理优先级。
缓存击穿为什么要用互斥锁或逻辑过期
标准回答:
热点 Key 过期瞬间,如果所有请求都去查数据库,数据库承受的是热点流量峰值,这就是击穿。互斥锁让只有一个线程回源并重建缓存,其他线程等待、重试或返回旧值;逻辑过期是在 value 里保存过期时间,过期后先返回旧数据,再异步重建,适合读多写少且允许短暂旧值的场景。不适合账户余额、支付状态、库存强一致判断。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 互斥锁有什么缺点 | 等待会增加延迟,锁超时和误删要处理,仍要有兜底 |
| 逻辑过期有什么缺点 | 会返回旧数据,需要异步重建和失败补偿 |
原理跳转:缓存问题:缓存击穿、高并发缓存治理:逻辑过期治理击穿。
缓存和数据库不一致怎么办
标准回答:
常见 Cache Aside 策略是先更新数据库,事务提交后删除缓存。删除缓存失败时要记录重试任务或发送消息补偿,缓存本身设置合理 TTL 作为最终恢复兜底。不要简单先删缓存再更新数据库,因为并发读可能在数据库更新前读到旧值并重新写入缓存。要求更高时可以用延迟双删、Binlog CDC 修正缓存、本地缓存广播失效等方案,但缓存通常只能做到最终一致或短时间不一致,关键交易和权限判断仍要回数据库或业务服务。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 为什么不是更新缓存 | 并发更新下顺序难保证,缓存数据可能由复杂查询拼装,删除后重建更稳。详见:四种写法的并发全过程 |
| 为什么不能先删缓存再写库 | 删除后、写库前的并发读可能查到旧库,并把旧值重新写回 Redis。详见:写法三:先删除缓存,再更新数据库 |
| 先写库再删缓存还有没有问题 | 有极端并发窗口:慢读请求可能在写请求删除缓存后,把旧值写回缓存。详见:先写库再删缓存的极端并发窗口 |
| 为什么要事务提交后删缓存 | 避免数据库回滚但缓存已删除,也避免事务未提交时其他请求读旧库重建旧缓存。详见:事务提交后再删缓存 |
| 删除缓存失败怎么办 | 重试表、消息补偿、Binlog 订阅、TTL 兜底、告警。详见:删除缓存失败怎么办 |
| 延迟双删适合什么时候 | 高并发读写同一个 key,且业务能接受短暂旧值,用来清理慢读请求回写的旧值。详见:延迟双删全过程 |
| Binlog CDC 解决什么 | 订阅数据库事实变更,作为业务删缓存失败或漏删时的异步兜底。详见:Binlog CDC 兜底全过程 |
| 本地缓存怎么一致 | 短 TTL、广播失效、MQ 通知,关键读绕过本地缓存。详见:本地缓存的一致性 |
原理跳转:Redis 与数据库缓存一致性。
Redis 和数据库如何保证一致性
标准回答:
常见 Cache Aside 策略是先更新数据库,事务提交后删除缓存。删除失败时要有重试、MQ、Binlog CDC 或 TTL 兜底。不要简单先删缓存再更新数据库,因为并发读可能在数据库更新前读到旧值并重新写入缓存。缓存和数据库通常只能做到最终一致,强一致场景要读数据库或通过业务状态机保证。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 删除缓存失败怎么办 | 重试表、MQ、CDC、TTL 兜底和告警。详见:删除缓存失败怎么办 |
| 为什么不直接更新缓存 | 并发顺序难保证,复杂缓存可能由多表拼装,删除后重建更稳。详见:为什么不推荐直接更新缓存 |
| 先删缓存再写数据库为什么危险 | 并发读可能在数据库更新前读旧值并写回缓存。详见:为什么不推荐先删缓存再写数据库 |
| 延迟双删是不是强一致 | 不是,只是缩短旧值回写窗口,仍要配合重试、TTL 和关键读回源。详见:延迟双删的问题 |
原理跳转:Redis 从零到生产级掌握、缓存一致性。
版本号怎么防止旧缓存回写
标准回答:
版本号防旧值回写解决的是一个极端并发窗口:读请求先缓存未命中并查到数据库旧值,但因为慢查询、网络或序列化很慢,写缓存动作发生得很晚;期间写请求已经把数据库更新成新值并删除缓存;最后慢读请求又把旧值写回 Redis。解决思路是在缓存值里保存 version 或 updated_at,写缓存前用 Lua 原子比较 Redis 当前版本和准备写入版本,只允许新版本覆盖旧版本,旧版本写入直接拒绝并记录指标。它不能替代写库后删缓存、删除失败重试和 TTL,只是防止旧值覆盖新值的一层保护。
追问要点:
| 追问 | 回答方向 |
|---|---|
| version 从哪里来 | 数据库乐观锁版本号、更新时间或业务数据版本 |
| 为什么用 Lua | 比较版本和写入缓存要在 Redis 端原子执行 |
| 能不能完全保证一致 | 不能。删除失败、本地缓存、漏删列表 key、强一致读仍要单独处理 |
| 怎么发现线上发生过旧值回写 | 记录 cache_stale_write_rejected_total 这类拒绝旧版本写入指标 |
原理跳转:版本号防旧值回写、版本号写缓存 Demo。
生产排查类
Redis timeout 怎么排查
标准回答:
Redis timeout 不一定是 Redis 宕机。排查要按链路看:先判断超时发生在借连接、网络传输、Redis 排队执行、返回大响应、客户端反序列化,还是缓存未命中后的数据库回源。再看应用连接池是否耗尽、SLOWLOG 是否有慢命令、大 Key、长 Lua,INFO 中 CPU、memory、clients、stats、replication 是否异常。最后看缓存命中率是否下降,是否因为穿透、击穿、雪崩导致 DB 慢,反过来拖住业务线程和 Redis 连接归还。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 应用线程堆积但 Redis CPU 不高怎么办 | 可能是连接池等待、网络等待、大响应反序列化、DB 回源慢、客户端超时配置不合理 |
SLOWLOG 没慢命令就能排除 Redis 吗 | 不能。热 Key 单次命令不慢但频率极高,大响应、连接池等待、网络、回源 DB 都可能导致 timeout |
| 只加大连接池行不行 | 不一定。连接池过大可能把 Redis 或 DB 打得更重,要先定位根因 |
| 怎么判断是不是数据库回源拖慢 | 看缓存命中率、DB QPS、慢 SQL、应用线程栈、Redis 连接池等待是否同时异常 |
原理跳转:高并发缓存治理:生产排查流程、Redis timeout 全链路排查、连接池、线程池和 Redis 的关系。
Redis 连接池打满怎么办
标准回答:
Redis 连接池打满要先判断是请求量太大、单请求 Redis 次数太多、命令执行慢、网络慢,还是缓存未命中回源 DB 导致连接归还变慢。不能上来就把连接池调大,因为更大的连接池可能让更多请求同时打到 Redis 或 DB,放大排队。治理思路是减少单请求 Redis 调用次数,批量查询用 MGET 或 Pipeline,热点数据加本地缓存,低价值接口限流,慢命令和大 Key 先治理,缓存回源要加互斥锁、逻辑过期和降级保护。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 活跃连接接近上限说明什么 | 说明连接被长时间占用或并发超出容量,要看命令耗时和业务线程栈 |
| 空闲连接长期为 0 怎么办 | 先看等待队列和 borrow latency,再看是否接口突刺或连接未及时归还 |
| timeout 时间调长是否更安全 | 不一定。调长会让线程占用更久,可能扩大雪崩 |
原理跳转:应用连接池排查、连接池、线程池和 Redis 的关系。
Redis 慢查询怎么查
标准回答:
使用 SLOWLOG GET 20 查看慢命令,结合 INFO commandstats 看命令调用分布。慢命令常见原因是大 Key、全量命令、复杂集合操作、长 Lua、一次返回结果太大。治理上禁止生产使用 KEYS *,大集合用 SCAN、HSCAN、SSCAN、ZSCAN 分批,分页获取,删除大 Key 用 UNLINK。
常用命令:
redis-cli slowlog get 20
redis-cli info commandstats
redis-cli --bigkeys
redis-cli memory usage your:key原理跳转:高并发缓存治理:Redis 慢命令和阻塞。
KEYS 和 SCAN 有什么区别
标准回答:
KEYS pattern 会一次扫描整个 keyspace,生产环境 key 很多时会阻塞 Redis,风险很高。SCAN 是游标式渐进扫描,每次返回一部分 Key,不会长时间独占 Redis,但它不是完全无成本,也可能重复返回,需要业务去重或容忍重复。生产扫描要低峰、限速,最好走从库或离线分析。
追问要点:
| 追问 | 回答方向 |
|---|---|
SCAN 会不会漏数据 | 迭代期间 keyspace 变化时结果不是强一致快照,可能重复或变化 |
SCAN count 是精确数量吗 | 不是,只是每次扫描工作量提示 |
原理跳转:高并发缓存治理:大 Key 怎么发现。
DEL 和 UNLINK 有什么区别
标准回答:
DEL 删除 Key 时会同步释放内存,如果 Key 很大,可能阻塞 Redis 命令线程。UNLINK 会先把 Key 从 keyspace 解除,再把真正释放内存的工作交给后台线程,能降低删除大 Key 对主线程的影响。它不是不消耗资源,而是把阻塞风险后移到后台。
追问要点:
| 追问 | 回答方向 |
|---|---|
所有删除都用 UNLINK 吗 | 大 Key 推荐,小 Key 用 DEL 也可以,核心是识别删除成本 |
UNLINK 后内存会立刻下降吗 | 不一定,后台释放需要时间 |
原理跳转:高并发缓存治理:大 Key 怎么治理。
Redis 内存高怎么办
标准回答:
先看 INFO memory、Key 数量、是否有大 Key、是否有大量无 TTL Key、空值缓存是否过多、淘汰策略是否合理。再看业务是否把 Redis 当数据库长期存储,是否存在无限增长的 List、Set、ZSet。治理包括设置合理 TTL、拆分或清理大 Key、限制集合长度、配置 maxmemory 和淘汰策略、冷热数据分层、监控命中率和淘汰次数。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 内存满了一定会报错吗 | 取决于 maxmemory-policy,可能报错,也可能淘汰 Key |
| 淘汰策略会有什么风险 | 热数据被淘汰会造成命中率下降和数据库回源 |
原理跳转:过期删除与内存淘汰原理、高并发缓存治理:过期删除和内存淘汰。
Pipeline 和 MGET 怎么用
标准回答:
循环单个 GET 会产生大量网络往返,批量读取可以用 MGET 或 Pipeline 降低 RTT。Pipeline 是把多个命令一次发给 Redis,再批量读取响应。但 Pipeline 不能把慢命令变快,也不能无限大批量,否则返回结果太大、输出缓冲区膨胀、客户端反序列化慢。Cluster 下还要考虑 key 是否跨 slot,成熟客户端通常会拆分请求。
追问要点:
| 追问 | 回答方向 |
|---|---|
| Pipeline 是否保证事务 | 不保证。它主要减少网络往返,不提供事务语义 |
| 批量大小怎么定 | 根据 value 大小、网络、Redis 延迟、P99 压测决定 |
原理跳转:高并发缓存治理:Pipeline、批量命令和输出缓冲区。
高可用和持久化类
RDB 和 AOF 区别
标准回答:
RDB 是定期生成内存快照,恢复快、文件紧凑,但两次快照之间可能丢数据;AOF 是追加记录写命令,数据丢失窗口更小,但文件更大,恢复需要重放命令,AOF rewrite 会带来磁盘 IO 和 fork 成本。生产常见是 RDB + AOF 混合,缓存数据可以接受丢失时可以简化持久化,核心事实数据不应只依赖 Redis。
追问要点:
| 追问 | 回答方向 |
|---|---|
appendfsync everysec 会不会丢数据 | 极端宕机可能丢最近约 1 秒数据 |
| AOF rewrite 会不会影响性能 | 会有 fork、磁盘 IO、rewrite 缓冲等开销,需要监控 |
原理跳转:Redis 持久化。
主从、哨兵和 Cluster 区别
标准回答:
主从复制解决数据副本和读扩展,但不自动完成故障转移;哨兵在主从基础上监控 Master,故障后选举 Slave 晋升,主要解决高可用;Redis Cluster 通过 16384 个 hash slot 把数据分散到多个 Master,同时具备分片扩容和分片级故障转移。哨兵不解决单机容量和写能力上限,Cluster 能扩容但会带来 slot、MOVED/ASK、跨 slot 多 key 限制。
项目表达:
如果 Redis 数据量和写压力不大,主要担心主节点故障,可以选主从加哨兵;如果单机内存或写入能力不够,需要多个 Master 分摊,就选 Cluster,但要提前设计 key,避免跨 slot 多 key 操作和热点 slot。原理跳转:主从、哨兵与集群、主从哨兵 Cluster 全过程原理、哨兵和 Cluster 怎么选。
MOVED 和 ASK 是什么
标准回答:
Redis Cluster 中 key 根据 hash slot 定位到某个 Master。客户端访问错节点时,Redis 会返回重定向。MOVED 表示 slot 已经稳定归属到另一个节点,客户端应该更新本地 slot 缓存;ASK 表示 slot 正在迁移中,客户端临时去目标节点执行一次,不应立刻永久更新全部映射。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 为什么客户端要支持 Cluster | 要能缓存 slot 映射、处理 MOVED/ASK、拆分跨节点请求 |
| hash tag 有什么用 | 让多个 key 的 {} 中内容参与 slot 计算,使相关 key 落同一个 slot |
原理跳转:主从哨兵 Cluster 全过程原理、MOVED 和 ASK 重定向。
Redis 主从切换会不会丢数据
标准回答:
可能会。Redis 主从复制默认异步,Master 写成功返回后,命令可能还没复制到 Slave。如果 Master 宕机,Slave 晋升为新 Master,未同步的数据就会丢失。可以通过合理持久化、WAIT 等待副本确认、监控复制延迟来降低风险,但 Redis 不适合作为强一致核心账本唯一存储。
追问要点:
| 追问 | 回答方向 |
|---|---|
WAIT 能彻底保证不丢吗 | 不能绝对保证,只是等待副本确认,增加可靠性也增加延迟 |
| 为什么缓存丢一点可以接受 | 因为缓存可从数据库重建,关键事实数据在数据库 |
原理跳转:主从哨兵 Cluster 全过程原理、主从复制为什么可能丢数据。
分布式锁类
Redis 分布式锁正确写法
标准回答:
Redis 锁要用 SET lockKey uniqueValue NX PX ttl,保证加锁和设置过期时间是一个原子命令。释放锁不能直接 DEL,必须用 Lua 判断 value 是否是自己的唯一标识,再删除,避免锁过期后误删别人锁。业务执行时间要小于锁有效期,长任务考虑 Redisson 看门狗或任务状态机。核心业务最终还要靠幂等、唯一约束和状态机兜底。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 为什么要设置过期时间 | 防止持锁服务宕机造成死锁 |
| 为什么 value 要唯一 | 解锁时识别锁是否仍属于自己 |
| 锁能不能保证最终正确 | 不能,只能减少并发,最终正确性靠业务兜底 |
原理跳转:Redis 分布式锁。
Redisson 看门狗是什么
标准回答:
Redisson 看门狗是在没有指定固定 leaseTime 时,对持有的锁定期续期,避免业务还没执行完锁提前过期。它通常按锁超时时间的一部分周期续期。看门狗能缓解执行时间不确定问题,但不能解决 JVM 长 GC、网络抖动、业务线程卡死,也不能替代数据库状态机和幂等。
追问要点:
| 追问 | 回答方向 |
|---|---|
指定 leaseTime 后还有看门狗吗 | 通常不会使用默认自动续期,要按 Redisson 用法确认 |
| 看门狗是不是越长越安全 | 不是。锁持有太久会影响吞吐和故障恢复 |
原理跳转:分布式锁:自动续期、锁扩展点:看门狗续期。
什么是红锁 Redlock
标准回答:
Redlock 是 Redis 分布式锁的多独立节点多数派算法。普通 Redis 锁在主从异步复制和故障切换时可能出现锁丢失,Redlock 会让客户端向多个相互独立的 Redis Master 加同一把锁,超过半数节点成功,并且总耗时小于 TTL,才算拿锁成功;失败要释放已加锁节点。但 Redlock 不是强一致共识算法,不能解决长 GC、业务超时、下游写入乱序等问题,核心业务仍要用状态机、幂等、唯一约束、Fencing Token 和补偿兜底。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 为什么要多数派 | 降低单 Redis 节点故障导致锁丢失的风险 |
| 为什么要判断耗时 | 加锁过程消耗 TTL,耗时太长时锁可能已接近过期 |
| 红锁能不能保证绝对安全 | 不能。它不是 Paxos/Raft,不是强一致事务 |
原理跳转:红锁 Redlock。
Redisson 常见锁有哪些
标准回答:
常见有 RLock 可重入锁、FairLock 公平锁、ReadWriteLock 读写锁、MultiLock 联锁、RedLock 红锁、RSemaphore 信号量、RPermitExpirableSemaphore 可过期信号量、RCountDownLatch 闭锁。回答时不要只背名字,要说适用边界:RLock 适合普通业务互斥,读写锁适合读多写少,信号量限制最多 N 个并发,公平锁吞吐更低,联锁复杂度更高。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 可重入锁怎么实现 | Redisson 通常用 Redis Hash 记录线程标识和重入次数 |
| 公平锁为什么慢 | 要维护等待队列和顺序唤醒 |
| 信号量和锁区别 | 锁是 1 个许可,信号量是 N 个许可 |
原理跳转:锁扩展点。
Redis运行在Docker中要关注什么
标准回答:
Redis容器化不是执行一个 docker run redis 就结束。网络上应保持protected mode,使用Redis 6+ ACL和Secret,优先只开放内部网络,不把6379直接暴露公网;数据上要把 /data 挂到Volume并根据RPO选择RDB、AOF或混合持久化,但Volume不是备份,仍要做独立备份和恢复演练;内存上不能让maxmemory等于cgroup限制,因为RSS还包括allocator碎片、客户端和复制Buffer、AOF Buffer以及fork期间的Copy-on-Write;宿主机还要检查overcommit、THP、文件描述符和磁盘IO。单容器restart只解决进程重启,不是高可用,主从、Sentinel和Cluster必须按副本、故障转移、分片及跨故障域需求选择。
追问要点:
| 追问 | 回答方向 |
|---|---|
| 为什么不能公开6379 | protected mode和ACL不是替代网络隔离,公网暴露会扩大扫描、撞库和误操作风险 |
| 为什么Volume不是备份 | 它通常仍在同一宿主机,会受磁盘故障、误删、down -v影响 |
| 为什么持久化可能OOM | fork后写流量触发COW,RSS可能明显高于used_memory和maxmemory |
| 容器重启后没数据先查什么 | 查Mounts、Compose项目名、RDB/AOF配置、加载日志、权限与磁盘,不先删文件 |
| 三个Redis容器是不是高可用 | 不一定;都在同一主机仍共享一个故障域,还要看角色、选主和客户端切换 |
原理跳转:Redis容器化、ACL、RDB/AOF、内存预算与高可用边界。
项目表达模板
医疗数据采集与资产平台怎么用 Redis
可以这样说:
项目里 Redis 主要用于热点资产详情、机构字典、字段元数据、采集任务状态、限流和分布式锁。核心业务事实仍然落 MySQL,Redis 作为缓存和辅助状态。
缓存读取采用 Cache Aside,正常数据设置随机 TTL,查不到的数据短 TTL 缓存空值防穿透。热点资产和字典配置会用本地缓存加 Redis 多级缓存,热点 Key 过期采用逻辑过期或互斥锁防击穿。大 Key 方面,不把一个机构或一张表的全部字段塞进一个 Key,而是按机构、表、字段、分页拆分;删除大 Key 用 UNLINK。
线上排查时会先看应用连接池和超时,再看 Redis slowlog、bigkeys、memory usage、info clients、info commandstats。如果是单节点热点,会做本地缓存、拆 Key、限流;如果是 DB 回源高,会检查穿透、击穿、雪崩和缓存命中率。常见追问速记
| 追问 | 标准方向 | 原理页 |
|---|---|---|
| 热 Key 扩容 Redis 有用吗 | 对整体容量有用,对单 Key 热点不一定有用,因为一个 Key 只落一个 slot | 热 Key |
| 大 Key 和热 Key 谁更危险 | 都危险。大 Key 让单次操作重,热 Key 让单点流量集中,叠加时最危险 | 大 Key 与热 Key |
| Redis 挂了怎么办 | 限流、降级、数据库保护、热点本地缓存、告警和缓存重建 | 降级和数据库保护 |
| 连接池越大越好吗 | 不是。过大可能放大 Redis 和 DB 压力,要结合 QPS、RT、超时和压测 | 连接池 |
为什么生产禁用 KEYS * | 会扫描全库并阻塞 Redis,应用应使用 SCAN 分批且限速 | 大 Key 怎么发现 |
| 为什么缓存不能强一致 | 缓存是数据库副本,网络、并发、删除失败都会导致短暂不一致 | 缓存一致性 |
| Redis 锁和 ZK 锁怎么选 | Redis 性能高适合业务互斥,ZK/etcd 更适合协调、选主和低频关键一致性 | 锁扩展点 |
本章小结
Redis 面试不能只背“快、单线程、缓存三大问题”。更好的回答要能说出:为什么快、什么情况下会慢、高并发下大 Key 和热 Key 怎么发现和治理、缓存问题如何保护数据库、线上 timeout 怎么排查、哨兵和 Cluster 怎么选、分布式锁为什么还需要幂等兜底。详细原理统一回到知识点页复盘。
