目录

短视频系统(如TikTok, Instagram Reels, YouTube Shorts)的宏观业务架构

1)与用户相关的子系统

2)与视频发布相关的子系统

3)点赞和评论相关子系统

4)推荐子系统

技术选型:常见的NOSQL存储框架选型

基于MinIO实现简单的短视频系统

1)视频上传与转码

2)直播录制

3)上传文件

4)点播地址映射

5)地址动态代理服务

6)拉流播放

7)总结

短视频架构的核心要点:CDN缓存

亿级视频处理系统架构实践

服务层和工作流系统

亿级视频处理宏观流程​编辑


短视频系统(如TikTok, Instagram Reels, YouTube Shorts)的宏观业务架构

以短视频点播为代表的流媒体技术应用在移动互联网时代实现了快速扩张。

现在,短视频内容已成为新趋势,每个人都在从TikTok、Instagram、YouTube等平台上消费这些内容。让我们看看如何为TikTok创建一个系统。

在互联网内容趋于多元化的今天,短视频迅速替代了传统的文字图片,席卷了人们的视野和生活,成为信息传播的重要渠道。

这样的应用程序看起来很小,但在后台有很多事情正在进行。

以下是相关的挑战:

  • 由于该应用程序在全球范围内使用,将会有大量的请求发送到服务器。这最终会增加服务器的负载。

  • 将视频上传到后台将是一个巨大的任务,这将增加服务器的负载并阻塞。

  • 流畅地播放视频,无缓冲。

  • 一个基于用户兴趣推荐视频的推荐系统。

让我们逐一了解每个部分。我将其分为三个部分:

  • 与用户相关的子系统

  • 与视频发布相关的子系统

  • 与点赞和评论相关的子系统

  • 推荐子系统

1)与用户相关的子系统

这是一个包含与用户相关服务的服务,如下所示:

  • 注册:用户将在应用程序中注册。

  • 登录:它将对凭证进行身份验证,并向应用程序发送响应。

  • 登出:用户将从应用程序中注销。

  • 关注:如果用户想要关注或取消关注其他用户,则可以通过此服务完成。

为了存储与用户相关的数据,我们将使用基于SQL的数据库,如MYSQLPostgreSQL,因为与用户相关的数据(例如追踪关注者)将会是关联数据,所以这是一个适当的选择。

为了优化数据库性能,我们将使用主从架构。主数据库用于执行写操作,从数据库用于执行读操作。要了解有关此内容的更多信息,可以阅读文章如何优化数据库性能并扩展它?[3]

现在让我们讨论用户服务的流程。应用程序将发出API调用,API Gateway将管理这些API。

它将为用户服务路由请求。

请求将通过负载均衡器进行,负载均衡器下将有多个用户服务实例。

根据负载,它将决定哪个实例将处理请求。

一旦请求被处理,负载均衡器将将响应发送回API网关,然后再发送回应用程序。

2)与视频发布相关的子系统

一般包含视频上传、存储、处理、播放等流程及相应的流程管理与审核。

核心的操作如下所示:

  • 上传视频:将视频上传到后台服务器。

  • 发布:如果用户想要创建、编辑或删除帖子,则可以通过此服务完成。

与视频发布相关的子系统的技术要点:

  • 如何安全可靠地存储PB级海量数据,并实现视频数据的快速存取;

  • 如何支持多种场景下的视频上传;

  • 如何保障稳定流畅的拉流播放;

  • 以及如何满足视频转码、水印等基本处理需求都成为构建一个视频点播平台需要考虑和解决的技术难题。

核心的核心,就是短视频的存储。

为了存储与帖子相关的数据,我们将使用基于NoSQL的数据库,如MiniO

对于每个用户,可能会有成千上万的帖子,这将导致大量数据。

为了实现最佳性能,扩展数据库可能会很困难。NoSQL数据库支持水平分片,这有助于我们在不影响性能的情况下扩展数据库。

现在让我们讨论视频服务的流程。

应用程序将发出API调用,API Gateway将管理这些API。它将为视频服务路由请求。

请求将通过负载均衡器进行,负载均衡器下将有多个视频服务实例。

根据负载,它将决定哪个实例将处理请求。一旦请求被处理,负载均衡器将将响应发送回API网关,然后再发送回应用程序。

如何使文件在全球范围内可访问而不增加下载时间?

视频文件将上传到NOSQL,如MiniO。

现在,如果我们想在世界范围内任何地方访问文件而没有任何延迟,那么该文件将发送到**内容分发网络(CDN)**,它将将媒体文件更新到世界各地的不同数据云存储中。

我们能进一步优化以减少下载时间吗?

还有一个挑战需要解决,即原始视频的大小可能较大,因此如果将大文件发送回客户端,则下载时间会更长,这会影响用户体验。

文件一旦上传到云存储,您可以在数据库中存储文件路径。

然后将帖子/视频详细信息发送到消息队列系统,如KafkaRockerMq

为了使用户体验流畅,我们需要压缩视频并为不同设备创建不同分辨率的视频。

视频处理工作者将从消息队列系统接收视频详细信息,然后从

云存储中提取文件并进行处理。处理完成后,这些新的视频文件将发送到CDN

如何访问压缩的视频文件?

现在您可能会想,应用程序如何知道上述讨论中压缩的视频的文件路径?由于压缩文件将存储在分类文件夹中,因此可以根据分辨率和文件名轻松查找文件。

视频发布API只会返回文件名,而要访问文件,应用程序将在URL本身中添加分辨率细节,例如/media//mediaID/xxxx

当访问此URL时,它将经过API网关,并从URL中提取分辨率和文件名详细信息。

然后它将在缓存系统(Redis)中检查,如果文件不可用,则将访问CDN并通过它获取文件。然后将其添加到缓存中,以便如果再次请求相同文件,则不必从CDN获取。

3)点赞和评论相关子系统

这是一个包含与视频点赞和评论相关服务的服务。正如名称所示,通过此服务,我们可以为特定帖子更新点赞和评论。与上面讨论的其他流程相同。

4)推荐子系统

通过此服务,基于用户偏好推荐一系列帖子。幕后有很多其他事情正在进行。让我们看看幕后运行的流程。

然后,创建一个帖子后,它将被发送到消息队列系统,然后消费者将提取数据并将数据更新到大数据(Hadoop)中。

将为机器学习服务(如PyTorchTensorflow)设置单独的服务器,在这里它将从大数据中提取数据并训练模型。

推荐服务将使用此AI模型为给定用户推荐帖子。

技术选型:常见的NOSQL存储框架选型

当前存储从逻辑上一般可分为三类,即块存储、文件存储和对象存储。

  • 块存储一般指常见的卷或硬盘存储,以及相应的磁盘阵列、NAS、SAN等存储方式,操作对象是磁盘,使用逻辑块编号寻址,数据按字节方式访问,读写速度快。

  • 文件存储则将数据以不同应用程序要求的结构方式组成不同类型的文件,可对文件进行创建、查找、修改、删除等操作,易于实现数据共享。

  • 对象存储将文件以对象的方式进行存储(一个对象包含属性以及内容),通常实现方式为多台分布式服务器内置大容量硬盘,通过对象存储软件组建集群,对外提供读写访问功能。

业内较为主流的开源存储框架MinIO、Ceph、SeaweedFS,从开源协议、扩展性、成本等多方面进行对比如下表:

由于对象存储结合了块存储读写效率快、存储空间可扩展以及文件存储方便共享的优点,同时结合短视频平台数据存储与视频点播需求,建议选取对象存储框架作为短视频点播平台的存储逻辑。

进一步考虑到短视频点播平台数据规模、存储动态不宕机扩容、在线HTTP多媒体播放以及学习运维成本等需求,通过以上对比,建议选用MinIO开源框架作为短视频存储与点播基础框架。

重点介绍:MinIO对象存储框架

对象存储的出现是为解决了存储海量大数据的问题,如存储海量的视频、图片,并进行数据归档、数据备份、大数据分析等操作。

对象存储一般采用key-object的扁平化存储架构,使用方便,调用API就可进行数据的多样化读写。其大容量、动态扩展、数据灾备等性能,是传统文件存储和NAS无法比拟的。

MinIO是一套基于Apache License V2.0协议的轻量级、高性能开源对象存储框架,适用于图片、视频、镜像等海量非结构化数据存储。

MinIO采用Golang实现,客户端支持Java、Python、JavaScript、Golang语言,兼容亚马逊S3云存储服务接口,方便与其他应用结合。

1)存储机制

MinIO使用纠删码(erasure code)和校验和(checksum)来保护数据免受硬件故障和无声数据损坏,可保证N/2节点损坏的情况下数据的正常访问。

2)扩展性

极简性和扩展性是MinIO集群的两个重要设计理念。

MinIO支持对等扩容和联邦扩容两种扩容方式。对等扩容,即通过增加对等的集群节点和磁盘以扩充集群,例如,原集群包含4个节点4块磁盘,则扩容时可同样增加4个节点4个磁盘(或其倍数),以此保证系统可维持相同的数据冗余SLA,降低扩展的复杂性。

联邦扩容,其基本原理是引入etcd作为统一命名空间,将多个MinIO集群组成一个联邦,可在原有联邦的基础上,向联邦中增加新集群,此扩容方式理论可实现无限扩展,且可以实现在原联邦服务不中断的情况下扩容。

3)对外服务

MinIO完全兼容S3标准接口,客户端和服务端之间通过http/https进行通信。MinIO提供客户端mc(MinIO Client)以支持UNIX命令,同时支持多语言的客户端SDK。此外,其存储后端除使用磁盘外,还可通过网关对接其他存储系统与资源。具体如下表所示。

4)多媒体拉流支持

MinIO对于多媒体文件,支持HTTP-Range的方式在线拉流播放与音视频进度条拖拽。

如下图,使用浏览器以流的形式访问存储于MinIO的多媒体文件时,每拖动一次进度条,则会向MinIO服务端发送一条Http-Request请求,请求Headers中包含Range字段,其内容是当前请求视频进度的开始字节数及缓存结束字节数。

这种形式使MinIO天生支持多媒体文件的拉流播放与进度拖拽。

MinIO多媒体在线播放支持

基于MinIO实现简单的短视频系统

出于集群存储可动态扩展性、支持HTTP流式播放、运营成本等因素,

建议使用MinIO对象存储作为底层存储,开发部署短视频点播地址映射、地址动态代理等服务,实现一套短视频存储点播平台。

其实现框架如下图:

点播平台大致可分为存储层、服务层与应用层。

  • 存储层主要部署MinIO对象存储系统及关系数据库,MinIO用来存储视频对象,关系数据库用来存储视频元数据;

  • 服务层提供各类存储访问服务接口,如文件上传下载、视频播放地址生成、对象地址映射等;

  • 应用层为前端提供应用功能,包括视频上传、查询、播放等功能。

基于MinIO对象存储的点播平台数据访问流程如下图所示:

1)视频上传与转码

统一采用mp4格式作为视频存储和点播格式,为了兼容多种格式视频文件上传,需开发转码模块将其转码成mp4格式进行存储,将其首先存入本地磁盘缓存。

2)直播录制

在直播的过程中开启录制,将录制的文件首先存入本地磁盘缓存。

3)上传文件

视频转码完成或录制完成后,调用MinIO文件上传接口,将视频文件上传至MinIO集群/联邦,由etcd对MinIO集群提供注册发现服务。

4)点播地址映射

服务端部署点播地址映射服务模块,实现MinIO视频点播地址与视频ID的映射,使存储介质的改变不影响视频点播拉流。

5)地址动态代理服务

出于系统安全性考虑,我们不希望暴露MinIO存储地址与存储细节,希望增加一层网关进行媒体流的转发或地址的代理,对外提供统一的服务地址,使用地址动态代理,可以根据点播请求的视频ID不同,动态代理至不同的视频播放地址,实现视频存储细节与服务地址的解耦。

6)拉流播放

客户端或浏览器使用HTTP协议流式拉取视频文件并播放。

7)总结

选用MinIO开源存储框架,快速设计并搭建出一套支持海量短视频上传、存储、点播等功能的视频点播平台,

为当下不断涌现的短视频点播平台及相关应用提供了一定技术选型与设计参考。

短视频架构的核心要点:CDN缓存

除此minio存储之外,短视频对CDN分发也是有很高要求的,

跟传统的长视频相比的话,因为长视频会进行预取刷新的操作,会预先将文件分发到CDN节点上去,

但是短视频内容因为是UGC,而且视频上传完成之后页面马上就要发布出去,进行播放,所以往往不能像长视频那样,提前预取到各个CDN节点,进行预热,这对视频云平台内部的分发能力是有要求的。

就近上传

用户拍完一段视频,需要立即上传。

CDN厂商一般全国各地有多个数据中心,“从基础资源能力上来讲,要求CDN网络有条件为客户提供就近上传的功能”。

如何实现?

通过一套SDK,开发者将这套SDK嵌入到他们APP里面去,最终用户在将视频上传的时候,会通过HTTP DNS的调度去获取离他最近的或者是当前网络中最佳的一个数据中心节点,并且实现这个文件的上传功能。

亿级视频处理系统架构实践

字节跳动火山引擎视频中台支撑了多个亿级应用的视频全生命周期管理:

  • 火山引擎视频的相关 ToB 业务

  • 支持了字节跳动抖音

  • 西瓜视频等产品

全部视频生命周期:

  • 视频生产

  • 视频下发

  • 视频播放等

视频处理整体的生命周期

视频从拍摄到播放的整个过程可以分为四个主要阶段:

  • 端侧生产:视频制作者使用设备拍摄(手机或其他设备),并可对视频增强和编辑。通过使用上传工具,将视频上传到云服务器。

  • 云端生产:云端包含两个关键环节:视频后期处理和审核。这两个环节同时进行。

  • 云端分发:完成上述两个环节后,视频就可以供用户观看,进入云端分发阶段。

    在此阶段,点播服务负责提供视频的播放链接(包括相关的元数据),视频内容通过 CDN 进行分发。

  • 视频播放:此阶段由播放工具负责在用户终端进行视频的处理和展示。

在整个过程中,视频处理系统是云端生产的核心阶段。

接下来,我们探讨一下字节跳动在视频处理方面所面临的几个挑战。

  • 庞大的规模:如今,字节跳动每天处理的视频数量已经达到亿级别,由于每个视频都有不同层次、不同格式的需求,实际上生产的视频数量近十亿级别。这对系统整体稳定性和性能的要求很高,同时,对计算和存储资源造成极大的消耗。

  • 多样化的业务:字节跳动的视频业务涵盖广泛,涉及教育、游戏等不同垂直行业,包括点播、直播、RTC,以及长视频、中视频、短视频 等相关业务。

  • 复杂的资源环境:除了常规的 CPU 资源外,还有许多弹性资源,如其他的硬件转码设备,CPU/GPU/FPGA 等。

  • 大型活动的峰值和业务高速增长:字节跳动每年都有许多大型活动,给系统带来巨大的压力。此外,每年处理的视频数量都以至少翻倍的速度增长。

视频处理系统的目标

面临以上这些挑战,视频处理系统要实现哪些目标呢?

大家可以看上图,这张图更偏逻辑的关系。

在实现视频处理系统的主要目标时,我们需要关注三个重要方面:首先,满足各种业务需求,例如支持短视频、长视频等不同类型的视频业务以及满足各行业的需求;其次,提升用户体验,通过优化画质、流畅性等方面,让用户获得更好的观看体验;最后,降低成本,特别是考虑到字节跳动庞大的业务量所带来的计算、存储以及 CDN 成本。

为达成这些目标,视频处理系统需要具备多种处理能力,例如转码、编辑、分析和图片处理等。这些处理能力都是视频应用的重要组成部分。以转码应用为例,我们需要采用新的编码器、自适应转码等技术来降低码率,同时通过增强技术提高画质等。

此外,所有这些处理能力都依赖于一个高可用性、高可扩展性和高效运维开发效率的基础处理系统。这个系统是整个视频处理系统的核心,为我们提供了各种视频处理能力的支持。

总之,视频处理系统是一个复杂的系统,它以底层系统为支撑,构建了各种视频处理能力,形成了多种视频应用,从而满足了业务需求、提升了用户体验并降低了成本。

视频处理系统架构

为了实现这些目标,视频处理系统的结构如图所示,可分为外部和内部两个部分。

在外部部分,系统被划分为三个层次:

  1. 数据平面:系统每天产生大量数据,这些数据可用于分析以指导系统优化,同时也用于计量、计费和监控等方面。

  2. 控制平面:服务于开发人员、运维人员和支持人员,他们负责操作和控制系统,并在系统出现问题时进行管理和应急处理。

  3. 用户平面:主要关注用户如何与系统互动,以及如何使用系统功能。

中间的四层分别是:

  1. BMF:动态多媒体处理框架,旨在插件化管理所有多媒体处理原子能力,从而提高系统的可扩展性、开发和运维效率。

  2. Lambda:这是一个高可用的函数计算平台,主要负责管理底层海量资源,实现资源的高效调度和任务执行。

  3. 工作流系统:旨在协调异步、分布式的媒体处理流程。

  4. 服务层:主要负责处理鉴权、任务队列管理、上层模板管理和策略控制等任务。

下面将为大家详细介绍几个核心层。

服务层和工作流系统

系统服务层介绍

在服务层中,有几个关键组件值得关注:

  • 服务网关:它能够进行跨数据中心的流量调度,并负责接口认证和接口层的流量控制。

  • 弹性队列:它可以隔离业务方面的资源。它的功能包括:队列资源设置(例如任务的 QPS 和最大并发任务数量 MRT)、队列管理和弹性资源的管理。

  • 管理服务:它具有两个功能,首先是对整个视频处理系统的元数据进行管理,例如任务队列、模板和工作流信息等;另外是启动底层工作流的执行,并管理整个工作流的生命周期状态。

媒体工作流介绍

在服务层的下方,有一个媒体工作流引擎,负责组织一系列视频处理的操作,这些操作以 DAG 的形式排列。例如,在西瓜视频上传一个视频后,需要提取视频封面并进行无水印转码,还需要进行各种编码格式的转换。

这些处理视频的流程都属于细粒度的任务。一个可行的方法是将这些单独的流程整合成一个工作流。工作流解决了以下问题:

  • 首先,它简化了复杂业务的调用过程。如果没有工作流,处理一个视频需要进行多次调用。

  • 其次,工作流有助于管理视频处理流程之间的依赖关系。在实际处理过程中,前后流程之间存在依赖关系,例如画质增强流程,需要先对原片进行增强,然后进行普通转码,或者通过分片转码功能对视频预先切片,接着对每个切片进行转码,最后将它们拼接在一起。这些都可以通过工作流实现。

  • 最后,工作流提供了任务超时、错误重试等高可用能力,降低了业务使用成本。

下面看一下工作流内部是怎样的结构。

工作流内部主要包括以下几个组件:

  • VWorker:作为上层与下层的连接层,将上层的业务模板转换为底层可执行的函数任务参数。

  • Scheduler:对于每个工作流中的节点,可以进行细粒度的任务调度。

  • Engine:管理所有工作流的运行状态。

  • Gate:负责处理流量调度和授权验证。

工作流的核心部分如图中所示,位于绿色区域。

服务层位于顶部,而下面要介绍的是函数计算平台。

任务执行

视频处理系统是一个批处理系统,每个任务都需要执行几十秒、几分钟甚至更长时间。

因此,最关键的是确保每个任务都能最终被执行,并且保持一致性。

为了实现这一目标,系统需要有at least once的保证。

此外,任务还需要满足幂等的要求。

任务幂等有两个意义:

  • 首先,无论任务在何时执行多少次,最终结果都应保持一致,并且对业务方来说透明。

  • 其次,在一定时间内,如果同一个视频进行相同处理并提交多次,系统需要具备去重机制,只执行一次。对调用者而言,这个过程也应透明,这能在某些场景下提高系统效率。

为了确保任务幂等,我们在视频 meta 信息关联和视频存储方面做了大量工作。同时,为了实现 at least once,我们在工作流和节点层面都设置了超时检测和重试机制。

任务执行的难点1:快速响应和恢复

视频处理系统的下游包括计算资源和存储资源。

一旦计算资源和存储资源出现问题,很难有一个完美的方案对上层业务做到完全无影响,所以要尽量减少损失,降低对业务的冲击。

为此,可以采取以下两个重要措施:

  • 多级限流:限流是一种常用方法,但视频处理有一个任务筛选过程,需要确保在有限资源内,所有重要任务得到优先执行。

    例如,假设底层计算资源突然减少一半,如何降低对业务的影响?

    首先,在工作流层面,需要将一些对任务延迟不敏感的工作流任务进行推迟,这需要一些策略的预设置。

    此外,在同一个工作流中,需要对不同节点进行优先级配置,比如视频需要转出五个档位,其中两个档位消费概率最高,需要优先转出,其他档位则可以延迟处理。这整体涉及到分级限流以及限流策略配置的能力。

  • 批量重转:假设昨天底层同事上线了一个有问题的功能,但今天才发现。这时需要把昨天这个功能上线后所影响的视频全部筛选出来,快速进行重新处理,且不能影响目前正在运行的业务。

    这有两个问题需要解决:

    第一,如何准确地从某个时间点到另一个时间点,将这一批视频全部挑选出来。

    第二,如何快速重新处理,且不影响线上业务。因此,需要一个单独的子系统来负责批量任务的查找和重新处理。

任务执行的难点2:系统维度

从系统层面来说,我们采取了若干措施,主要包括中间件备份以及对下游异常进行监测。一旦发现某些实例出现问题,我们会立即对这些实例进行隔离和剔除。此外,系统具备较为完善的流量切换策略,因为系统已经经历了多次大型活动考验,同时拥有全面的压测和预案,这些对于确保系统的高可用至关重要。

函数计算平台

上面介绍了工作流的系统。下面介绍一下它的下层函数计算平台。

首先,让我们来了解一下函数的概念。

函数在媒体工作流中代表一个节点,同时也对应着一个细粒度的视频处理任务。换句话说,函数就是一个可执行的程序段。

那么,这个函数计算平台需要具备哪些能力呢?

  • 首先,也是最关键的,平台需要为视频处理程序提供大规模水平扩展能力,以便轻松地为线上业务提供稳定服务。

  • 其次,平台需要管理多种类型的庞大资源,并且具备高效的资源调度能力。

  • 最后,平台还需要具备处理各种异常情况和容灾等的高可用能力。

上图是这个函数计算平台的基本架构。

在图中的左侧部分,有一个控制平面,开发者可以编写一个函数并通过管理用户界面将其注册到函数计算平台上。

接着,我们看到图中的右侧部分展示了整个函数调用过程。首先,该过程会通过函数计算平台的网关,进入集群级别的调度。随后,过程会进入一个独立的集群,而这个集群内部包含了我们自主研发的中心调度系统 Order。

Order 系统拥有一个中心调度器,它会将任务分配到一个具体的节点上执行。这个节点会获取整个函数的可执行包,然后运行该函数。

高可用性:多集群

在多集群层面,

  • 首先,我们做了流量的一键切换,多集群的容灾;

  • 其次,我们也会根据预设配置进行流量的自动调节。

上图是简单的多机房示意图。

图中左右两侧均为机房,每个机房包含多个集群。

每个机房设有一个集群级调度器模块,而多个机房之间还有一个负责同步各机房资源状况的模块,包括资源总量和使用情况等。

高可用性:单集群

我们的单集群采用中心调度系统,其中心调度器名为 Server,另有一个执行单元称为 Client。Server 具有多实例、无状态的特点,能够平稳、动态地进行升级。

在 Server 和 Client 之间,有状态检测机制以及对问题节点的熔断和任务重试等措施。

通常情况下,Server 通过心跳检测来判断节点是否正常运行。除此之外,Server 还会关注节点的整体状态,例如任务超时较多或失败率较高等情况。当出现这些情况时,也会对节点执行熔断策略。

控制面——服务治理

之前我们提到过函数计算平台分为几层,分别是网关层、集群调度层和机器内部调度层。

这些层次均为多实例服务。因此,每个上游都会对下游进行异常检测和隔离,这意味着所有组件都具备单点异常处理能力。此外,还有一些中间件熔断策略。

动态多媒体框架 BMF

BMF,即 ByteDance Media Framework,是字节跳动自主研发的多媒体处理框架。

我们决定开发一个视频处理框架,是因为发现传统的视频处理框架存在一定的局限性。

  • 首先,传统的框架通常使用 C/C++ 进行开发和扩展,这导致扩展的门槛较高,且扩展后需要重新编译。在一个大型系统中,这是非常麻烦的。

  • 其次,随着越来越多的人参与框架的开发和维护,框架的依赖关系会变得越来越复杂,最终降低开发和运维的效率。

  • 另外,传统的视频处理流程较为固定,例如视频转码,传统框架都可以支持。但在一些更为复杂的场景下,如视频编辑或 AI 分析,传统框架在灵活性上存在限制。

  • 最后,传统框架在性能方面也存在瓶颈。以 ffmpeg 为例,filter graph 是单线程执行的。如果在 filter graph 中加入一个 GPU 的 filter,执行效率会大幅降低,同时 GPU 的利用率也不会很高。

为了解决上述问题,我们研发了 BMF 多媒体处理框架,其目标包括:

  • 通过一套框架支持各种复杂的应用场景,具备较高的灵活性。

  • 屏蔽底层硬件差异。随着业务越来越多地使用不同异构硬件,如 GPU,我们希望这个框架能原生支持这些硬件。

  • 通过该框架将所有视频处理的原子能力模块化,并实现动态管理和复用,以解决大规模协同开发的问题。同时,也能使这些能力在不同场景和业务上得到较好的复用。

  • 降低视频应用开发的成本,使应用开发标准化。

上图展示了 BMF 框架的总体结构。

在最上层,即应用层,每一模块都代表一个视频应用,例如前面提及的视频转码、视频编辑、图片处理等。在下层,是模块层,其中的每个模块都代表视频处理的一个细粒度原子功能,如进行视频编解码或 ROI 检测等。

应用层和模块层通过中间的框架层连接在一起。

框架层的核心是一个引擎,它向上提供一套通用、简洁的流式接口,便于开发者容易地构建视频处理应用。此接口支持多种语言,包括 C++、Python 和 Go。向下,它提供一套完整的模块开发 SDK,同样支持这几种语言。

在核心引擎周围,我们还开发了一些相关服务和工具集,主要用于管理模块的版本、依赖等信息。

这种架构的最大优点在于,它为开发者提供了一个较好的划分

不同模块的开发者可以专注于自己模块的开发,并选择熟悉的编程语言。

模块开发完成后,可以将整个模块注册到系统中。上层的应用开发支持业务,业务无需了解底层模块的实现方式以及所使用的编程语言。只需利用框架提供的接口,就可以无缝连接并使用这些模块。

上图进一步展示了 BMF 的动态开发模式。

以实际情境为例,算法开发者负责研究视频处理算法。

  • 首先,算法优化人员会对算法进行优化。优化完成后,算法将形成一个模型。

  • 接下来,算法优化人员会将模型注册到系统中,而模块开发人员会将模型封装成具体模块,并注册到系统中。这些模块代表着具体的原子能力。

  • 然后,函数开发者,即业务开发人员,可以将模块串联成具体的视频处理应用,并将函数注册到函数管理平台,然后进行灰度测试和上线。

在整个流程中,各个团队的分工非常明确,独立开发协作效率大大提高。

此外,流程中的所有模块原子能力都是可重复使用的。且流程不会涉及任何编译依赖,全部都是动态进行的。

亿级视频处理宏观流程

上图展示了视频转码的完整流程示例。当用户上传一个视频后,该视频将首先进入服务端的存储,从而触发转码流程,即提交一个工作流任务。此任务将首先经过转码服务,然后被放入弹性队列;接下来,任务将从弹性队列出队,进入工作流引擎执行;工作流引擎将拆分任务为细粒度的子任务,并将它们发送到函数计算平台执行。每一个函数都将采用前面介绍的 BMF 动态开发方式进行构建。最终,在所有细粒度节点任务完成后,整个工作流程也将完成,然后转码或视频处理流程将完成,并逐步返回。

在此,让我们回顾一下本文的一些关键点:

首先,视频处理系统需要满足几个重要要求,包括高可用性(系统稳定性)、高可扩展性(在支持众多业务场景时,可扩展性对整体高可用性具有重大影响)以及开发和运维效率。

总的架构可以概括为媒体工作流、函数计算平台以及动态多媒体框架 BMF 这三个核心部分。在高可用性方面,服务层将提供任务幂等、多级限流和批量重传;平台层将实现多机房、多集群的切流策略、单集群内部的冗余、上下游的异常检测等。最后,底层的动态多媒体框架虽然并未直接提高系统的高可用性,但提升了系统的可扩展性、开发和运维效率,因此也对系统起到了至关重要的作用。

未来,系统将朝着更智能化的方向发展。我们希望构建一种分布式调度执行平台,用户只需关注处理流程,而平台的拆分、资源调度和执行方式将由平台自行决定。