Skip to content

文件处理:上传完成、异步转码与批量资源控制 ​

视频转码应在文件完成上传并校验后触发。创建上传地址或收到第一块数据时,源文件可能仍不完整;用户刷新或登录页面只能查询进度,不能反复创建新的转码。

示例把同一源文件版本转成多种输出格式,允许格式任务独立失败与重试。

从上传接口推导后台处理 ​

假设一个小文件格式转换只需很短时间,容量可控且请求超时预算足够,同步处理可以成立。需求变成上传大型视频、用户随时离开、处理持续数分钟时,请求生命周期就无法承担整个处理过程。

候选方案适合什么条件需要处理的代价
上传请求内转换耗时短、资源上界可控请求长占用,断开后的结果不确定
请求返回后启动内存协程工作可以丢失或有外部重建依据进程重启、限流、进度持久化
持久化运行与输出任务需要独立恢复、跟踪与资源控制源版本、任务领取、产物发布和清理

本篇选择第三种。拆分的最小单位是可独立确认的输出格式,而不是无条件把一整份文件的所有处理捆在一次重试里。对于必须共享一次昂贵解码的处理流水,也可以改用单运行多阶段,但要相应设计阶段检查点。

上传确认、转码与产物发布时序 ​

对象写入与数据库发布不在同一个事务里。暂存产物可以已经存在,但未取得发布资格时不对用户作为正式结果开放。

多个格式可以独立执行与恢复。通知阶段读取已发布的文件版本,不以某个子进程已经退出作为整份文件可用的唯一依据。

文件处理需求与完成标准 ​

示例要求上传完成后生成低清预览与高清版本,预览先完成时允许用户先看,全部必需格式完成后才标记整份文件 ready。产品也可以选择必须全部成功,关键是明确发布条件。

需求示例决策开发约束
谁能上传按租户和用户控制大小、数量与资源预算上传会话与配额记录
上传后何时开始完成合并并通过源文件校验完成接口和存储事件共同核对
什么叫可用必需输出通过校验且正式结果已发布不把进程退出码当唯一成功标准
谁能取消文件所有者与授权操作员取消请求与源版本关联
重做后是否覆盖旧版本新处理版本完整后切换产物指针条件更新

触发前确认源文件 ​

事实需要确认什么
上传完成分片合并已完成,对象能够读取
文件身份对象键、版本或不可变内容标识稳定
业务登记文件属于正确用户,大小与格式校验通过
处理要求使用哪个转码参数版本、哪些输出格式

对象存储通知可能重复或乱序。以 S3 为例,官方明确说明事件至少投递一次且不保证顺序,见事件顺序与重复说明。

任务键可以采用 file_id + source_version + profile_version + output_format。同一路径后来上传的新内容不能继续沿用旧任务身份。

数据结构与业务接口 ​

记录关键字段与约束
upload_sessions用户、源对象身份、预期大小、完成状态、请求键
file_versions文件、源版本、校验摘要、登记状态、删除标记
processing_runs源版本、参数版本、所需格式、取消状态
processing_outputs运行、格式、尝试 token、暂存产物、校验结果、发布指针
storage_inbox存储来源与事件身份、原始内容、关联状态

产物可用通知复用通知意图与渠道投递约定:意图绑定处理运行及发布版本,渠道记录保存每个目标的请求身份、提交时间和结果。通知失败只重试相应投递,不重新转码或重复发布产物。

业务接口可以划分为开始上传、确认完成、查询处理进度、请求取消和创建重新处理版本。重复完成请求返回同一运行,不再次创建所有输出任务;重新处理请求必须明确参数版本和请求幂等键。

下载接口同时校验文件归属与当前可见版本。业务表中的对象地址不应直接成为永久公开访问凭据。

上传登记与任务创建 ​

应用确认上传完成后,在业务数据库中保存文件版本与转码任务。对象已经存在、数据库登记却失败时,保留可重试的完成流程,并定期识别孤立对象。

如果存储事件先于业务登记到达,消费者可以记录待关联事件,稍后核对;不要因为暂时查不到文件记录,就永久确认并丢弃唯一的触发依据。

Outbox 只能覆盖数据库内部的原子提交,不能让对象存储与数据库自动变成一个事务。

完成上传的处理流程 ​

text
完成 API 或存储事件触发核对:
  验证来源、上传会话身份、对象版本与完整性
  在事务外完成必要的对象读取或校验
  BEGIN
    锁定上传会话,确认没有取消且源版本仍相同
    幂等保存 file_version 与 processing_run
    为必需输出格式创建独立任务
    更新上传完成状态
  COMMIT

存储事件先到时,把事件持久化到待关联记录;业务登记先到时,保留等待对象确认的状态。核对任务让两条路径最终接上,不能让一次暂时查询失败变成永久漏处理。

1000 个视频同时上传 ​

1000 个 10 MB 短视频与 1000 个 5 GB 长视频,不能采用相同的并发预估。队列长度之外,还要估算总时长、输入字节、预计 CPU/GPU 时间、临时磁盘与输出大小。

可以按轻重任务划分资源池,按用户限制并发,给交互式短任务保留容量。Worker 根据可用资源领取任务,不能先领取全部 1000 条,再让它们在内存里等待直到租约过期。

通知渠道与转码资源分别限流。把更多通知 Worker 加进去,不会提高 GPU 转码吞吐。

Worker 的执行边界 ​

阶段行为失败恢复
准备领取与资源匹配的任务,核对源版本、取消和配额暂时无资源则不大量预领取
处理使用本次尝试的隔离工作目录,持续检查截止时间超时停止子进程并记录退出结果
保存暂存输出和校验摘要,确认大小、格式与可读性部分产物按尝试身份清理
发布事务中校验当前领取 token、源版本与运行状态失去资格则不发布旧产物
收尾更新格式结果与文件可用条件,保存通知通知失败独立恢复

续租失败只改变数据库所有权,不会自动停止转码进程。Worker 要主动结束或隔离旧执行,并以发布时的 token 检查防止迟到结果覆盖。

部分成功和结果发布 ​

text
源版本通过校验
  → 创建各输出格式任务
  → 输出写入本次尝试的暂存位置
  → 校验产物完整性
  → 条件更新该格式的正式结果指针
  → 所需格式达到发布条件后,通知文件可用

重试使用独立暂存产物,只有通过版本与所有权检查后才发布,避免旧 Worker 恢复后覆盖新结果。两个格式成功、一个失败时,按产品规则决定部分可用,失败格式单独重试。

暂存地址回答“本次尝试写到了哪里”,正式指针回答“用户可以读取哪份结果”。外部存储写入可能已经完成,而发布事务仍然失败;分开两者,才能回收无人引用的产物,并阻止把半成品直接暴露给用户。

删除、取消与恢复 ​

用户删除文件后,运行中的任务可能仍持有源对象。处理器应在关键阶段检查删除或取消状态,停止发布;临时产物通过有范围的清理任务回收。

任务重试需要确认源版本仍存在、参数仍有效,并区分暂时读失败与永久格式不支持。长期失败不能无限占用昂贵资源。

兜底扫描核对“上传已登记但没有任务”“任务成功却缺少可用产物”“暂存对象无人引用”。完成通知按文件可用版本去重,用户离线也不影响处理继续进行。

一次部分成功与旧尝试恢复 ​

假设文件 F6 的源版本为 3,处理运行 P12 要生成预览和高清两个格式:

动作处理与产物记录对外结果
完成事件重复到达仍是同一源版本与参数版本的 P12不额外创建第二轮全部任务
预览校验并发布成功preview 指向本轮有效产物按示例规则允许预览
高清尝试 token 8 停顿超租约重新领取得到 token 9高清仍未就绪
token 9 生成并发布高清正式结果关联有效尝试满足必需格式后整体 ready
token 8 恢复并写出旧暂存对象发布检查失败,保留待回收记录不覆盖 token 9 的结果

如果用户此时删除 F6,发布事务还要检查删除状态。只检查源版本相同不足以授权发布,因为同一源版本也可能已经被撤销。

这个案例可以迁移到图片缩略图、导入文件和文档解析:先识别输入版本,再定义可独立确认的结果,最后控制谁有权发布。

验收与排查依据 ​

场景应断言的结果
完成上传请求与对象事件各到达两次只生成同一源版本的必需格式任务
对象完成但业务登记暂时不存在待关联事件保留,核对后可继续
三个格式中一个失败成功格式不重算,整份 ready 按约定判断
旧尝试在新尝试发布后结束token 与版本检查阻止旧结果替换
删除与发布同时发生发布事务核对删除状态,旧链接无权访问
1000 个重任务同时到来资源池、租户配额与临时磁盘都受控

每次尝试记录输入字节、媒体时长、执行资源、输出格式、退出原因与产物摘要。积压容量按预计工作量衡量,同时观察待处理年龄,不能只看任务条数。

腾讯云媒体服务的回调与结果补查 ​

腾讯云点播的回调设置区分普通 HTTP 回调与内置队列供应用拉取消费的可靠回调。另一个产品——腾讯云媒体处理——在任务配置常见问题中说明,未收到转码回调可能源于配置错误或任务积压;已成功提交的 API 任务可以通过任务查询接口检查进度。两份资料对应不同产品,接入时应分别核对协议。

应用因此需要保存外部任务 ID、源文件版本、提交时间和最后核对时间。本文建议先接收事件并去重,再按任务身份更新格式结果;长时间没有事件时发起限速补查。没有收到回调不能直接判定转码失败,更不能每次超时都重新提交昂贵的转码任务。

1000 个视频同时处理时,应把处理并发、事件消费能力与补查频率分别限制。若大量任务停在处理中,先区分执行积压和通知积压,再安排恢复。可靠回调改善的是结果通知路径,业务仍需处理重复结果、源文件撤销和正式产物发布条件;上述字段和恢复策略属于本文的接入设计建议。

火山引擎视频点播:上传成功后元信息仍可能未就绪 ​

火山引擎的事件通知常见问题说明:超大文件可能先完成上传,再抽取元信息,上传完成回调中的文件信息因而可能为空;回调失败会有限重试,耗尽后会丢弃通知。上传完成、元信息可用与转码完成需要分开判断。

本文建议保存源文件已上传、元信息待就绪、处理已提交、产物待发布等阶段。回调缺少时长或编码信息时,不应仅据此判定文件损坏,也不能立即发布给需要这些信息的下游。保存外部身份后,按对应 API 支持的查询方式补齐证据,并为长期未就绪任务设置超时处置。不能假设供应商会永久重推丢失通知。

美团流水线引擎:领取成功与执行开始之间还有窗口 ​

美团的流水线引擎建设实践描述了决策、待领取、已调度等状态,以及乐观锁、领取 ACK 和队列补偿。文中的作业可能在 Worker 长暂停后被再次分配,因此恢复的旧 Worker 不能被默认视为仍拥有执行资格。

这个模式可用于检查本文转码任务的故障窗口:任务领取后尚未开始时崩溃,应该允许恢复;旧进程恢复后尝试发布,则应被当前 token 与源版本拒绝。外部转码服务已经接受的请求,不能只凭本地租约过期便确认没有执行,需要查询原任务或使用供应商支持的请求幂等机制。美团原文是 CI/CD 场景,本文借用的是状态与交付边界,没有将其直接当作视频处理实现。

参考资料 ​