22. ByteDance 亿级视频处理系统高可用架构实践
info
Reference: 字节跳动亿级视频处理系统高可用架构实践
01 视频处理系统整体介绍

视频整体的生命周期大致可以分为四个阶段:
- 端侧生产: 视频的创作者用手机或者其他设备拍摄一个视频,可以对视频做一些增强和编辑,通过上传 SDK,即可把这个视频上传到云端。
- 云端生产: 在云端有两个比较核心的流程:视频处理和审核,这两个流程是在并行执行的。
- 云端下发: 当以上两个流程都执行完以后,一个视频也就可以给大家看了,接下来就进入云端下发的阶段。在这个阶段,点播服务负责下发视频的播放地址(包括相关的 meta 信息),然后视频的内容是通过 CDN 下发。
- 视频播放: 这个阶段由播放 SDK 进行端上视频的处理以及渲染。
在视频生命周期里,视频处理系统是云端生产的核心环节,这也是本文主要介绍的内容。
1.1 视频处理的当前挑战
- 大规模: 目前,字节跳动每天处理的视频量级在亿级,因为每一个视频都会产生不同档位、不同格式的视频,实际生产出的是接近十亿量级的视频。这对计算和存储都是非常大的消耗,这么大体量的业务对系统整体的稳定性和性能也有非常高的要求。
- 多业务: 字节跳动的视频业务非常多样,包括短视频、中视频、长视频,以及点播、直播、RTC 相关的一些业务,涉及教育、游戏等不同的垂直的行业。
- 资源复杂: 除了常规的 CPU 资源,还有很多弹性资源,以及 CPU/GPU/FPGA 等多种类型的资源,还有一些其他的硬件转码设备等。
- 业务高速增长以及大型活动的峰值: 到目前为止,每年处理的视频量级至少都是在翻倍地增长。每年又有很多大型的活动,给系统带来了非常巨大的考验。
1.2 视频处理系统的目标
面临以上这些挑战,视频处理系统要实现哪些目标呢?
大家可以看上图,这张图是一个更偏逻辑的关系。视频处理系统最终的目标总结起来只有三点:
- 满足业务需求
- 提升用户体验: 比如画质、流畅性等方面的体验。
- 降低成本: 字节跳动的体量带来的计算、存储以及 CDN 成本都非常巨大,所以降低成本也是一个很重要的目标。
为了实现这些目标,就需要对视频做不同类型的处理,包括转码、编辑、分析,也包括一些图片处理,每一项都是一种视频的应用。
总结起来就是,整个视频处理系统以底层的系统支撑为基础,构建各种各样的视频处理的能力,形成多种视频应用,从而满足业务场景的需要,提升体验,降低成本
02 视频处理系统架构

为了实现这些目标,视频处理系统的架构如上图所示,外层被划分为三个平面.
- 用户平面: 顾名思义,就是从用户的角度,如何去调用系统。
- 控制平面: 它面向的是开发人员、运维人员、支持人员,如何去控制这个系统,以及当系统出问题的时候,怎么样对系统做一些管理和应急处理的动作。
- 数据平面: 系统每天会产生海量的数据。这些数据一方面可以进行分析,来指导系统的优化。另一方面也用于计量、计费、监控等。
中间的这四层分别是.
- 服务层: 主要是处理鉴权、任务队列的管理、上层的模板管理、策略控制等等。
- 工作流系统: 主要是为了串联异步、分布式的媒体处理流程。
- Lambda: 高可用的函数计算平台,它最大的 作用是管理底层海量的资源,并且对资源进行高效的调度,以及任务的执行。
- BMF: 它是一个动态多媒体处理框架,目标是把所有多媒体处理的原子能力进行插件化管理,然后提高系统的可扩展性以及开发和运维的效率。
03 服务层和工作流系统
服务层有几个重要的组件。
- 服务网关: 它可以进行跨机房的流量调度以及一些接口的鉴权,包括接口层的限流。
- 管理服务:
- 元数据管理 (队列、任务模板、媒体工作流)
- 媒体工作流生命周期管理 (触发、执行、状态管理等)
- 弹性队列:
- 队列限流能力:QPS,MRT 最大并发任务的数量
- 队列管理:任务分发,状态维护
- 弹性资源管理:动态资源调整
3.1 媒体工作流介绍

服务层下方就是媒体工作流的引擎,工作流是以 DAG 的形式组织一系列视频处理的流程。比如说在西瓜视频上传一个视频后,需要去抽取它的封面,并对视频进行无水印转码,还需要进行各种档位的转码。这些都是处理视频的流程,每一个流程都是一个细粒度的任务。把这些单个的流程组织起来就形成了一个工作流。
工作流能解决什么问题呢?
-
解决了复杂业务的调用流程
- 如果没有工作流,处理一个视频就要进行多次的调用。
-
比较好管理视频处理流程的依赖关系
- 在实际的处理过程中,前后的流程之间是会有依赖的,比如画质增强的流程,需要先对原片作增强,再进行普通转码,或者通过分片转码的功能对视频预先切片,再对每一个切片再做转码,最后再把它们拼接在一起。这些都可以通过工作流的方式实现。
-
提供任务超时、错误重试等高可用的能力
- 通过工作流,可以对每一个任务设置超时时间,并在任务失败时进行重试,从而提高系统的稳定性和可用性。
下面图示是工作流内部结构:
- Gate: 工作流入口
- 处理流量调度,包括鉴权的功能。
- Engine: 工作流状态管理
- 管理所有工作流的状态。
- Scheduler: 节点任务队列管理
- 一个工作流包含很多节点,Scheduler 可以对每一个节点进行细粒度的任务调度。
- VWorker: 工作流和函数计算平台粘合层
- 将上层一些偏业务属性的模板转换成一个底层,实际可以执行的函数任务的参数。
3.2 高可用性 - 任务执行
视频处理系统是一个离线处理系统,每一个任务都是 long-term running 任务。这时最重要是保证过来的每一个任务都能够最终被执行,而且最终保持一致。所以对系统来讲,需要有 at least once 的保证。
-
任务幂等
- 转码系统 -> 多媒体离线处理系统 -> 任务需要保证最终一致性 -> 任务幂等
- 同一个任务无论何时执行 执行多少次,最终的结果是一样的。业务方对此是无感知的。
-
任务合并/去重
- 在一定的时间内,如果同一个视频做同一个处理提交了非常多次,这时就需要有去重的机制,只执行一次。这在某些场景下能够比较好的提升系统的效率。业务方对此是无感知的。
- 判重逻辑 -> 转码模板的 Hash + 元信息的 Input
- 接口幂等 -> 当发现有重复转码任务时会返回 相同任务ID + 多次回调
3.3 高可用性 - 快速响应和恢复
视频处理系统的下游涉及到计算资源和存储资源。一旦计算资源和存储资源出问题,很难有一个完美的方案对上层业务做到无感知,要做的就是尽量避免损失,尽量减少对于业务的影响。
- 限流控制: 保证有限的资源内保证重要的任务优先被处理
- 多级限流: 接口/工作流队列/节点
- 例如. 假设底层计算资源现在突然变为正常的一半,如何减少对业务的影响?首先,在工作流层面,需要把一些对于任务延时不敏感的工作流任务进行 delay,这就需要一些策略的预设置。
- 预配置策略 & 动态调整
- 例如. 需要对不同的节点进行优先级的配置,比如视频要转出五个档位,可能其中有两个档位是大家消费概率最高的,就需要把这两个档位优先转出来,其他的档位进行延迟处理
- 多级限流: 接口/工作流队列/节点
- 重转重试 (快速恢复): 任务重试/快速筛选工具/批量重转工具
- 例如场景. 昨天有位同学上线了一个有问题的功能,但是今天才发现。这时要做的是把昨天这个功能上线这个功能以后所影响的视频全部筛选出来,快速进行重新转码,而且不能够影响目前正在运行的业务.
- 挑战1: 如何准确的从某任意一个时间点到另外一个时间点把这一批视频全部都挑出来
- 挑战2: 快速重传,而且不能影响线上的业务。所以这里需要有一个单独的子系统来负责整体的批量任务的查找和重转。
3.4 高可用性 - 系统维度
- 下游中间件冗余备份
- 数据库多级缓存
- 消息队列备份
- 完备的活动压测/预案
- 完备的报警/监控/Oncall 流程
04 函数计算平台
-
函数的定义
- 一个工作流内部的一个节点
- 一个具体的处理任务
- 一段可以运行的程序函数
-
函数计算平台所提供的能力
- 视频应用的水平扩展能力
- 提供多种资源的高效管理和调度能力
- 提供函数管理能力
- 提供函数部署、运行环境等
- 提供各种异常处理及容灾等高可用能力
- 提供日志、报警、监控等数据相关服务

- 图中左侧部分是一个控制平面,开发者可以开发自定义函数,通过管理 UI 注册到函数计算平台上。
- 图中右边是整个函数调用的流程。这个流程首先会经过该函数计算平台的 Gateway,到集群层面的调度,然后会到一个单集群里,单集群内部是我们自研的一个中心调度系统 Order。
- Order 有一个中心调度器,会把这个任务调度到一个具体的节点上去执行。
- 这个节点就会拉取整个函数的可执行的包,然后执行这个函数。