需求分析
作业分片方案
- 任务添加成功后,对于要处理的任务,会添加到待处理任务表中,现在启动多个执行器实例去查询这些待处理任务,此时如何保证多个执行器不会重复执行任务?
- 在上一小节的测试中,每个执行器收到广播任务有两个参数,分片序号和分片总数
- 每个执行器从数据表取任务时,可以用
任务id
对分片总数
取模
,如果等于该执行器的分片序号,则执行此任务 - 例如
- 1 % 2 = 1,执行器2执行
- 2 % 2 = 0,执行器1执行
- 3 % 2 = 1,执行器2执行
- 4 % 2 = 1,执行器1执行
- 以此类推
- 每个执行器从数据表取任务时,可以用
保证任务不重复执行
- 通过作业分片方案,保证了执行器之间分配的任务不重复执行
- 但是如果同一个执行器,在处理一个视频的时候,还没有处理完,此时调度中心又来了一次请求调度,为了不重复处理同一个视频,该怎么办?
- 首先配置调度过期策略
- 调度过期策略:
- 忽略:调度过期后,忽略过期的任务,从当前时间开始重新计算下次触发时间;
- 立即执行一次:调度过期后,立即执行一次,并从当前时间开始重新计算下次触发时间;
- 调度过期策略:
- 这里我们选择
忽略
,如果立即执行一次,可能会重复调度 - 其次,我们在看阻塞处理策略。
- 阻塞处理策略就是当前执行器正在执行任务还没有结束时,调度中心又请求调度,此时该如何处理
- 阻塞处理策略:调度过于密集执行器来不及处理时的处理策略;
- 单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
- 丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
- 覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;
- 阻塞处理策略:调度过于密集执行器来不及处理时的处理策略;
- 这里选择
丢弃后续调度
,避免重复调度 - 最后,也就是要注意保证任务处理的
幂等性
,什么是任务的幂等性
?- 任务的幂等性是指:对于数据的操作不论多少次,操作的结果始终是一致的。
- 执行器接收调度请求去执行任务,要有办法去判断该任务是否处理完成,如果处理完则不再处理,即使重复调度处理相同的任务也不能重复处理相同的视频。
- 什么是幂等性?
- 它描述了一次和多次请求某一个资源,对于资源本身应该具有相同的结果
- 幂等性是为了解决重复提交问题,比如:恶意刷单、重复支付等
- 解决幂等性常用的方案
- 数据库约束,例如:唯一索引、主键
- 乐观锁,长用户数据库,更新数据时根据乐观锁状态去更新
- 唯一序列号,操作传递一个唯一序列号,操作时判断与该序列号相等,则执行
- 这里我们在数据库视频处理表中添加状态处理字段,视频处理完成更新状态为完成,执行视频前判断状态是否完成,如果完成则不再处理
业务流程
- 确定了分片方案,下面梳理哼歌视频上传以及处理的业务流程
- 上传视频成功,向视频待处理表中添加记录,视频处理的详细流程如下
- 任务调度中心广播作业分片
- 执行器收到广播作业分片,从数据库读取待处理任务
- 执行器根据任务内容MinIO下载要处理的文件
- 执行器启动多线程去处理任务
- 任务处理完成,上传处理后的视频到MinIO
- 将更新任务处理结果,如果视频处理完成,除了更新任务处理结果之外,还要将文件的访问地址更新至任务处理表及文件中,最后将任务完成记录写入历史表
- 下面是待处理任务表