视频平台系统设计
视频平台案例究竟包含哪些功能?
- 核心功能: 上传视频、播放和分享,按标题或标签搜索,并允许发表评论;
- 质量目标: 上传内容不丢失,播放低延迟且高可用,系统能扩展;
- 扩展需求: 按地区限制内容、断点续播及指标分析;
- 题设边界: 原文题名为 Netflix,但混合了用户上传和评论等 YouTube 式功能,本文按通用视频平台处理;
- 阅读方式: 保留端到端媒体链路,案例可超过普通笔记行数限制,避免将上传与播放之间的关键关系拆散;
怎样估算上传与播放规模?
- 假设: 10 亿总用户,2 亿 DAU,每人每天看 5 个视频;播放与上传比 200:1,每个上传视频平均 100 MB;
| 项目 | 计算 | 结果 |
|---|---|---|
| 播放次数 | 2 亿 × 5 | 10 亿/日 |
| 平均播放开始 | 10 亿 / 86400 | 11574/s,约 12K/s |
| 上传数量 | 10 亿 / 200 | 500 万/日 |
| 平均上传开始 | 500 万 / 86400 | 57.87/s |
| 原始视频新增 | 500 万 × 100 MB | 500 TB/日 |
| 十年原件 | 500 TB × 3650 | 1825 PB |
| 平均上传入口 | 500 TB / 86400 | 5.79 GB/s |
- 方向修正: 原文 5.8 GB/s 是入口,不能代表播放出站带宽;若每次完整看完 100 MB,出站约 100 PB/日,即 1.16 TB/s;
- 播放负载: 每次播放又包含清单、多个片段和重试请求,播放开始 RPS 不等于媒体 HTTP 请求 RPS;
- 真实容量: 原件、多个码率与编码版本、缩略图、字幕及副本都会增加存储,需要按保留规则另算;
- 并发估算: 同时播放数还取决于平均观看时长,不能从 DAU 直接得到连接峰值;
视频元数据与观看记录怎样建模?
| 表 | 关键字段 | 作用 |
|---|---|---|
| users | id、name、email、dob、location、createdAt | 用户资料 |
| videos | id、userID、title、description、thumbnailURL、streamURL、uploadedAt | 视频信息与媒体引用 |
| tags | id、value | 标签字典 |
| video_tags | videoID、tagID | 补齐一个视频多个标签的关联 |
| views | userID、videoID、offset、platform、createdAt | 观看和续播信息 |
| comments | userID、videoID、comment、createdAt | 用户评论 |
- 原图修正: videos 中单个 tags UUID 无法完整表示多个标签,因此显式增加多对多关联;
- 内容存储: 数据库保存元数据与对象引用,大视频字节存对象存储或分布式文件存储;
- 发布状态: 可补充 uploaded、processing、ready、failed 等状态,避免处理未完成的视频被当作可播放内容;
- 存储选择: 元数据关系与观看事件的访问模式不同,可以分别选择关系库或分布式存储;
上传 API 如何表达异步处理?
uploadVideo(title, description, byteStream, tags?) → videoID, status
- 数据通道: 上传服务授权并接收或签发上传地址,把大文件交给存储层,而非长时间占用普通 API 请求线程;
- 响应语义: 原文返回 boolean,此处区分“原件已接收”与“处理完成可播放”,客户端用 videoID 查询进度;
- 失败恢复: 对分块上传记录已完成部分,允许断点重试并验证完整性;
- 发布前提: 原件持久保存成功后再进入处理队列,避免任务引用不存在或未完成的文件;
播放与搜索接口应携带哪些信息?
streamVideo(videoID, codec, resolution, offset?) → manifest / stream
searchVideo(query, nextPage?) → VideoPage
comment(videoID, text, requestID?) → commentID
- 播放参数: 编码如 H.264、H.265、VP9,清晰度和偏移用于选取可用版本,不应承诺任何设备都支持所有编码;
- 搜索游标: 以稳定 nextPage 表达分页,避免一次返回整个匹配集合;
- 评论: 验证用户与视频状态,按请求 ID 处理重试,评论删除和审核也应有明确状态;
- 权限: 在签发播放地址前确认订阅、资源权限和地域规则,不能只依赖 videoID 不易猜测;
服务和媒体路径如何划分?
用户 → API 入口 → 用户 / 搜索 / 播放服务 → 元数据存储
上传者 → 媒体服务 → 原件存储 → 任务队列 → 处理 worker
处理产物 → 对象存储 → CDN → 播放器
播放事件 → 分析管道
- 媒体服务: 负责上传和处理状态,worker 可按 CPU 或加速设备需求独立扩展;
- 播放服务: 校验权限并提供清单或播放信息,实际大文件尽量由存储与 CDN 交付;
- 搜索服务: 维护可检索元数据,不把全文搜索负担全部放在事务库;
- 分析服务: 消费播放事件形成指标,避免统计失败阻塞观看;
- 通信方式: 依据接口选择 HTTP 或 gRPC,服务发现和网格按规模需要采用,不是每个教学系统都必需;
处理队列怎样组织长时间视频任务?
- 异步目的: 转码可能远超普通 API 超时,队列把上传与昂贵处理解耦并吸收突发;
- 任务状态: 保存 videoID、输入版本、处理步骤和输出位置,失败后可以从明确边界重试;
- 幂等输出: 同一输入和处理参数应生成可识别的结果,重试不能重复发布多个互相冲突的版本;
- 工具示例: 原文用 SQS 或 RabbitMQ 作为任务队列,处理保证仍依赖应用的确认与重试逻辑;
文件分块如何帮助上传和媒体处理?
- 分块: 把大文件分成可独立传输或处理的小片段,减少失败后重传范围;
- 去重条件: 只有建立内容识别和复用机制,分块才可能节省重复数据,切碎文件本身不会自动去重;
- 切片边界: 可按时间、关键帧或内容场景规划,场景感知有助于编码优化,但不保证任何网络下都不会卡顿;
- 原文归因: 关于 Netflix 场景切块的叙述仅作为作者给出的设计示例,不当作全部现网实现事实;
内容检查如何阻止不合规视频直接发布?
- 检查阶段: 根据平台要求检测内容类型、版权、敏感内容和分级等,具体判断规则由产品定义;
- 人工复核: 自动检查不确定或失败时,进入专门复核任务,必要时使用隔离队列保存问题输入;
- 状态边界: 尚未审核完成的对象可以已存储,但不能因此被公开检索或播放;
- 失败区分: 不符合内容规则与基础设施暂时失败应分别处理,不能无限重试业务拒绝;
转码如何生成适配不同设备的版本?
- 转码: 解码原始媒体,再以目标编码、码率和分辨率生成输出,降低传输或存储成本并适配设备;
- 清晰度梯度: 生成 4K、1440p、1080p、720p 等合适版本,实际梯度需依据内容质量与带宽需求选择;
- 流水线边界: 原文把转码和清晰度转换分为两步,真实实现可以在同一处理阶段生成多种输出;
- 附加产物: 按需要生成缩略图、字幕和播放清单,并保持它们与视频版本对应;
- 工具: FFmpeg 或云端 MediaConvert 是原文实现选项,处理完成后把产物写入对象存储并更新发布状态;
播放器怎样根据网络变化选择码率?
- 自适应码率: 播放器根据可用吞吐和缓冲状况,在多个码率版本间选择合适片段;
- HLS: 原文举出的基于 HTTP 的流媒体协议,通过清单和媒体分段组织播放;
- 播放体验: 低码率可能减少停顿,高码率提高画质,应在网络波动时优先维持可接受播放;
- CDN: 缓存片段并从更合适的位置交付,回源失败时需要重试、备用路径和播放器容错;
- 内存缓存边界: Redis 更适合热点元数据与状态,海量视频主要放在对象存储和 CDN,不把全部视频塞进普通业务缓存;
Open Connect 与通用 CDN 的侧重点有什么不同?
- Open Connect: Netflix 为视频交付建立的专用 CDN,与 ISP 通过互联和设备部署缩短内容路径;
- 设计启示: 当流量和内容分布足够稳定时,可把热门内容预放到靠近用户的网络位置;
- 故障处理: 节点不可用时需要其他可用交付节点或路径接管,而不是只准备一份边缘副本;
- 来源: 机制参见 Netflix Open Connect,不沿用原文中可能过期的流量百分比和站点数量;
断点续播怎样恢复到用户离开的位置?
- 进度记录: 按用户和视频保存最近确认播放位置 offset,可在 views 或独立进度表中维护;
- 恢复路径: 读取 offset,定位对应时间附近可解码片段,再由播放器调整到目标时间;
- 更新频率: 不必每播放一帧就写库,周期上报与暂停、退出时上报结合,在精度和写压力之间取舍;
- 多设备竞争: 新旧设备上报不能无条件互相覆盖,需要会话时间或版本规则;
地理限制怎样在实际资源入口生效?
- 地域规则: 依据内容分发授权限制某些地区访问,可结合可信网络位置和账户信息判断;
- 执行边界: 播放授权与 CDN 实际对象访问都需一致执行,不能仅把目录页重定向;
- 信号局限: 用户可编辑的地区字段不能独立作为可靠访问依据,IP 位置也可能不精确;
- 原文示例: CloudFront 地域限制或 Route 53 地理路由可作为组件,DNS 路由本身不能替代资源访问控制;
视频搜索怎样复用文本检索能力?
- 搜索: 索引标题和标签,异步更新时需过滤未发布或不可见内容,热点窗口计算见 社交信息流;
视频分享怎样复用短链接服务?
- 分享: 生成指向视频页面的短链接,复用 短链接系统,分享链接不应绕过观看权限;
推荐怎样从用户行为形成候选?
- 推荐: 可以从观看历史及相似用户行为做协同过滤,并组合搜索、浏览、时间和设备等已获准的信号;
- 归因边界: 原文列举的年龄、性别等字段是作者的特征示例,不当作 Netflix 实际使用全部字段的断言;
视频指标怎样支持体验分析?
- 指标: 记录播放启动、缓冲、完成率和失败等事件,原文用 Spark 做分析,推荐质量与交付质量分开观测;
存储增长与节点故障怎样处理?
- 分区: 视频元数据按 videoID 或上传者访问模式组织,观看事件可按用户和时间分区;
- 缓存: 热门元数据可设置 TTL 与 LRU,视频分段的 CDN 缓存和应用状态缓存分开管理;
- 冗余: 入口、服务、元数据存储和缓存避免单点,对象存储与原件恢复满足上传不丢的目标;
- 降级: 搜索、推荐或统计故障不应必然阻断已授权视频播放,播放主链路保持尽量短;
- 验证: 覆盖上传中断、重复转码、产物未完成、CDN 未命中、码率切换、地域限制和跨设备续播;