系统设计:视频流媒体平台
视频平台的复杂度远超「上传一个文件、播放一个文件」:一次上传要经过转码、切片、分发,一次播放要在弱网与高清之间动态权衡,而成本的大头是带宽而非存储。本文按面试节奏逐步拆解。
1. 需求分析
功能性需求
- 上传:分片上传、断点续传、秒传(内容去重)
- 转码:多分辨率多码率、水印、封面抽取
- 播放:多清晰度切换、拖动进度、断线续播
- 互动:弹幕、评论、点赞、投币
- 管理:审核、下架、统计观看时长
非功能性需求
- 起播延迟:低于 1 秒(点播)
- 卡顿率:低于 1%
- 可用性:99.99%,播放链路无单点
- 规模:日活 1 亿,日播放 10 亿次
- 成本:带宽成本可预测、可优化
核心难点
- 转码算力:一源多档,算力需求是上传量的数十倍
- 分发成本:CDN 带宽是最大开销,必须提高命中率
- 弱网体验:用户网络差异巨大,必须自适应码率
2. 容量估算
- 日上传视频:500 万个,平均原始大小 100 MB
- 日新增原始数据:500 万 × 100 MB = 500 TB/天
- 转码后多档合计:约 1.5 倍原始大小 → 750 TB/天
- 日播放 10 亿次,平均单次观看 50 MB → 50 PB/天出口流量
- 若 CDN 命中率 95%,回源流量仅 2.5 PB/天
关键结论:出口带宽按 PB/天计,因此「提高 CDN 缓存命中率」与「降低平均码率」是成本优化的两大杠杆,远比省存储重要。
3. 整体架构
上传端 ──► API 网关 ──► 上传服务 ──► 对象存储(原始文件)
│
▼
转码任务队列(Kafka)
│
▼
转码集群(分片并行 + GPU)
│
┌────────┴────────┐
▼ ▼
切片产物(HLS/DASH) 封面/元数据
│ │
▼ ▼
对象存储(源站) ◄── 元数据服务(MySQL/Redis)
│
▼
CDN 边缘节点
│
▼
播放器(App/Web)
上传路径
客户端分片上传到上传服务,上传服务做内容哈希实现秒传,原始文件落对象存储,随后投递转码任务。
播放路径
播放器请求播放清单(Manifest),CDN 返回切片列表与地址,播放器按当前带宽选择码率拉取切片;CDN 未命中则回源站。
4. 数据模型
视频主表
videos (
video_id BIGINT PRIMARY KEY,
user_id BIGINT,
title VARCHAR(256),
duration_ms INT,
cover_url VARCHAR(512),
source_hash CHAR(64), -- 秒传去重
status TINYINT, -- 上传/转码中/可播/下架
created_at TIMESTAMP
)
转码产物表
video_variants (
variant_id BIGINT PRIMARY KEY,
video_id BIGINT,
resolution VARCHAR(16), -- 360p/720p/1080p
bitrate_kbps INT,
codec VARCHAR(16), -- H.264/H.265/AV1
manifest_url VARCHAR(512), -- m3u8/mpd 地址
segment_cnt INT
)
弹幕表
danmaku (
danmaku_id BIGINT PRIMARY KEY,
video_id BIGINT,
user_id BIGINT,
offset_ms INT, -- 相对视频时间轴
content VARCHAR(128),
mode TINYINT, -- 滚动/顶部/底部
created_at TIMESTAMP
)
5. 转码流水线
为什么必须转码
- 原始文件码率与编码格式五花八门,设备无法直接播放
- 需要在画质与带宽之间提供多档选择
- 需要统一封装为流式协议便于切片与自适应
转码任务拆解
- Demux:解封装,分离音视频轨道
- Decode:解码为原始帧
- Filter:缩放、去噪、加水印
- Encode:按目标码率重新编码(H.264/H.265/AV1)
- Package:切片并生成清单文件
并行加速
- 时间分片并行:把视频按 GOP 切成多段,多台机器并行转码后拼接,几乎线性加速
- 硬件加速:GPU/专用编码卡(NVENC)吞吐是 CPU 的数倍
- 优先级队列:大 UP 主与热门内容优先,长尾内容排队
转码档位设计
| 档位 | 分辨率 | 码率 | 适用网络 |
|---|---|---|---|
| 240p | 426×240 | 300 kbps | 弱网/2G |
| 480p | 854×480 | 1 Mbps | 3G |
| 720p | 1280×720 | 2.5 Mbps | 4G/WiFi |
| 1080p | 1920×1080 | 5 Mbps | 宽带 |
| 4K | 3840×2160 | 15 Mbps | 高速宽带 |
6. 切片与流式协议
HLS 与 DASH 对比
| 维度 | HLS | DASH |
|---|---|---|
| 开发者 | Apple | 标准化组织 |
| 清单格式 | m3u8(文本) | MPD(XML) |
| 兼容性 | iOS 原生支持 | 需 MSE |
| 延迟 | 传统 6-30 秒,低延迟可到 2 秒 | 可更低 |
| 编码 | 多支持 H.264/H.265 | 支持 AV1 等新编码 |
切片策略
- 每片时长 2 到 6 秒,过长导致切换码率迟钝,过短导致请求数暴增
- 关键帧必须对齐切片边界,否则切换码率时会花屏
- 每档码率生成独立切片序列,清单中列出所有档位的地址
清单文件示例
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
360p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720
720p/index.m3u8
7. CDN 分发与回源
分层缓存
- 边缘节点:离用户最近,命中率最高,容量最小
- 中间层:区域汇聚,回源前的一级缓冲
- 源站:对象存储,仅在全部未命中时访问
提高命中率的手段
- 热点预热:新发布视频主动推送到边缘
- 长尾合并:冷门视频用更大缓存粒度,减少回源次数
- 一致性哈希:同一视频固定路由到同一节点,避免缓存碎片
- 智能回源:合并回源请求(回源聚合),降低源站压力
CDN 边缘缓存的失效与回源策略,与 分布式缓存设计 的缓存穿透、击穿问题本质相同;首页推荐流的分发则可参考 信息流系统设计。
成本优化
| 手段 | 效果 | 代价 |
|---|---|---|
| 提高 CDN 命中率 | 直接降低回源带宽 | 需要更大边缘容量 |
| 使用 H.265/AV1 | 同画质码率降 30% 到 50% | 编码与解码算力上升 |
| 多档码率覆盖 | 弱网用户自动降档 | 转码存储增加 |
| P2P 辅助分发 | 热门内容省带宽 | 实现复杂、依赖客户端 |
8. 播放器与自适应码率
ABR 自适应码率
播放器持续测量下载速度与缓冲区水位,动态选择下一片码率:
def select_bitrate(throughput_kbps, buffer_sec, variants):
# 缓冲区充足时更激进,紧张时保守
margin = 1.5 if buffer_sec > 10 else 0.8
target = throughput_kbps * margin
candidates = [v for v in variants if v.bitrate_kbps <= target]
return max(candidates, key=lambda v: v.bitrate_kbps) if candidates else variants[0]
常见算法:基于吞吐量(Throughput)、基于缓冲区(Buffer-based,如 BOLA)、以及两者混合。核心目标是既不卡顿、又不浪费码率。
起播优化
- 预加载首片、预连接 CDN 域名(DNS/TCP/TLS 预热)
- 首片用低码率,缓冲稳定后再升档
- 播放器缓存清单,减少首帧前的往返
断线续播与拖动
- 播放进度上报服务端,换设备可续播
- 拖动到未缓冲区间时优先拉取目标位置的关键帧切片
9. 弹幕与互动
弹幕的写入与读取
- 写:弹幕按视频时间轴写入,量级大但单条小,用分片表 + 时间索引
- 读:播放器按当前时间窗口拉取(如当前秒前后 5 秒),做本地渲染
- 热点保护:超热门视频的弹幕做采样与去重,避免刷屏
弹幕一致性
弹幕容忍最终一致,可用消息队列异步落库 + 内存缓存加速读取。与 IM 的实时性要求不同,弹幕延迟一两秒用户无感。
互动数据
点赞、投币、收藏走独立的计数服务,用 Redis 计数 + 异步落库,防止高频写打爆数据库。
10. 面试常见问题
Q: 转码为什么这么贵,怎么优化?
贵在解码与编码的算力。优化路径:时间分片并行缩短墙钟时间、GPU 硬件编码提升吞吐、按热度分级只转必要档位、用更高效的编码标准降低后续带宽。
Q: 为什么用 HLS 而不是直接传 MP4?
MP4 是整文件下载播放,无法中途切换码率、无法快速起播。HLS/DASH 切片后可按需拉取、动态切档,且天然适配 CDN 缓存。
Q: CDN 回源流量怎么降下来?
提高边缘命中率(预热、一致性哈希、合并回源)、降低码率(新编码)、把冷门内容缓存粒度调大,最后才是加缓存节点。
Q: 弱网下如何保证不卡顿?
ABR 快速降档到低码率保连续播放,宁可清晰度低也不卡顿;同时扩大缓冲水位、预取后续切片。
Q: 弹幕量极大时怎么扛?
写入侧限流 + 采样,读取侧按时间窗口拉取并本地渲染;热门视频可对弹幕做聚合展示。
Q: 存储成本怎么估?
原始 + 多档转码约 2.5 倍原始大小,冷门视频可降档或转冷存储;但真正的大头是带宽,估成本时要先算出口流量再算存储。
Q: 秒传怎么实现?
客户端计算文件内容哈希,服务端若已存在相同哈希则直接建立引用,不重复上传与转码。
总结
视频流媒体平台的答题主线是上传—转码—分发—播放四段流水线:上传侧做分片与秒传,转码侧做并行与多档,分发侧靠 CDN 命中率与缓存分层,播放侧靠 ABR 自适应。所有设计最终都要落到两个数字上——带宽成本与卡顿率,能把这两者的 trade-off 讲清楚,再补上弹幕与审核的边界处理,这道题就稳了。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。