1238 字
约 4 分钟
3
通用架构笔记 · 缓存失效与"改了就更新"的实现

通用架构笔记 · 缓存失效与"改了就更新"的实现

用途:沉淀一条可复用的架构决策——系统用缓存提升性能时,如何正确解决"用户改了输入,结果却不更新"的经典问题。 可迁移到任何有缓存/AI 生成/编辑器的项目。

一、问题定义(先在头脑里框定问题)

症状:用户改了输入(如调整切图/选区),AI 生成的结果或预览仍是旧的。

本质原因:缓存(如 html-preview-cache)把上一次的结果存了下来,但"输入变化 → 缓存失效"这条联动没接全,导致命中了脏数据。这不是崩溃,是静默地显示旧数据——最坑的一类 bug,因为它不报错,极难察觉。

性能的诱惑:AI 生成又慢又贵,不可能每次改动都重调;所以缓存是刚需。真正困难的是**"什么时候该作废"**。

二、方案谱系(由简单到彻底,按需选)

# 方案 做法 代价 适用
手动失效 「重新识别」按钮 + 重启后端 体验差,靠人,容易漏 兜底 / 紧急
内容指纹 (digest) 把输入算成 hash 放进缓存 key,输入变→key 变→自动 miss 极低,一行 hash ★ 大多数场景首选
依赖追踪 (dep graph) 显式记录"结果依赖哪些输入",dep 变→标 stale 依赖复杂、多共享
乐观失效 + 后台重建 改动即作废,后台悄悄重算新稿 中高,后台任务 高频交互编辑器
结果级缓存→请求级去重 缓存"请求本身"而非结果,相同输入→幂等复用 中高 想省模型调用费

三、推荐落地:方案② 内容指纹(digest)

核心思路:把"这次任务的输入"算成一个哈希指纹,作为缓存 key 的一部分。

cacheKey = "preview:" + sha256( 原始截图 + 用户改动后的选区/参数 + 模型/config 版本 )
  • 用户改了切图 → 指纹变 → key 变 → 自动 cache miss,重新生成。
  • 用户没改 → 指纹不变 → 命中旧缓存,又快又不乱调 AI。

关键点——指纹里的"输入"要包含什么:

  • 源数据(截图/文档)
  • 用户所有可改变结果的操作参数(选区、宽高、阈值)
  • 会改变输出的"版本类"信息(用哪个模型、prompt 版本),否则换模型也不会刷新

可迁移配方句:

When 缓存的产物取决于一组输入, use 把输入算成内容指纹放进缓存 key, because 输入一变 key 就变,缓存自动失效,无需手动清。


四、更完整:方案②+④ 组合(推荐用于编辑器类项目)

  1. 改动写入即作废:用户每一步操作都让对应缓存失效(invalidate-on-write),界面立刻反映"这里要重算了"。
  2. 后台重建:不阻塞用户,后台任务悄悄算出新稿,回来覆盖预览;前端可给"识别中…"轻提示。
  3. 请求去重(可叠加⑤):对完全相同的请求幂等,省模型调用费。

五、工程判断 / 反模式提醒

  • 正确心态:当系统用缓存换取性能时,必须把"缓存失效"当作一等需求来设计,而不是事后再打补丁。
  • 反模式:靠"重启服务/手动刷新"兜底 —— 这暴露了失效逻辑没接对;正确做法是让"输入变化→自动失效对应缓存"链路闭环。
  • 过度设计:若依赖不复杂,不要上来就上"依赖图/事件总线",优先用指纹,简单且够用。

六、选型速查(给别人/自己以后快速决策)

要解决的问题:缓存不更新 / 改输入没反应
├─ 输入单一、依赖不复杂 → 方案② 内容指纹(默认首选)
├─ 交互高频、要即时反馈 → 方案②+④ 乐观失效+后台重建
├─ 省模型调用费 → 叠加 方案⑤ 请求去重
└─ 结果被多处、复杂地复用 → 方案③ 依赖追踪
(方案① 手动+重启 只留作紧急兜底)

七、相关笔记/位置

  • 本项目的具体缓存实现位置:html-preview-cache(可到 src/ 内 grep,查看失效逻辑)。
  • 关联通用主题:双线程消息契约AI 输出容错(双解析)大脑-仓库分离
通用架构笔记 · 缓存失效与"改了就更新"的实现
http://clxhxhhr.top/posts/548/
作者
clxstart
发布于
2026-09-08
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。