VOD 深度剖析(七):CDN 分发 —— 为什么它在全球都快

CDN 架构(Edge/Shield/Origin)、缓存策略、请求合并、签名 URL、预热、JIT 与预打包、多 CDN 策略、HTTP/3 以及成本估算。

zhuermu··20 分钟

这是 VOD 流媒体深度剖析 系列的第 7 篇。


为什么视频需要 CDN#

假设你的服务器在上海,而一位美国用户想要观看:

US user ────🌊 Trans-Pacific undersea cable 🌊────► Shanghai server
                  (180ms+ latency)
                  (high packet loss)
                  (limited bandwidth)

10 万名美国用户并发观看,每人 2 Mbps = 200 Gbps 的跨洋流量。无论从技术还是财务上都不可行。

CDN(内容分发网络) 解决了这个问题:

              ┌─── New York edge cache ──► US users (20ms)
Shanghai ───►
origin        └─── Frankfurt edge cache ──► EU users (10ms)

After the first origin fetch, popular videos "live" at global edge nodes

可以把 CDN 想象成一条 全球连锁便利店。总部(源站)在一处集中生产商品,然后分发到每座城市的门店(边缘节点)。用户就近购买 —— 更快也更便宜。


三层架构#

 ┌─────────────────────────────────────────┐
 │            User                         │
 └──────────────┬──────────────────────────┘
                │ ① Request seg_42.m4s

       ┌────────────────────┐
       │ Edge PoP           │   Closest to user, within tens of km
       │ (hundreds globally)│   Caches popular content
       └────────────┬───────┘
                    │ Cache miss → go upstream

       ┌────────────────────┐
       │  Mid-tier / Shield │   Regional aggregation layer
       │  (a few per region)│   Reduces origin load
       └────────────┬───────┘
                    │ Cache miss → origin fetch

       ┌────────────────────┐
       │      Origin        │   Object storage (S3/OSS/COS)
       │                    │   or Packager service (MediaPackage)
       └────────────────────┘

缓存命中率(Cache Hit Ratio) 是 CDN 最重要的指标。目标:> 95%


回源流程#

1. User → Edge: GET /video/seg_42.m4s
2. Edge checks local cache:
   ├── HIT → return immediately ✅
   └── MISS:
       3. Edge → Shield: GET /video/seg_42.m4s
       4. Shield checks cache:
          ├── HIT → return to Edge → Edge caches → return to user
          └── MISS:
              5. Shield → Origin: GET /video/seg_42.m4s
              6. Origin responds → Shield caches → Edge caches → user

第一位用户会触发整条链路(慢)。之后的每位用户都命中边缘缓存(快)。这就是为什么 新上线剧集的第一位观众体验最差 —— 也是预热之所以重要的原因。


缓存策略#

CDN 的缓存行为由 HTTP 头控制:

推荐的 VOD 缓存策略#

文件类型Cache-Control理由
清单文件(.m3u8/.mpd)max-age=60max-age=300可能更新(广告插入、字幕变更)
初始化分片(.mp4)max-age=31536000(1 年)不可变
媒体分片(.m4s/.ts)max-age=31536000(1 年)不可变
字幕(.vtt)max-age=3600(1 小时)可能被修订
缩略图max-age=86400(1 天)可能更新

关键陷阱:如果签名 URL 的参数(?token=xxx)被纳入缓存键,那么 每个用户都会得到一个唯一的缓存条目,命中率会跌到零。务必将签名参数从缓存键中排除。


请求合并(Request Collapsing)#

当 100 个用户同时请求 seg_42.m4s 且全部缓存未命中时:

没有合并:100 个回源请求 → 源站过载。

启用合并(现代 CDN 默认开启):边缘节点识别出这是同一个对象,只发送 1 个回源请求,然后把响应分发给全部 100 个用户。

在上线活动和新剧首播时,这是救命稻草。


签名 URL 与防盗链#

CDN 的分片 URL 是公开的。有人可能把它们嵌入自己的网站免费白嫖。签名 URL 可以防止这一点:

https://d1234.cloudfront.net/video/seg_42.m4s
  ?Expires=1715084800
  &Signature=nitfHRCrtziwO2HwPf...
  &Key-Pair-Id=APKAEIBAERJR2EXAMPLE

CDN 边缘节点会校验:是否已过期?签名是否正确?参数是否被篡改?校验失败 → 403 Forbidden。

其他防盗链手段:Referer 白名单、User-Agent 检查、IP 地域限制、限流,以及 签名 Cookie(在需要加载大量分片时比签名 URL 更方便)。


预热(Pre-Warming)#

新剧上线时,所有分片都是 冷的(尚未进入边缘缓存)。首波用户全部未命中 → 体验糟糕。

预热:在 CMS 发布之后,主动把内容推送到边缘节点:

CMS publish hook → CDN prewarm API
  ├── POST /prewarm { urls: ["…/seg_0001.m4s", ..., "…/seg_0010.m4s"] }
  └── CDN dispatches edge nodes to origin-fetch

Minutes later: global edges have the segments
First-wave users hit cache ✅

不要预热每一个分片 —— 重点关注:初始化分片、前 5–10 个媒体分片,以及这些分片对应的所有清晰度档位。


JIT 打包 vs 预打包#

预打包(离线)#

在转码之后生成所有 HLS/DASH/CMAF 清单和分片 → 存入 S3 → CDN 直接提供。

优点:简单,缓存命中率最高。缺点:存储成本更高(多种格式的多份拷贝),不够灵活(加一条字幕就得重新打包)。

JIT 打包(Just-in-Time,即时打包)#

S3 只存储源 fMP4。当用户请求清单时,源站服务实时生成。

优点:只存一份,灵活(无需重新打包即可添加 DRM 或字幕)。缺点:首次命中较慢(消耗源站 CPU),源站必须扛住负载。

代表性实现:AWS MediaPackage-VOD、Unified Origin、开源的 mp4box。

建议:小体量片库 + 高流量 → 预打包。大体量片库 + 长尾内容 → JIT 打包。


多 CDN 策略#

为什么单个 CDN 不够用:

  • 单点故障:CDN 挂了,你也就黑屏了
  • 地理覆盖:没有任何一家 CDN 在所有地区都是最好的
  • 议价能力:多家厂商为你的业务相互竞争
  • 性能:随时把流量路由到当下最快的那家

路由方式#

基于 DNS:70% 流量到 CloudFront,20% 到 Cloudflare,10% 到区域性 CDN。

客户端探测:App 在启动时 ping 所有 CDN,选出最快的一家;每 5 分钟重新探测一次。

托管调度:Cedexis、Conviva Traffic Steering、Route 53 基于延迟的路由。

故障转移#

播放器逻辑:如果 CDN A 连续失败 3 次 → 切换到 CDN B → 上报告警。


HTTP/2、HTTP/3 与 QUIC#

协议对视频的关键收益
HTTP/1.1基准。队头阻塞(Head-of-line blocking)是主要瓶颈。
HTTP/2多路复用:单条 TCP 连接上并发请求。对下载多个分片是重大改进。
HTTP/3 / QUIC基于 UDP。消除了 TCP 队头阻塞。0-RTT 重连。在弱网/高丢包的移动网络上带来显著提升。

所有主流 CDN(CloudFront、Cloudflare、Akamai)都支持 HTTP/3。启用它可以改善启动时间和重缓冲率,在蜂窝网络上尤为明显。


成本估算#

典型带宽定价(批量折扣后)#

地区$/GB
北美 / 欧洲$0.005–$0.010
拉丁美洲$0.020–$0.050
中东$0.050–$0.080
亚太 / 印度$0.015–$0.040

快速估算#

Assumptions:
  DAU = 1 million
  Average watch time = 30 min/day
  Average bitrate = 1.2 Mbps (720p H.264)

Per-user daily traffic = 1.2 Mbps × 1800s ÷ 8 ≈ 270 MB
Daily total = 1M × 270 MB = 270 TB
Monthly total = 270 TB × 30 = 8.1 PB

At $0.02/GB (weighted average):
  Monthly CDN cost ≈ 8.1 PB × 1000 × $0.02 = $162,000

降本手段#

  1. 更优的编解码器:HEVC 相比 H.264 节省 37%;AV1 再省 20–30% → 直接压缩账单
  2. 逐标题编码(Per-title encoding):为每个标题定制码率阶梯,节省 10–20%
  3. 降低默认档位:移动端默认 720p(相比 1080p 节省 40%)
  4. 多 CDN 竞价
  5. 批量折扣:> 1 PB/月 可解锁可观的折扣档位
  6. 自建 CDN:Netflix Open Connect 把服务器直接部署在 ISP 数据中心内

关键要点#

  1. CDN = 把内容缓存到离用户最近的「便利店」里。
  2. 三层架构:Edge → Shield → Origin
  3. 缓存命中率 > 95% 是目标。把签名参数排除在缓存键之外。
  4. 对新内容预热,避免首波冷未命中。
  5. JIT 打包 节省存储;预打包 更简单。
  6. 多 CDN 提升韧性、覆盖范围和议价能力。
  7. HTTP/3 显著改善弱网性能。
  8. CDN 带宽是 VOD 的主要成本大头:编解码器效率 + 档位设计 + 多 CDN 竞价 是三个最大的杠杆。

上一篇: 第 6 篇:自适应码率流媒体

下一篇: 第 8 篇:DRM 内容保护

参考资料

  1. Amazon CloudFront Developer Guide — AWS Documentation
  2. Amazon S3 User Guide — AWS Documentation

常见问题

视频网站为什么一定要用 CDN?
单一源站扛不住视频流量:10 万人并发、每人 2 Mbps 就是 200 Gbps 的跨洋带宽,远端用户延迟还高达 180ms 以上,技术和成本上都不可行。CDN 把热门内容缓存到全球数百个边缘节点,首次回源之后,用户就近从缓存下载分片,延迟只有几十毫秒。最核心的指标是缓存命中率,目标应高于 95%。
HLS 的分片和 m3u8 清单应该设置多长的 CDN 缓存时间?
媒体分片和初始化分片是不可变的,可以缓存一年(max-age=31536000);清单文件(.m3u8/.mpd)可能因广告插入、字幕变更而更新,建议 max-age=60 到 300;字幕缓存约 1 小时,缩略图约 1 天。特别注意:签名 URL 的参数(如 ?token=)必须从缓存键中排除,否则每个用户都是独立缓存条目,命中率会直接跌到零。
JIT 打包和预打包该怎么选?
预打包是转码后一次性生成所有 HLS/DASH/CMAF 清单和分片存入对象存储,简单且缓存命中率最高,但多份格式拷贝费存储,加条字幕就要重新打包。JIT(即时打包)只存一份源 fMP4,用户请求时由源站实时生成清单,灵活省存储,但首次命中较慢、源站要扛住负载。经验法则:小片库高流量选预打包,大片库长尾内容选 JIT。
分享这篇文章 微博 X LinkedIn
微信扫码

用微信扫一扫,把文章带到聊天或朋友圈。

讨论

用 GitHub 账号评论 —— 评论存放在本仓库的 Discussions 里。

继续阅读