异步作业调度系统(代号:Razer)为网易视频云提供底层任务调度和资源管理服务,对非实时作业如视频转码、视频合成、文件转换等进行分发,并按照用户限额原则、资源最大利用原则对底层集群资源进行支配和规划。
为了调度的高可用和调度的能力的水平扩展,Razer本身是一个调度集群,将上层应用(app server)的作业分发到底层的执行服务器上(worker)。如下图:
一、资源管理
Razer提供多维度的管理服务,包括服务管理(注册、过期、探活、状态通知)、用户管理(增删、用户验证)、任务的实时统计(worker维度、user维度)、资源监控、全局配置信息、及自身的HA。同时,还为可视化运维平台提供相应的RPC接口,提供实时的数据来源。
更加全面的统计可以更好的感知集群的负载状况,进行合理的容量规划,以及更细粒度的追踪作业的生命周期,便于运维等。
资源管理功能模块如下图所示:
核心模块:
1)ClusterManager
负责服务节点的健康监测和状态维护,如果有节点服务不可用,会通知其他节点服务节点的变化情况。
2)UserManager
负责对上层应用进行管理,并提供用户粒度的统计信息。
3)JobTracker
对于可视化运维来说,最需要的数据就是实时的集群运行负载,不同粒度下的job信息的统计以及job的追踪。JobTracker负责跟踪Job的生命周期中的各个事件,并负责悬挂job的检查和处理。
二、分发调度
在公有云资源超售的背景下,Razer的分发必须保证一定的公平性,避免饥饿。
应用通过RPC向Razer发起离线任务调度的请求,通过一致性hash按用户分区调度到不同的Razer节点上。Razer将接收的调度任务塞入不同用户的有序队列,Scheduler模块根据用户最大限额原则和公平原则,将不同用户的队列中的元素丢入分发器的内部队列,最后由分发器Dispatcher将允许调度的任务分发到MQ中,由worker完成具体视频处理任务。
核心模块:
1)Feeder
离线调度任务的生产者,任务可以来自上层应用,也可以来自数据库中的积压任务。从任务产生的策略上来分,可以分为GreedyFeeder和LazyFeeder。
LazyFeeder任务来自数据库。当用户队列的job数小于一定数值时,会触发LazyFeeder的填充动作。GreedyFeeder任务直接来自于应用,GreedyFeedy始终会主动尝试feed job。
2)Schuduler
任务调度器,根据用户最大限额原则和公平原则,封装了razer异步调度的核心逻辑。
最大限额原则是指,调度到底层worker服务器上去执行的job数不会超过用户的配额。
公平原则是指,每个用户被调度出去的job数的占比越低,则其调度的优先级越高。
3)Dispatcher
任务分发模块,负责将Job下发到底层Worker服务器。
Dispatcher对Job进行了进一步的封装,每个job会携带上一个job。如果任务分发失败的原因是底层没有资源,或者发送超时,则上一个job可能并未发送成功,此时,并行分发转变为串行分发,保证作业的顺利分发和执行。
4)UserView & GlobalView
UserView是用户运行时信息,包括任务队列,running等各种计数,是任务调度的依据。
GlobalView包含了所有UserView,维护全局运行时信息。
三、核心技术
1)基于快照的调度
GlobalView中保存着所有的UserView,是用户运行时的一个全局视图。用户的统计数据是在时刻变化的,所以在调度作业的时候,会对所有可调度的UserView排序形成一个快照,在一定时间内,以快照的数据为依据进行调度,并在超时后重新构建快照。
基于快照调度可以解决饥饿问题,如果一个用户的短任务非常多,若已时刻在变的数据作为调度的依据,可能导致其他用户的任务一直无法执行。
2)高可用
Razer支持水平扩展,通过一组调度服务器实现高可用。
应用可以跨节点重试任务,保证任务的顺利下发。
Razer在挂掉重启后,也会recover自身积压的任务。当某个节点宕机时,资源管理模块会感知,并通知其他节点,按照一定的算法指定一个节点take over。
3)负载均衡与配额
Razer通过用户ID进行分区,不同的用户落在不同的Razer服务器上。实现一定的负载均衡。而且,每个用户落在一个固定的分区,更加易于实现用户配额的限制。