Files
examination/topics/architecture/cache-system/cache-architecture/short_answer.json
T
2026-09-05 12:03:21 +08:00

236 lines
15 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"topic": "cache-architecture",
"type": "short_answer",
"schema_version": "1.0.0",
"generated": "09-2026-09-05T00:00:00+08:00",
"questions": [
{
"id": "sa-001",
"type": "short_answer",
"difficulty": 2,
"tags": [
"单机缓存"
],
"question": "简述判断单机环境是否需要引入 Redis 的'判断三问',并说明每问回答'是'意味着什么。",
"answer": "判断三问:①缓存是否需要被多进程/多服务共享?②是否依赖 Redis 某项能力(AOF 持久化、分布式锁、原子计数 INCR、榜单 ZSET、PubSub 等)?③数据量是否大得本地进程内内存扛不住、或将来必然扩展为多机集群?只要任一回答'是',就应当引入 Redis;只有当三问全部为'否'时,进程内本地缓存(如 Caffeine)才足够。",
"keywords": [
"多进程共享",
"Redis能力",
"数据量",
"本地缓存",
"Caffeine"
],
"scoring_rubric": "答出三问各得 20 分(共 60 分);正确说明三问全否才选本地缓存得 20 分;能指出'单机≠单进程'这一易错点得 20 分。",
"explanation": "决定是否用 Redis 的核心是缓存是否需要被多进程/多能力共享,而不是机器是否单机。三问中任一命中就说明需要 Redis 的跨进程共享或特性能力;全否则本地缓存足够,加 Redis 反而引入网络与一致性麻烦。",
"source": null,
"related": []
},
{
"id": "sa-002",
"type": "short_answer",
"difficulty": 3,
"tags": [
"Write-Behind",
"回写式缓存"
],
"question": "请说明 Write-Behind(回写式/懒更新缓存)架构的运作方式,以及使用它需要注意哪几类代价或边界。",
"answer": "运作方式:客户端完全不直连 DB,统一读写缓存层;写操作只更新缓存并返回,由缓存层异步批量把写入同步回 DB(Read-Through + Write-Behind)。注意事项:①不丢写——缓存必须开启持久化(AOF)并配套兜底日志/队列,绝不可把缓存当唯一真源;②不乱序——批量落库需带时间戳/版本号防止旧覆盖新;③外部读到旧值——直查 DB 的外部/报表系统会看到滞后数据,因此只适合内部读、可容忍一致的数据,而交易/余额/库存等强一致数据绝不可进入该链路。",
"keywords": [
"异步落库",
"持久化",
"AOF",
"版本号",
"旧值",
"强一致"
],
"scoring_rubric": "正确描述异步落库机制得 30 分;说出缓存需持久化兜底不丢写得 25 分;说出版本号/时间戳防乱序得 20 分;指出外部读旧值风险并排除强一致数据得 25 分。",
"explanation": "Write-Behind 的优势是写异步化、可批量合并、降低 DB 写压力;代价是丢写风险、乱序风险和读滞后。本题考察对整个架构边界(可靠性、一致性、适用数据)的把握,是必考点。",
"source": null,
"related": []
},
{
"id": "sa-003",
"type": "short_answer",
"difficulty": 3,
"tags": [
"多级缓存"
],
"question": "多级缓存(L1 本地 + L2 Redis)副本不一致是核心难点,请给出至少三种缓解不一致的治理手段。",
"answer": "①本地缓存设置短 TTL + 逻辑过期兜底——即使没收到失效通知,本地数据也会在较短时间内自然过期回源,缩小不一致窗口;②主动失效 + 广播——写入时通过 MQ 发送失效事件,通知所有节点清除本地缓存副本;③版本号/时间戳判定过期——缓存项携带版本号或写入时间戳,读时对比 L2 判定本地副本是否已过期。",
"keywords": [
"短TTL",
"逻辑过期",
"广播",
"MQ",
"版本号",
"失效"
],
"scoring_rubric": "每种治理手段计约 33 分(共约 100 分)。答出短 TTL/逻辑过期得 33 分;答出 MQ 广播主动失效得 33 分;答出版本号/时间戳判过期得 34 分。",
"explanation": "多级缓存的根本矛盾是同一数据多个副本。思路分两条线:缩短过期窗口(短 TTL + 逻辑过期),和主动同步失效(广播 + 版本判定)。三者属于缓存一致性的经典治理手段。",
"source": null,
"related": []
},
{
"id": "sa-004",
"type": "short_answer",
"difficulty": 2,
"tags": [
"Caffeine",
"TinyLFU",
"多级缓存"
],
"question": "对比 Caffeine 与 Redis 两种缓存组件,说明各自适用场景,在多级缓存中各自适合承担哪一层。",
"answer": "Caffeine 是进程内 JVM 内存、TinyLFU 淘汰、纳秒级无网络单机访问,适合做 L1 极热/高访问层;但重启即失、无法跨进程共享。Redis 是独立进程、可跨机器,毫秒网络 I/O、支持持久化、分布式锁/原子计数/榜单/PubSub,适合做 L2 共享与兜底层。多级缓存中 Caffeine 放 L1 承接极端热点、Redis 放 L2 跨进程共享,两者组合兼顾极热性能与一致性。",
"keywords": [
"Caffeine",
"TinyLFU",
"L1",
"Redis",
"L2",
"多级缓存"
],
"scoring_rubric": "Caffeine 特点与 L1 定位各得 20 分;Redis 特点与 L2 定位各得 20 分;正确说明二者组合成多级缓存得 20 分。",
"explanation": "两者的本质差异是'进程内内存' vs '独立共享服务'。多级缓存正是发挥二者长处:L1 用 Caffeine 承接极热访问减网络开销,L2 用 Redis 保证跨进程一致与可靠性。",
"source": null,
"related": []
},
{
"id": "sa-005",
"type": "short_answer",
"difficulty": 4,
"tags": [
"缓存降级",
"限流",
"熔断"
],
"question": "在缓存架构的可靠性设计中,请说明限流、熔断、降级三种手段各自的职责,以及它们如何共同保护 DB 和后端服务。",
"answer": "限流:限制单位时间回源/请求的数量,防止突发流量瞬间打满 DB 连接或线程池;熔断:当后端(DB/缓存)连续失败达到阈值时快速失败而非继续请求,让其有喘息恢复时间;降级:当 Redis 等组件不可用时,返回兜底数据(如本地缓存副本、默认值、静态页)而不是无限回源。三者配合:Redis 抖动时先本地兜底降级 + 限流控制回源 + 熔断保护 DB,避免全量打爆后端。",
"keywords": [
"限流",
"熔断",
"降级",
"兜底",
"保护DB"
],
"scoring_rubric": "正确说明限流职责得 25 分;熔断职责得 25 分;降级兜底职责得 30 分;能整合说明三者协作保护 DB 得 20 分。",
"explanation": "可靠性设计不止是缓存本身高可用,更重要的是对下游的保护。限流控制流量、熔断快速失败、降级提供兜底,三者共同避免缓存故障演变为 DB 过载故障。",
"source": null,
"related": []
},
{
"id": "sa-006",
"type": "short_answer",
"difficulty": 3,
"tags": [
"Redis持久化",
"RDB",
"AOF"
],
"question": "请对比 Redis 的 RDB 快照与 AOF 日志两种持久化方式,说明各自在数据安全性与恢复方式上的特点,并给出选型建议。",
"answer": "RDB 按周期把内存数据整份快照序列化落盘,文件紧凑、恢复快,但两次快照之间的写入可能丢失,安全性较弱。AOF 记录每次写命令的追加日志,可重放到最近状态,数据更安全,但文件较大、在重写(bgrewriteaof)影响恢复速度/性能。选型:若对安全性要求高(如缓存作为准真源、写后异步落库)选 AOF 或两者同时开启、仅接受少量丢失选 RDB;一般高要求生产推荐同时开启 AOF 以保数据。",
"keywords": [
"RDB",
"AOF",
"快照",
"重放",
"持久化",
"选型"
],
"scoring_rubric": "正确说明 RDB 快照特点与丢失窗口得 30 分;正确说明 AOF 追加日志与重放得 30 分;给出符合场景的选型建议得 40 分。",
"explanation": "RDB 是周期性快照(紧凑、恢复快、可能丢最后窗口数据),AOF 是命令日志(数据更安全、可重放)。持久化选型属于缓存组件选型的核心点,尤其结合 Write-Behind 的落库需求更强调 AOF。",
"source": null,
"related": []
},
{
"id": "sa-007",
"type": "short_answer",
"difficulty": 2,
"tags": [
"单机缓存",
"多进程共享"
],
"question": "为什么说'单机'不等于'单进程',并基于此说明一台单机部署在手机多进程时为何仍需 Redis。",
"answer": "'单机'描述的是部署物理维度(一台机器),而'单进程'描述的是运行进程维度(应用进程个数)。决定是否需要 Redis 的是缓存是否被多进程/多能力共享:即使在同一台机器上运行多个业务进程,每个进程持本地副本会各自维护一份缓存而产生数据不一致;此时仍需要引入 Redis 作为跨进程的共享缓存层,保证所有进程读到同一份数据。因此'单机用本地缓存即可'的常见误判,本质是把'单机'误当成了'单进程'。",
"keywords": [
"单机",
"单进程",
"多进程",
"共享",
"不一致"
],
"scoring_rubric": "正确解释单机与单进程的维度区别得 40 分;指出多进程各自持副本不一致得 30 分;正确结论是仍需 Redis 做共享层得 30 分。",
"explanation": "该题是缓存选型中最常见的误判点。判断依据是'缓存是否需要被共享',与机器台数无关。只要多进程共享就需 Redis。",
"source": null,
"related": []
},
{
"id": "sa-008",
"type": "short_answer",
"difficulty": 4,
"tags": [
"哨兵",
"Redis Cluster"
],
"question": "区分哨兵(Sentinel)与 Redis Cluster 在体系结构中的职责,并说明二者是否可以同时使用及其各自解决的问题。",
"answer": "哨兵负责高可用:部署在主从复制之上,监控主从状态,在主库故障时自动发起投票并提升上手从库为主库,实现自动接管,不负责数据分片;Redis Cluster 负责横向扩展:按 hash slot(16384 个槽)把键分布到多个分片节点,支持大容量与更高吞吐,具有分片能力。两者职责不同可同时使用——在 Cluster 之上叠加基于哨兵的监控/运维切换,或对不同的独立 Redis 实例分别用哨兵保障。哨兵解决'主库挂了怎么办',Cluster 解决'单实例容量/吞吐不够怎么扩展'。",
"keywords": [
"哨兵",
"Sentinel",
"集群",
"Cluster",
"分片",
"自动切换"
],
"scoring_rubric": "正确说明哨兵负责故障检测与自动切换得 35 分;正确说明 Cluster 负责分片/横向扩容得 35 分;说明两个职责互补、可同时使用得 30 分。",
"explanation": "这是选型中易混淆的一对:哨兵是'高可用'组件(故障切换),Cluster 是'分片扩展'组件(横向扩容)。职责不同,可搭配使用。",
"source": null,
"related": []
},
{
"id": "sa-009",
"type": "short_answer",
"difficulty": 3,
"tags": [
"Write-Behind",
"回写式缓存"
],
"question": "Write-Behind 架构中,为什么'绝不能把缓存当作唯一真源'?请从一两个典型故障说明后果与应采取的兜底措施。",
"answer": "因为 Write-Behind 下数据先写缓存、异步落库,若缓存作为唯一真源而该缓存未持久化或崩溃,则尚未同步到 DB 的写入会直接丢失;同时如果只有一套副本,一旦重启清空则无法恢复任何待落库数据。典型故障:缓存进程崩溃且未开 AOF,队列中积压的上万笔写入全部丢失;或落库逻辑持续失败导致缓存与 DB 长期分歧。兜底措施:缓存开启持久化(AOF)+ 独立的可靠的落库日志/消息队列兜底,保证每比写入都被可靠记录并可重放;配合版本号防乱序、System对账重试。",
"keywords": [
"丢写",
"崩溃",
"持久化",
"AOF",
"消息队列",
"兜底"
],
"scoring_rubric": "指出缓存作为唯一真源会有崩溃丢写风险得 30 分;给出具体的故障场景(崩溃/清空/重放)得 30 分;提出持久化 + 队列兜底/对账措施得 40 分。",
"explanation": "Write-Behind 的可靠性核心是不把缓存当唯一真相源:必须要有持久化 + 兜底队列,把写入先可靠记下来再异步同步,避免缓存崩溃丢真源。",
"source": null,
"related": []
},
{
"id": "sa-010",
"type": "short_answer",
"difficulty": 5,
"tags": [
"多级缓存",
"Caffeine"
],
"question": "设计一个多级缓存的一致性读写如何做具体过程:热点数据写入时,如何保证 L1 本地、L2 Redis 与 DB 三方的新旧一致?",
"answer": "可采用的完整流程:写时先更新 DB,写成功后向 L2 Redis 写新值并发出失效事件/版本号;通过 MQ 把版本号/失效通知直接发给所有节点的 L1 本地缓存,各节点收到后删除对应本地 key(主动失效);本地 key 同时设置短 TTL + 逻辑过期作为兜底,即使广播丢失也会在短 TTL / 逻辑过期时触发校验回源,读时携带版本号判断过期;对外暴露时返回已确认一致的值。排列组合:更新 DB → 更新或失效 Redis → 广播失效本地 → 本地短 TTL 逻辑过期兜底 + 版本号判定,最终保证 DB 为真源、L2 与 L1 为可作废副本,缩短不一致窗口。",
"keywords": [
"RIO广播",
"失效",
"短TTL",
"版本号",
"DB真源"
],
"scoring_rubric": "答出 DB 为真源、写库先行得 20 分;答出 L2 更新/失效再加版本号得 20 分;答出 MQ 广播失效各节点 L1 得 25 分;答出短 TTL + 逻辑过期兜底得 15 分;答出版本号校验过期得 20 分。",
"explanation": "多级缓存一致性的核心是“DB 真源 + 主动失效 + 过期兜底”。题目考察对读写路径和一致性窗口最小化的全套设计理解,属于本子主题较难的综合题。",
"source": null,
"related": []
}
]
}