面试记录 2026-09-20
题目:如果设计一个缓存,需要考虑哪些方面?
难度:high
标签:practice/redis, redis/design, redis/cache
评分:⭐⭐☆☆☆(2/5)
我的回答
设计缓存优先要考虑的,我觉得是效率,然后是稳定性,再然后是持久化,还有就是支撑大的资源的反馈。首先效率上,主流的还是缓存。用内存。稳定性方面,基本上是分布式的一个形态,然后提供服务。分布式主从或者是集群,通过分片的方式去提供缓存的稳定性。然后持久化方面,为了保证数据的安全性吧,缓存类的数据还是要,有时候还是要考虑一些安全性的,它突然消失了,是否能重新读回?这时候考虑用持久化。资源,大的资源方面可以通过分布式去解决,横向扩展、扩容。这暂时是我的一些考虑。
点评
优点:
- 抓了 4 个方向:效率、稳定性、持久化、扩展性
- 顺序合理:性能 → 可用性 → 数据安全 → 横向扩展
不足:
- 广度严重不足:设计一个缓存至少 10+ 个维度,只答了 4 个
- 每个维度都停留在"名词"层面:效率只说"用内存"没说数据结构选型;稳定性只说"分布式"没说一致性模型/故障转移/脑裂;持久化只说"考虑"没说 RDB/AOF/混合持久化;扩展只说"横向扩展"没说分片策略/重平衡/迁移
- 完全漏掉关键维度:淘汰策略、过期机制、并发控制(原子性/Lua/事务)、网络模型(I/O 多路复用/协议)、内存管理(SDS/jemalloc)、安全(认证/ACL/TLS)、监控、多级缓存、数据一致性、API 设计、容量规划、限流熔断
- 缺乏量化思维:没说"效率"要多少 QPS、"稳定性"要几 9、"持久化"要什么 RPO
- 没有取舍权衡:设计题的核心是 trade-off,只列不取舍
补充:设计缓存的 12 大维度框架(见完整讲解)
完整讲解
第一部分:知识重点剖析
核心考点定位:考察系统设计的结构化思维——能否列出所有关键维度 + 每个维度给出量化目标 + 讲清 trade-off。
知识点拆解——12 大维度框架:
- 性能模型(先定目标):目标 QPS(如 10w)、P99 延迟(< 5ms)、内存占用、带宽;用 redis-benchmark 建基准;上线前压测找临界点
- 数据结构(选对工具):String(KV/计数/锁/Session)、Hash(对象)、List(队列)、Set(去重/共同好友)、ZSet(排行榜/延迟队列);小数据用 ziplist/listpack,大数据自动升级
- 淘汰与过期:过期用惰性 + 定期删除(serverCron 采样);淘汰选 LRU(近似采样)、LFU(Redis 4.0+,防热点长尾);通用 allkeys-lru;热点长尾 allkeys-lfu;数据不能丢 noeviction
- 持久化(RPO/RTO 权衡):RDB 快照恢复快但丢 15min 数据;AOF 追加日志 everysec 更安全但写慢;混合持久化(Redis 4.0+)RDB + 增量 AOF 是最佳折中
- 高可用:主从复制读扩展 + 故障转移;Sentinel 哨兵自动故障转移,3 个哨兵仲裁;Cluster 原生分片 16384 哈希槽;脑裂防护 min-replicas-to-write + 多数派仲裁
- 扩展(分片策略):哈希槽(Redis Cluster 16384 槽,MOVED 重定向);一致性哈希(自定义分片,减少数据迁移);在线重平衡(redis-cli --cluster reshard);平滑扩容先加节点再迁 slot 再验证再摘老节点
- 一致性(CAP 选型):Redis 是 AP 系统分区容忍 + 可用性牺牲一致性;写已写写主库立即返回读可能读到旧值;读多数 READMULTI 多副本读;最终一致靠异步复制 + 业务容忍窗口
- 并发控制:单线程模型命令串行天然原子;Lua 脚本批量操作原子化;事务 MULTI/EXEC 无回滚慎用;分布式锁 Redlock / Redisson(6.0+ 推荐)
- 网络模型:I/O 多路复用 epoll/kqueue 单线程处理万级连接;RESP 协议轻量二进制;连接复用(Lettuce 用 Netty 复用);Pipeline 批量命令减少 RTT
- 安全:认证密码 + ACL(Redis 6.0+ 细粒度权限);传输加密 TLS;网络隔离内网访问防火墙白名单;审计命令日志敏感操作告警
- 监控(可观测性):核心指标 QPS、延迟 P50/P99、内存 used_memory、连接数;业务指标 evicted_keys、expired_keys、rejected_connections;慢查询 SLOWLOG(默认阈值 10ms);告警 Prometheus + Grafana
- 业务集成:穿透/击穿/雪崩用布隆过滤器 + 互斥锁 + TTL 抖动;多级缓存本地 Caffeine + 分布式 Redis + DB;限流熔断 Sentinel / Hystrix;与 DB 一致性 Cache-Aside + 延迟双删 + Canal + TTL 兜底;API 设计 CRUD、批量、事务、Pub/Sub、Pipeline
第二部分:考察方向与延伸递进
考察方向:
- 深度:每个维度的实现细节(如 LFU 计数器衰减、一致性哈希的虚拟节点)
- 广度:与 Memcached / etcd / TiKV / Hazelcast 对比选型
- 应用:具体场景(电商秒杀、社交 Feed、排行榜、Session)的架构设计
延伸递进面试题:
- 如何估算缓存容量?
- 解答要点:热点数据量 × 单条大小 × 副本数 × 安全系数(1.5-2);MEMORY USAGE 抽样
- 一致性哈希如何解决数据倾斜?
- 解答要点:虚拟节点(每物理节点 100-150 个虚拟节点)、MD5 散列均匀
- Redis Cluster 的脑裂如何防护?
- 解答要点:min-replicas-to-write + 多数派仲裁 + 老主库下线验证
- Redis 如何做蓝绿部署?
- 解答要点:新版本部署 → 双写或同步旧数据 → 灰度切流 → 全量切换 → 回滚预案
- 如何设计一个支持强一致缓存?
- 解答要点:Raft 协议(etcd 思路)+ 多副本同步 + 写多数;或业务层加锁
- 缓存如何优雅降级?
- 解答要点:熔断打开 → 走 DB(限流)→ 静态兜底数据 → 前端提示
- 多级缓存的一致性如何解决?
- 解答要点:Cache-Aside + 发布订阅 + 本地缓存 TTL 极短 + 容忍短暂不一致
第三部分:面试者参考回答(300-600 字口语化)
面试官您好,设计缓存我一般从 12 个维度入手,每个都要给量化目标和权衡。
第一层:性能与存储。性能模型先定目标 QPS(如 10w)、P99 延迟(< 5ms)、内存预算;用 redis-benchmark 建基准。数据结构:String(KV/计数/锁)、Hash(对象)、List(队列)、ZSet(排行榜);小数据用 listpack 紧凑。淘汰与过期:过期用惰性 + 定期删除;淘汰选 allkeys-lru(通用)或 allkeys-lfu(热点长尾);TTL 加随机抖动防雪崩。
第二层:可靠性与扩展。持久化:RDB 恢复快但丢 15min,AOF everysec 更安全但写慢;混合持久化是最佳折中。高可用:主从 + Sentinel 自动故障转移;生产用 Cluster 16384 哈希槽分片。脑裂防护:min-replicas-to-write + 多数派仲裁。扩展:在线重平衡迁 slot;平滑扩容先加节点再迁数据。
第三层:一致性与并发。CAP 选型:Redis 是 AP 系统,牺牲一致性保可用。并发:单线程模型保证命令原子;Lua 脚本批量原子化;分布式锁用 Redisson。
第四层:网络与安全。网络:epoll I/O 多路复用 + RESP 协议 + 连接池 + Pipeline。安全:ACL 细粒度权限 + TLS + 内网隔离。
第五层:可观测性。监控:QPS、延迟 P99、used_memory、evicted_keys、SLOWLOG;Prometheus + Grafana 告警。
第六层:业务集成。三大问题:穿透用布隆过滤器、击穿用互斥锁、雪崩用 TTL 抖动。多级缓存:本地 Caffeine + Redis + DB。与 DB 一致性:Cache-Aside + 延迟双删 + Canal binlog + TTL 兜底。
实际项目我做过一个电商缓存设计:10w QPS、P99 < 3ms 目标;用 Redis Cluster 6 节点 3 主 3 从;淘汰策略 allkeys-lfu(热点商品长尾);混合持久化;Canal 消费 binlog 保证与 DB 最终一致;本地 Caffeine 5 秒兜底;压测验证临界点。踩过一个坑:早期没做容量规划,大促时内存爆表触发 OOM,后来加了容量告警 + 自动扩缩容。