读书笔记 · 约 11,540 字 · 预计推送 2 部分

计算机系统中的缓存:CPU、文件系统、数据库、HTTP、LLM prompt cache 的共同规律 :: 跨层总结 未开始

目录

题记与说明


一、核心问题

存储与计算之间、节点与节点之间的速度差是跨数量级的:CPU 快于内存约两个数量级,内存快于磁盘若干数量级,源站处理快于网络往返,LLM 重复 prefill 相同前缀是纯浪费。缓存要解决的问题是:如何用一层"小而快"的存储挡在"大而慢"的存储(或重复计算)前面,吸收大部分重复访问。 本笔记进一步追问:CPU 缓存、OS page cache、数据库 buffer pool、HTTP 缓存、LLM prompt cache 这五个看起来毫不相干的层,是否共享同一组设计变量与规律?

二、主要主张

五层缓存共享同一组设计变量——层级位置、缓存键、准入策略、写策略、失效机制、TTL——差异只在参数取值,不在原理。 具体展开为十条共同规律(见第四节),其中最核心的三条:

  1. 局部性是燃料:没有时间局部性(重复访问)与空间局部性(成块访问),缓存收益归零。
  2. 失效一致性没有免费午餐:五层全都放弃了强一致,改用"TTL + 验证 + 不可变化"的组合来逼近正确性。
  3. 应用越靠近缓存,越要求应用主动配合设计:从 CPU 的透明自动缓存,到 prompt cache 要求把静态内容前置——"让缓存命中"正在从硬件问题变成 prompt 工程问题。

三、方法

  1. 来源选择:每个抽象层选一个权威来源——CPU 层用 Wikipedia「Cache hierarchy」(底层数据引 Hennessy & Patterson 教材)、文件系统层用 Wikipedia「Page cache」(引 Linux 内核开发权威著作)、数据库层用 MySQL 官方手册、HTTP 层用 MDN(对应 RFC 9111)、LLM 层用 Anthropic 官方文档。
  2. 对齐维度:对每一层统一提取六个变量——缓存位于哪两层之间(层级)、如何判断"是同一条数据"(缓存键)、什么内容允许进入(准入/粒度)、写如何处理(写策略)、何时作废(失效机制)、收益如何度量(命中模型)。
  3. 跨层归纳:将五层的同名机制横向并置,提炼参数之外的共同规律;对无法从本次来源证实的内容明确标注"基于已有知识"。

四、数据与证据(逐层精读 + 原文引述)

4.1 CPU 缓存(L1/L2/L3)

"In the history of computer and electronic chip development, there was a period when increases in CPU speed outpaced the improvements in memory access speed. … This issue motivated the creation of memory models with higher access rates in order to realize the potential of faster processors." —— Cache hierarchy - Wikipedia
"Benefits may be minimized or eliminated in the case of large programs with poor temporal locality, which frequently access the main memory."

4.2 文件系统缓存(OS page cache)

"a page cache, sometimes also called disk cache, is a transparent cache for the pages originating from a secondary storage device such as a hard disk drive (HDD) or a solid-state drive (SSD). The operating system keeps a page cache in otherwise unused portions of the main memory (RAM)… and is mostly transparent to applications." —— Page cache - Wikipedia
"In 2019, security researchers demonstrated side-channel attacks against the page cache: it's possible to bypass privilege separation and exfiltrate data about other processes by systematically monitoring whether some file pages … are present in the cache or not."(Gruss et al., *Page Cache Attacks*, arXiv:1901.01161)

4.3 数据库缓存(InnoDB Buffer Pool)

"The buffer pool permits frequently used data to be accessed directly from memory, which speeds up processing. On dedicated servers, up to 80% of physical memory is often assigned to the buffer pool." / "The larger the buffer pool, the more InnoDB acts like an in-memory database." —— MySQL 8.0 手册 §17.5.1
"A table scan, performed for a mysqldump operation or a SELECT statement with no WHERE clause, for example, can bring a large amount of data into the buffer pool and evict an equivalent amount of older data, even if the new data is never used again."

对策:新页默认插入链表中点(默认 3/8 给 old 子链表),只有被再次访问才"变年轻"升入 new 子链表——一次性扫描的数据没资格挤掉热点页。准入控制(admission control)是 LRU 的必要补丁,五层里 DB 层把它做成了默认行为。

4.4 HTTP 缓存(浏览器/代理/CDN)

"First, since there is no need to deliver the request to the origin server, then the closer the client and cache are, the faster the response will be. Also, when a response is reusable, the origin server does not need to process the request… That reduces the load on the server. Proper operation of the cache is critical to the health of the system." —— HTTP caching - MDN
"There is no way to delete responses on an intermediate server that have been stored with a long max-age." / "Caching reduces access to the server, which means that the server loses control of that URL."

对策不是"删除",而是三种替代:① 条件请求验证(If-None-Match/ETag、If-Modified-Since → 304 Not Modified,把失效从"推送失效"改成"拉取验证");② cache busting("changing the URL each time the content changes",用版本化文件名 bundle.v123.js 把可变资源变成不可变资源——改键不改值);③ managed cache 的主动 purge API(CDN 面板/接口删除,逃出协议限制)。

4.5 LLM prompt cache(Anthropic Claude)

"The system checks if a prompt prefix, up to a specified cache breakpoint, is already cached from a recent query. If found, it uses the cached version, reducing processing time and costs." —— Prompt caching - Anthropic Docs
"Cache hits require 100% identical prompt segments, including all text and images up to and including the block marked with cache control." / "Caches are isolated between organizations."
"Changes at each level invalidate that level and all subsequent levels."

官方给出完整失效矩阵:改工具定义 → 全失效;开/关 web search、citations(动 system)→ system+messages 失效;改 tool_choice、插图片、改 thinking 参数 → 仅 messages 失效。这与文件路径前缀失效、HTTP 的 URL 键完全同构——失效沿前缀树向下传播。

五、结论:跨层共同规律(十条)

#共同规律CPUpage cachebuffer poolHTTPprompt cache
1层级化:缓存永远夹在两个速度差数量级的存储/计算层之间L1-L2-L3-DRAMRAM↔磁盘内存↔磁盘页浏览器-CDN-源站KV 前缀↔重复 prefill
2局部性是燃料:时间局部性决定 TTL/LRU 收益,空间局部性决定块粒度cache linepage16KB page整响应token 前缀
3命中是指数杠杆:AAT = hit + miss×penalty,命中率小幅提升 → 平均延迟大幅下降50ns→1.51ns—hit rate 1000/1000 可观测304 只传头读价 10%
4缓存键=内容身份:键必须精确判定"同一条数据";键里塞高基数变量会杀死命中率地址 tag(inode, offset)(tablespace, page)URL + Vary逐字节相同前缀
5无强一致:五层都选"TTL + 验证 + 不可变化"而非推送失效协议保证脏页回写WAL/checkpointETag 304 + cache busting前缀级联失效表
6写比读贵:进缓存要付溢价,命中才打折write-back 脏位成本dirty page 刷盘flush 开销源站写入后才能缓存写 +25%~100%,读 −90%
7准入控制必要:一次性扫描不得冲刷热点页nontemporal hints(基于已有知识)—中点插入 LRU(默认)—多断点分层 TTL(1h+5m)
8透明性光谱:越靠上层,越要求应用主动配合缓存设计硬件透明对应用透明SQL 透明、需调参需显式 header需重排 prompt 结构
9不可变性是缓存之友:把可变的东西变成不可变的键,失效问题消失一半—只读页共享—cache busting + immutable静态前缀前置
10缓存是攻击面与竞争点:命中与否泄露信息、被争抢、被合并侧信道/分区Page Cache Attacks多 instance 分片private 防泄露、request collapse 防击穿组织隔离、并发首响应前全 miss

一句话结论:缓存不是五种技术,而是同一个设计问题在五个速度尺度上的五次实例化;设计新系统的缓存时,答案几乎总能在另一层里找到——你缺的只是把 LRU 改成中点插入、把失效改成 cache busting、把静态内容前置这类"本层方言"。

六、局限

  1. Anthropic 延迟收益数字未在本次精读页面出现:官方营销页常引用"最高 85% 延迟降低",但本次精读的文档页只说 "reducing processing time and costs",未给出具体百分比,故笔记不引用该数字(成本 −90% 有定价表直接支撑)。
  2. 部分跨层对应关系标注为"基于已有知识":如 CPU 的 nontemporal/streaming 访问提示、Phil Karlton "computer science 两大难题"名言的归属、Linux multi-gen LRU 等新算法,本次 5 个来源未覆盖或 Wikipedia 条目较简略。
  3. 来源以文档与百科为主,缺少对账式实测(如 CDN 命中率统计、vLLM/SGLang 自动前缀缓存的 benchmark),LLM 层仅精读了 Anthropic 一家,OpenAI 的自动缓存(50% 折扣档)未核证。
  4. 缓存击穿/雪崩/穿透三件套在 HTTP 层只覆盖了 request collapse,DB 层未展开。
  5. Wikipedia 条目存在少量 [citation needed] 标记(inclusive/exclusive 策略部分),引用时已避开依赖这些句子的结论。

七、对我的启发

  1. Prompt 排序即缓存优化:写 system prompt 时把工具定义、长文档、few-shot 例子全部前置并用 cache_control 断点收口,动态内容放最后——这是 prompt 工程里的"局部性优化",命中部分直接打 1 折;长会话 agent 场景付 2 倍写溢价上 1 小时 TTL 是划算的(读价只有 10%)。
  2. 失效优先选"改键"而非"删值":HTTP 层 40 年的教训——中间缓存的值删不掉,所以发明了 cache busting。做应用缓存(如构建产物、API 响应)时优先用版本化键 + 长 TTL,而不是绞尽脑汁做主动失效。
  3. 给任何 LRU 配准入控制:一次性批量任务(全表导出、全库扫描)会把热点数据冲出缓存,InnoDB 中点插入是现成答案;自研缓存至少要有"新页先进 old 区"的意识。
  4. 把命中率做成一等监控指标:InnoDB 连 youngs/s、脏页数都直接输出;应用缓存如果连 hit rate 都看不到,等于没有缓存。
  5. 不可变内容无限缓存,可变内容永不进长 TTL:跨层通用的二分法——静态资源、append-only 会话前缀走长缓存;用户画像、实时状态走短 TTL + 验证(no-cache + ETag 模式)。
  6. 跨层阅读是设计捷径:以后设计任何"快慢层"结构(包括 agent 的记忆分层:工作记忆/情景记忆/长期知识库),先问一句"CPU/DB/CDN 是怎么解决键、准入、失效、冷启动的",大概率有现成答案。

*精读完成于 2026-11-01,全部 5 个来源为当日在线抓取全文;引述均为原文摘录,链接见文首来源列表。*

← 资料库今日播报 →