技术背景:
深度学习平台(或存在异步任务调度的平台),存在不同的操作用户,用户存在不同的部门,调度的硬件服务器资源,按照不同的资源类型,操作系统,GPU卡的型号区分成不同的资源组,CPU资源,或者调试任务和训练任务区分,例如操作用户A,操作用户B,属于不同的部门,均具有对于资源组1080ti资源组的访问权限,且资源1080ti下只有1台1080ti的8卡的GPU服务器,用户A提交训练任务A-1需要8张卡,提交训练任务A-2需要4张卡,用户B提交训练任务B-1要4张卡,提交任务B-2需要1张卡,需要满足的功能业务需求点:
- 不同资源的排队任务的情况查看
- 对于用户的针对的资源的访问的Priority有管理员进行设置,Priority(1)~Priority(k)
- 根据用户的对于资源的等级可以优先抢占资源
- 对于同等优先级的任务和对于同一个用户提交的任务按照时间顺序进行排队等待
- 管理员可以根据任务的情况和状态删除排队中的任务
- 管理员或具备管理员权限的用户可以调整任务的位置,比如,调整到队列的头部,调整到队列的指定位置,调整到队列的尾部
以时间和用户对于资源的角色权重,完成对于资源组下的有限的资源的合理调度,并根据训练任务的和硬件资源组的特色提升硬件资源的利用率。
固有的深度学习的任务的调度策略为使用RabbitMQ,不同版本的RabbitMQ调用任务没有任务优先级策略,且无法满足灵活调整排队任务的如上功能特色需求和更高的性能需求,故基于Redis的zset的内存数据和zset本身的数据结构特色(根据Score自动排队)和数据持久化策略来实现高性能分布式任务调度队列的方法的方案来解决此深度学习平台的应用场景或存在类似场景的需求。也可产品上自行封装实现类似功能的zset的数据结构和数据持久化管理策略
核心创新点:
- 通过用户的权重和时间戳管理生成任务的综合Score,原理简单方便理解
- 以zset的特殊的高性能数据库结构,实现调度任务的自动高性能的排队
- 结合Redis内存数据库和磁盘持久化队列,解决分布式调度队列的高性能和灵活性依旧数据的可靠性的平衡
- 以任务的关键要素Score,以简单调整队列任务的Score完成高效的调整任务的位置的方法
- 基于Redis的内存数据库形式,可以进行分布式调度,且性能更加优秀
同时需要解决的调用约定,同样Priority根据对于资源的请求时间来排队,如下的方案步骤:
1.以资源的分组的创建资源自身的队列(Redis的zset)
2.用户A的训练任务1卡A-1和用户B的训练任务2卡B-1创建训练任务
3.信令服务接收创建命令,根据用户的信息获取用户的Priority信息和获取系统的ticker时间,根据策略公式生成训练任务的Score,把任务放入任务队列,基于如下计算公式:Score = 权重因子*Priority + 时间戳(系统的32位ticker时间),例如权重因子:100000000000
4.消费进程或消费线程直接从队列Redis的zset取优先级Score最高的消息进行处理
5.Redis实例进行定时持久化到本地磁盘,以处理任务消息的异常发生时的持久化动作
6.系统管理员可以直接修改权重因子直接调整任务在队列中的位置
7.调整任务在排队中的任务的位置情况,按照如下策略计算Score,同一个任务可以反复调整
1)调整到头部,Score = 队列头部任务Score + 1
2)调整到尾部,Score = 队列尾部任务Score - 1
3)调整到中间位置,Score = (目标位置的前一个任务Score + 目前位置的后一个任务Score) / 2
8.消费进程根据运行中的任务的情况和调度任务的情况设定任务的回馈信息,如:排队中,硬件资源不足,调度中。