7.2 CDN 缓存、回源与流量导向
远方居民下载同一份地图时,源站已经不堪重负;你们要决定哪些副本可以放到离用户更近的边缘节点。
CDN 是分布式 edge platform,caching 是它最常见的能力之一。它可以缩短 user 与 content copy 之间的 network path、减少 origin load,并在 edge 处理 TLS、request routing 和部分 security policy。但这些效果取决于 cacheability、traffic mapping 和 origin design,不是“接入 CDN 就自动快”。
1. 一次 edge request 的基本路径
client
|
| DNS answer / anycast route
v
edge point of presence
|-- fresh cache hit -----------------> response
|-- stale entry -> revalidate origin -> 304 / new response
`-- miss ----------------------------> origin or origin shieldCDN 不一定先“把所有 file 推到全球”。很多 content 在第一次 request 到达 edge 时 pull from origin,后续 request 才命中 cache;大规模 launch 或 video workflow 也可以做 pre-positioning。
2. Cache key 决定“哪些 request 共享一份 response”
Typical key 至少包含 scheme/host/path,query parameter 是否进 key 取决于 configuration。Vary 让 cache 按指定 request field 区分 stored response,例如 content encoding 或 language。
一个 cache key 过窄可能把 user A 的 personalized response 发给 user B;过宽则把每个 tracking query、cookie 或 header 变体分成独立 object,让 hit ratio 降低并放大 storage。
Cache policy 应明确:
- 哪些 method/status 可存;
- shared cache 是否允许存 authenticated/personalized response;
- key 包含哪些 query/header/cookie dimension;
Cache-Control、Expires、ETag与Last-Modified如何处理;- stale response 在 origin error/revalidation 期间能否使用;
- maximum object size 与 negative/error caching policy。
3. Freshness、validation 与 purge 是三件事
Fresh response 可不问 origin 直接复用。Stale response 可用 validator 发 conditional request;origin 返 304 时 cache 更新 metadata 并继续使用 stored content。
Purge/invalidation 是 CDN vendor control plane 能力,不是 HTTP caching 语义保证的全球 instant transaction。Purge 需要传播时间,也可能因 key 与预想不同而没命中 object。
Static asset 通常适合 content-addressed / versioned URL:
/assets/app.4f3a91c2.jsContent 变更就生成新 URL,旧 URL 可设 long freshness lifetime。HTML entry point 用较短 freshness 或 validation,引用新 asset URL。这比每次 release 都要精准 purge 全球旧 object 更容易推理。
4. Miss storm 与 origin shield
一个 popular object 过期时,大量 edge/request 可同时回源,形成 cache stampede。常见缓解方法:
- request collapsing / single flight:同一 key 只让一个 fetch 回源;
- freshness jitter:避免大量 object 同一时刻过期;
- stale-while-revalidate / stale-if-error 策略;
- origin shield:多个 edge 先向一层 shield cache 聚合 miss;
- origin capacity limit 与 circuit breaker。
Shield 是多一跳,它的价值来自 miss aggregation 和 origin protection,不是每个 request 都会 latency 更低。
5. Geo-aware DNS 与 anycast 都不承诺“地理最近”
CDN 可通过 DNS answer 将 recursive resolver/client subnet 映射到某个 edge cluster,也可让多个 site 广播同一 anycast IP,由 BGP route selection 选 path。实际部署常将多种 mechanism 组合。
GeoDNS 看到的常是 recursive resolver address,不一定是 end user address;EDNS Client Subnet 可传递部分 client prefix,但带来 privacy 和 cache fragmentation trade-off。DNS answer 还会在 TTL 内被 cache,不能做 per-request instantaneous load decision。
Anycast 选的是 routing policy 下的 best path,不是 Euclidean distance 最短或 latency 必然最低的 site。BGP 本身也不读 CDN application queue depth。Operator 可通过 route advertisement/withdrawal、community 和 traffic engineering 影响 mapping,但需要另外的 health signal 与 failover design。
6. 观测 cache,不要靠 vendor header 猜品牌
curl -sS -D - -o /dev/null https://www.example.com/assets/app.js关注:
Cache-Control、Expires、ETag、Last-Modified;Age是 response 在 cache 系统中的 current age 信息,不是“命中某 CDN 品牌”的证据;Via、Server-Timing或 vendor-specific cache-status header,其语义应查该 provider 文档;- Response 是
HIT、MISS、BYPASS、STALE还是 revalidated; - Request ID / trace 能否与 origin log 关联。
只从 response header 搜索 cf-、x-cache 之类字符串不能可靠判断“是否使用 CDN”:header 可被删除、修改或由其他 proxy 生成。
7. Cache correctness 与 security
CDN 是 shared intermediary,cache policy error 可放大 data leak。重点检查:
- Authenticated/private response 是否被 shared cache 存储;
- Cache key 是否忽略会改变 response 的 header/cookie/query;
- Untrusted host/header 是否能污染 generated redirect 或 absolute URL;
- Origin 是否只允许受信 CDN 访问,以及如何 authentication edge-to-origin;
- Signed URL/cookie 的 expiry、scope 和 key rotation;
- Compression/range request 与 object size limit 是否可被 abuse。
TLS 在 client-to-edge 终止时,edge 能看见 plaintext,才能做 HTTP caching/routing。Edge-to-origin 是另一条 security boundary,需要自己的 TLS authentication、authorization 和 certificate lifecycle。
8. 验收问题
- 为 versioned JS asset 和 HTML entry point 分别设计 cache policy。
- 为什么
Age不能单独证明 response 来自某个 CDN? - 解释 cache key 过窄与过宽各自的 failure mode。
- 为一个 hot object 的 expiry 设计 request collapse、stale policy 和 origin shield。
- 为什么 anycast 不等于 application-aware load balancing?
下一课进入7.3 负载均衡算法、健康检查与重试边界。