这次要做的是一条无人值守的视频产线。两台机器各自运行剪辑程序,批量处理电影解说和书籍植入视频;主机会话只负责开发,产线自己启动、继续、失败后换下一项,最后把合格成片放到统一的交付位置。听起来像是把任务平均分给两台机器,然后让它们同时工作,事情就会自然变快。
一开始我也容易这样想。既然有两台机器,就把一半任务给第 1 台,另一半给第 2 台,或者一台处理奇数集,另一台处理偶数集。可真正把它跑起来后,问题很快出现了:机器速度不完全一样,登录授权状态不完全一样,某些任务的长度也不一样。表面上是“怎么分任务”,实际上是在设计一条不用人盯着的生产系统。
两台机器同时工作,不等于产线稳定
当时的场景很具体。一台机器连续完成了几集,另一台刚好卡在剪辑软件的授权弹窗上;有时一台已经进入下一集,另一台还在检查上一集的状态。后来授权问题解决,两台才恢复同时出片。这个过程让我看到,设备数量只是产能的一部分,真正影响结果的还有启动条件、任务长度、运行状态和失败后的处理方式。
如果简单按照总量平均分配,最开始看不出问题。两边都拿到了一堆任务,进度表也可能显示一半对一半。但只要一台稍慢,或者它拿到的电影更长,队尾就会出现一台机器已经空闲、另一台还在拥堵的情况。无人值守系统最怕的不是某一台机器慢,而是慢机器把任务变成了别人无法接手的孤岛。
如果不处理,后果也不只是少做几集。机器可能已经停止,调度表却还显示“进行中”;失败的任务没有回到队列,下一台机器以为没有可做的内容;更糟的是,重复领取会造成两台机器做同一集。到了最后,人看到的可能是完成数量不少,却不知道哪些成片能回取、哪些任务已经丢失、哪些只是卡在中间状态。
我一开始纠结的是电影还是集数
讨论调度时,最直观的选择有两个:按电影分,把一部电影的全部集数交给一台机器;或者按集数分,谁空闲谁领取下一集。按电影分的好处是连贯。同一部电影尽量由同一台机器完成,目录、草稿和处理顺序更容易理解。若一部电影被切成很多段,整包交给一台机器,后面检查时也不容易遇到两边状态不一致。
但按电影分有一个明显代价:任务包的大小差异可能很大。一部电影有 6 集,另一部可能有 15 集。如果一台机器拿到长片,另一台拿到短片,短片做完后就只能等待。尤其在限时处理窗口里,空等不是小问题,它会直接减少总产量。
按集数分则更灵活。每集完成时间大约在 8–10 分钟,谁先空出来,谁就从队列里领取下一集。快的机器自然多做,慢的机器自然少做,单台机器临时卡住时,其他机器也能继续推进。它牺牲了一点同片连贯性,却换来了更好的吞吐和故障隔离。
后来我判断,不能把这两个选项当成必须二选一的架构。调度单位应该按“可独立验收、可独立重试”的任务来切分,内容顺序则可以另设规则。 这就是为什么最后采用了混合方式:队列按集领取,任务排序尽量按电影组织;同一部电影内部保持集数顺序,哪台机器先空闲,哪台就领取下一个合适的任务。
这个判断的理由很现实。两台机器的速度相差不大时,把整部电影固定给某一台,连贯性的收益有限;而让快机器一直有活可做,能减少更多空闲时间。等队列快见底,再考虑“先到先得”地尽量保持同片归属,才是对整体吞吐影响更小的优化。
真正的调度单位不是一集,而是一条状态链
说“谁空谁领下一集”还不够。无人值守系统必须知道一项任务现在到底处于什么状态。至少要区分待领取、已领取、处理中、质检通过、失败待重试和需要人工处理。每次领取都要留下记录,记录机器、任务和时间;任务超过合理时长没有进展,就不能永远保持“处理中”,而应该回到队列,或者被标记为需要检查。
这里最容易误判的是“完成了多少集”。数字很漂亮,却不能说明产线健康。某台机器可能完成了很多集,但没有把产物写入统一位置;也可能产物在目录里,质检没有通过;还可能前面几集失败后,程序跳过了它们,继续做后面的集。只统计完成数量,会把缺口藏在总数后面。
所以我会把一项任务看成一条完整链路:领取记录、工作文件、成片、字幕和封面、质量检查、统一归档、发布台账。只有这些状态彼此对得上,才算完成。调度器负责让任务流动,质检负责判断能不能进入下一步,归档负责让产物以后找得到。一个流程成熟的标志,不是它能顺利跑完一次,而是它能把“做过什么、为什么失败、还能不能重做”留下来。
归档和过程文件,不能用同一种处理方式
这次还有一个容易被忽略的分界:工作文件并不都应该保留,也不都应该马上丢掉。能复用的剪辑草稿、未压书图和字幕的母版、稿子、字幕、质检回执和必要日志,属于归档型文件。它们以后可能用于换字幕、换书图或重新导出,应该放到统一的工作文件归档区。
从原片截出的片段、带书图的中间视频、已经交付后的成片副本、配音中间文件、失败重做留下的目录和其他纯过程大文件,则没有同样的复用价值。它们过了保留周期后,只移动到废纸篓,不直接删除。这样既能释放工作盘空间,也保留了回退机会。
我选择“归档型留存、过程型延后移动”,是因为无人值守的清理不能只追求空间数字。直接删除最省事,却会让一次错误分类变成不可恢复的损失;把所有东西都归档,又会让归档区变成另一个垃圾堆。归档前先复制和核对,核对通过再移动原工作目录,重复执行时不重复处理,这条边界比“全部保留”或“全部删除”更可执行。
失败重试要有边界,授权问题不能伪装成任务失败
产线运行时,失败原因不只来自内容本身。有一次,机器上的字幕判断逻辑还是旧版本,带引号的句子被误判;另一台则遇到剪辑软件授权弹窗,程序不是做错了任务,而是在等待系统许可。后来还遇到过剪辑软件退出、外置存储短暂卡住等运行状态问题。
这些情况不能全部用“失败一次,重试一次”处理。字幕规则错误,应该修正判断逻辑后再决定是否把旧失败任务放回队列;授权弹窗,应该暂停并等待授权完成,不能连续启动同一任务制造更多中间目录;剪辑软件正常退出,可以自动重启;连续失败达到阈值,则应暂停该机器并写明原因,等待人处理。
真正安全的重试,需要先判断失败发生在哪一层:内容筛选、授权登录、剪辑过程、文件写入、质量检查,还是发布排期。内容筛选还要遵守已确定的范围,例如优先处理美国和中国电影,犯罪、动作、战争片可以保留,真正吓人的恐怖类先过滤或单独确认。把这些规则和调度混在一起,任何一次重试都可能改变原本的内容边界。
我没有把“完成数量增加”当成唯一目标,也是因为质量门不能被吞吐量覆盖。每集要能完整解码,音频不能出现异常空白,字幕、书图、封面和必要的禁词检查要通过。无人值守不是让系统什么都自动放行,而是让它在明确规则内自动前进,在不确定状态下自动停住。
一套可以复用的任务切分方法
把这次经验抽出来,我会先回答 4 个问题。第 1 个问题是:任务能不能独立验收?如果必须等同片所有集都完成才知道是否合格,就不适合直接作为最小调度单位。第 2 个问题是:任务能不能独立重试?如果失败后只能整批重做,机器稍微波动就会造成很大的返工范围。
第 3 个问题是:任务的工作文件和最终产物能不能分开管理?最终产物进入统一交付区,可复用的中间成果进入归档区,纯过程文件按周期移动到废纸篓。第 4 个问题是:失败时由谁接手?机器故障可以让任务回到队列,规则不明确的内容应进入人工确认,授权和登录问题则不能靠盲目重试解决。
具体流程可以很朴素:先建立待处理队列;机器空闲时领取一个任务并写入认领记录;处理过程中定期更新心跳;产物写入统一位置后做质量检查;通过后登记归档和发布状态;失败则按失败层级决定重试、回队列或暂停。队列里按电影组织顺序,执行时按实际吞吐取任务,正好把“内容连贯”和“机器不空等”放在了不同层解决。
这套方法不只适合视频。批量转码、长文档处理、图片生成、数据清洗,凡是任务时长不一致、执行设备性能不一致、失败后可以局部重做的场景,都可以用同一个原则:先找到最小的可验收单元,再让资源动态领取,而不是提前把一大包工作永久绑在某台设备上。
下次我会怎么做
下次搭建类似产线,我会先画出任务状态,而不是先讨论两台机器各做多少。先确认什么叫领取、什么叫完成、什么叫失败,哪些状态可以自动转换,哪些状态必须停下来等人。状态清楚以后,按电影还是按集数就不再是一个抽象争论,而是根据任务粒度和故障恢复成本做选择。
我会默认采用“可独立重试的任务动态领取”,再根据内容需要增加同片顺序和归属规则。机器速度不同,就让快的多领、慢的少领;某台机器暂停,就让未完成任务回到队列;不能确认的任务不强行推进。归档、过程文件、失败重试和发布排期也分别记状态,不用一张“完成数”表格替代整个系统。
这件事让我重新意识到,多设备协作的核心不是把工作平均切开,而是让工作在变化中仍然可接手。平均分配只在假设设备、任务和状态都一样时成立;真实世界里它们总会不同。与其追求表面上的整齐,不如把任务切到足够小,把边界写到足够清楚,再让系统根据实际情况继续往前走。