V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
axunnnn
V2EX  ›  程序员

请教大佬,一个批量生成视频并上传方案的困扰

  •  
  •   axunnnn · 2022-04-08 01:49:02 +08:00 via iPhone · 1950 次点击
    这是一个创建于 965 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在我想的方案是生成视频丢一个队列 1 ,生成成功丢另一个队列 2 上传( oss ),包括上传封面图片之类乱七八糟的。最后彻底完成的视频写数据库。<br/> <br/>

    问题是 是分多个 server 本地生成的,丢到队列里出一点错,跑到另一个 server 里一查发现没有,又要重新生成。<br/> <br/>

    还有个严重问题是,视频上传很慢,彻底完成的条件又很多:视频传完,转码完,封面图片传成功,其他信息传成功。怎么判定它彻底成功呢?成功一项就写一列数据库,不停查数据库这几列来判断吗?感觉有点蠢。<br/> <br/>


    最后越改越觉得队列很多判定很杂,队列 2 里面发现东西不全又打回队列 1… 整个流程都越看越不满意。感觉经验太少。<br/> <br/>

    求问各位有没有清爽的解决方案?或者局部优化?大感谢!
    13 条回复    2022-04-09 22:35:51 +08:00
    documentzhangx66
        1
    documentzhangx66  
       2022-04-08 02:10:32 +08:00
    学习使用 Visio ,来画流程图。

    这种比较复杂的流程,第一次做的话,先画流程图。
    Immortal
        2
    Immortal  
       2022-04-08 03:56:40 +08:00
    没有经验,说下我初步的思路:
    1. 因为上传和封面图等都是基于"视频生成".所以一开始生成视频是线性,后面都是并发.如果后续操作失败可以回退到"生成后的视频"这一步重新尝试,只要能保证原始视频能正常生成且在所有操作完成前只生成一次即可.
    2. 数据记录上不一定需要多条数据,一条视频用一条记录就可以了.像这类 bool 类型(成功或者失败)的复合操作可以用 2 进制来记录,很容易判断是否完成或者哪一步没完成.(比如总共 5 个步骤,全部完成即 11111),每一步操作后可以 update 这条数据上自己对应的操作位.
    Immortal
        3
    Immortal  
       2022-04-08 03:58:47 +08:00
    @Immortal #2
    补充下
    数据库记录操作状态还是用十进制记录(11111=>31),封装几个函数来做操作的标记和查询即可
    macrorules
        4
    macrorules  
       2022-04-08 07:16:14 +08:00
    处理过类似的,一个任务分多个阶段,用 Type 表示:Prase1, Prase2, Prase3,... worker 完成一个阶段就交给一个统一的 manager 处理,由 manager 触发第二阶段,如此类推

    那么,对一个视频而言,可以先生成它的封面图( P1),然后上传视频(P2), 转码(P3), 等等,每个阶段的成果确保没问题,这样如果某个特殊阶段出错,重新执行的成本也不会很高。另外我觉得不同阶段的属性可以用文本记录,比如 json, txt 等,不需要数据库,这样减少对中心的依赖,每个任务包括都是 self-explained 的
    playniuniu
        5
    playniuniu  
       2022-04-08 09:11:51 +08:00 via Android
    这种需求 用 airflow 之类的任务调度工具来做比较省事
    3dwelcome
        6
    3dwelcome  
       2022-04-08 09:51:31 +08:00
    "成功一项就写一列数据库,不停查数据库这几列来判断吗?感觉有点蠢。"

    不用你去循环查,一些数据库有回调通知机制的吧,写一点触发器。
    axunnnn
        7
    axunnnn  
    OP
       2022-04-08 21:41:00 +08:00 via iPhone
    @documentzhangx66 你说的对 受教
    axunnnn
        8
    axunnnn  
    OP
       2022-04-08 22:52:58 +08:00
    @Immortal 生成这步 也申请了多台服务器,并行进行的。所以其实导致了 上面提的一个问题,就是当这个视频在上传的过程中出错 被打回之后,它会去本地 server 找源视频,但好几台服务器 它只能找本地就不一定找得到,就又得重新生成,就尴尬
    2 很机智哎感谢!但是其实 mysql 里相应列存的是它的 url ,比如封面图需要存 url 。只是顺便兼任 boolen 的判断。这里其实之前也有过纠结,需不需要再开一个或者再在哪里,单独记录一下状态呢?最后是没有建
    axunnnn
        9
    axunnnn  
    OP
       2022-04-08 22:56:03 +08:00
    @macrorules 你说的很对,感觉从另一个层次梳理了应做的事。那么这个记录需要是全局共享的,因为现在是有多个服务器来一起生成视频,对分布式还不太熟,有什么好 tools 建议吗
    axunnnn
        10
    axunnnn  
    OP
       2022-04-08 22:59:24 +08:00
    @3dwelcome 是查到过回调的使用!但不熟且很多困惑就搁置了。那么如果用回调的话,我看一些系统设计的文章,都在讲视频上传这类耗费时间的事要用 mq 。那么用 mq 和直接回调标记的区别在哪呢?什么时候选用哪个呢?仅是场景规模大小的问题吗
    Immortal
        11
    Immortal  
       2022-04-09 02:49:25 +08:00
    @axunnnn #8
    1. 没有理解你说的并行生成的概念,这样不会导致视频重复上传吗?
    2. 你说的用"业务字段"来判断是否已经完成确实是可以的,但是如果遇到没有数据记录的阶段就无法判断,而且统一用一种逻辑去判断过程我觉得在代码上更加内聚,不然不同操作是否成功用各种字段去判断显得代码很"散".
    axunnnn
        12
    axunnnn  
    OP
       2022-04-09 17:31:35 +08:00
    @playniuniu 搜了一下 很厉害的样子 谢谢
    axunnnn
        13
    axunnnn  
    OP
       2022-04-09 22:35:51 +08:00
    @Immortal 是这样的,各服务器都会起几个进程,redis 是生产消费者模式,大量 id 进入队列后每一条 id pop 出,在随机一台服务器生成视频,在生成的过程中不会重复生成。但是如果在第二段丢入上传队列时出错,再次上传时,未必能在当前服务器本地找到源视频,这时会再次就地重新生成。
    2 对 位判断更简明。其实这里纠结的是是否要多出一重位判断(A)的步骤,因为业务字段( B )是必须的,trade off 不是 A or B 取舍,而是是否要额外加 A ,以及多一个步骤附带的可能的衔接处丢消息,空间开销等等。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3562 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 11:11 · PVG 19:11 · LAX 03:11 · JFK 06:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.