Open cjuexuan opened 5 years ago
每个公司可能都有自己的任务调度系统,我司也不例外,那么一个合格的调度系统到底该有哪些功能呢,这里又能产生什么样的价值呢, 今天我们来简单的讨论下这个问题
从我们调度系统的发展过程来看,我觉得是可以分成几个阶段的
首先,在刚开始做调度系统的时候,我们当时的目标用户是数仓,数仓会用什么呢,会用sql(xql)来描述自己的etl任务,那我们需要做的事情就是能让这些任务在规定的时间跑起来,能指定每个任务需要的一些配置参数。 另外任务和任务之间难免会有一些依赖关系,所以调度系统要能帮助他们管理这些依赖关系
当时我司其实有一个任务调度框架,叫data-task,这个系统是从mr时代就有的,可以描述任务和任务的依赖关系,不过当时这个二方包之前是给开发用的,他们用xml在自己项目里管理这些任务就可以了,但对于数仓的小伙伴来说,这显然太过于麻烦了,因为他们的task类型也是固定的,都是sql系列的,而且对于数仓来说,每天常态化的任务编辑之后需要重新发布上线显然是不合理的,所以当时第一版本的目标就是对于调度框架做一个web的封装,支持上述的那些基本需求就可以。这个系统大概是16年上线的,当时这一块还不是我这边负责的
随着任务越来越多,用户就给我们接着提需求了,首先有了各种报警的需求,之前我们的报警是统一设置的策略,但是按照业务的优先级不同,这些任务也应该有着不同的报警策略,所以我们重点支持了下这一块的需求,我们目前把全部的场景都交给用户去配置,如果用户没配的情况下才会用我们平台提供的默认策略,这些场景包括了以下情况
另外在刚线上的时候,因为白天任务比较少,所以如果有功能升级的话,我们一般会选择白天升级,但随着任务增加的话,每次发布的时候其实我们还是蛮紧张的,万一没发成功,哪怕回滚啥的也要1-2分钟,这中间可能就漏掉了用户的调度任务了。所以自从我们团队接手这个项目之后,我们就决定对调度系统的整体架构做一个重构升级。我们这个项目内部代号叫panda,为啥叫panda呢,其实是我觉得dota里的熊猫酒仙开大之后非常炫酷,有很多技能,并且能一起操作多个单位,并且一个分身死了以后也不会导致英雄死亡,这一点就满足了我们这个系统的美好寓意:高可用的支持,能进行灰度的发布上线,一个节点有问题不会影响到整体。另一个原因是我们团队还有个可视化系统叫unicorn,这是一个西方的神兽了,调度系统其实和看板关系还是蛮紧密的,所以我们取了个我国的国宝作为项目代号
那我们到底是怎么做高可用的,这里给一个架构的简图
我们用了akka cluster做了节点之间的通信,并且区分了节点的角色:用于发布任务的panda-console,充当了生产者的概念,用于执行任务的panda-executor,充当消费者的概念,这样我们如果发布的话,只需要用优雅停机的方式将需要下线的节点从集群里面摘掉,然后依赖db做一次recovery,将这个节点上正在执行的任务漂移到其他节点上去,这里需要补充说明的一点是:我们的executor节点实际也不跑真的在本地跑任务,而是将任务提交到其他执行引擎上去跑,比如提交到xql平台,发布spark任务到yarn上,或者调用一些远程的服务。所以下线存在漂移的一些基本条件,我们有两个下线模式,一个是等上面任务全部执行完才能将节点摘掉,一个是从下线开始的一瞬间就不接新任务,摘掉该节点,去其他节点上继续跑该任务。所以我们就把这一块做成了两阶段的:提交阶段,提交成功的标志是生成了唯一的id,比如yarn的appId,xql的commitId等。等待执行完成阶段,这个阶段我们会用上一步的id轮询系统,直到任务完成
其实这一块的话,目前我们也仅仅通过一些监控的数据做到了监控任务的最大消耗资源大小,然后按照任务的需要进行动态的增减。这一块也是调度的价值所在,统一的提交平台可以很容易的做到做一些钩子,这些钩子用来采集用户任务的性能指标,在用户无感知的情况下就接入到了监控系统中去,享受到了我们给他提供的资源的弹性分配需求。因为数仓的小伙伴对任务的调优也没啥经验,配置参数的时候很可能配置的过大或者过小,所以这一块的意义和价值还是蛮大的。另外随着数据量的不断增加,一些存量作业也需要用户子增加资源,所以这些弹性可能减少人工介入的环节,在超过一个阈值后就可以做出一些响应了
调度系统的迭代是一个循序渐进的过程,早期可以直接拿别人开源的系统直接来用,后续最好还是按照公司的业务发展选择一条合适的路去演进。在这个过程中,需要注意抽象出场景,把用户常见的操作复杂的功能去做流程简化操作,减少用户操作出错的概率,比如我们按照用户的操作习惯就提炼出了修复模式,重跑模式等新的调度场景,前者用来简化用户在任务失败的时候选中那些出错任务的步骤,后者用来解决用户去跑一些历史数据的时候,不需要改现有任务。在做b端系统的过程中一定要聆听用户的声音,但是也要注意提炼归纳,要考虑用户需求背后的价值,只有这样才能持续迭代我们的系统
背景
每个公司可能都有自己的任务调度系统,我司也不例外,那么一个合格的调度系统到底该有哪些功能呢,这里又能产生什么样的价值呢, 今天我们来简单的讨论下这个问题
从我们调度系统的发展过程来看,我觉得是可以分成几个阶段的
起步阶段
首先,在刚开始做调度系统的时候,我们当时的目标用户是数仓,数仓会用什么呢,会用sql(xql)来描述自己的etl任务,那我们需要做的事情就是能让这些任务在规定的时间跑起来,能指定每个任务需要的一些配置参数。 另外任务和任务之间难免会有一些依赖关系,所以调度系统要能帮助他们管理这些依赖关系
当时我司其实有一个任务调度框架,叫data-task,这个系统是从mr时代就有的,可以描述任务和任务的依赖关系,不过当时这个二方包之前是给开发用的,他们用xml在自己项目里管理这些任务就可以了,但对于数仓的小伙伴来说,这显然太过于麻烦了,因为他们的task类型也是固定的,都是sql系列的,而且对于数仓来说,每天常态化的任务编辑之后需要重新发布上线显然是不合理的,所以当时第一版本的目标就是对于调度框架做一个web的封装,支持上述的那些基本需求就可以。这个系统大概是16年上线的,当时这一块还不是我这边负责的
成熟阶段
随着任务越来越多,用户就给我们接着提需求了,首先有了各种报警的需求,之前我们的报警是统一设置的策略,但是按照业务的优先级不同,这些任务也应该有着不同的报警策略,所以我们重点支持了下这一块的需求,我们目前把全部的场景都交给用户去配置,如果用户没配的情况下才会用我们平台提供的默认策略,这些场景包括了以下情况
另外在刚线上的时候,因为白天任务比较少,所以如果有功能升级的话,我们一般会选择白天升级,但随着任务增加的话,每次发布的时候其实我们还是蛮紧张的,万一没发成功,哪怕回滚啥的也要1-2分钟,这中间可能就漏掉了用户的调度任务了。所以自从我们团队接手这个项目之后,我们就决定对调度系统的整体架构做一个重构升级。我们这个项目内部代号叫panda,为啥叫panda呢,其实是我觉得dota里的熊猫酒仙开大之后非常炫酷,有很多技能,并且能一起操作多个单位,并且一个分身死了以后也不会导致英雄死亡,这一点就满足了我们这个系统的美好寓意:高可用的支持,能进行灰度的发布上线,一个节点有问题不会影响到整体。另一个原因是我们团队还有个可视化系统叫unicorn,这是一个西方的神兽了,调度系统其实和看板关系还是蛮紧密的,所以我们取了个我国的国宝作为项目代号
那我们到底是怎么做高可用的,这里给一个架构的简图
我们用了akka cluster做了节点之间的通信,并且区分了节点的角色:用于发布任务的panda-console,充当了生产者的概念,用于执行任务的panda-executor,充当消费者的概念,这样我们如果发布的话,只需要用优雅停机的方式将需要下线的节点从集群里面摘掉,然后依赖db做一次recovery,将这个节点上正在执行的任务漂移到其他节点上去,这里需要补充说明的一点是:我们的executor节点实际也不跑真的在本地跑任务,而是将任务提交到其他执行引擎上去跑,比如提交到xql平台,发布spark任务到yarn上,或者调用一些远程的服务。所以下线存在漂移的一些基本条件,我们有两个下线模式,一个是等上面任务全部执行完才能将节点摘掉,一个是从下线开始的一瞬间就不接新任务,摘掉该节点,去其他节点上继续跑该任务。所以我们就把这一块做成了两阶段的:提交阶段,提交成功的标志是生成了唯一的id,比如yarn的appId,xql的commitId等。等待执行完成阶段,这个阶段我们会用上一步的id轮询系统,直到任务完成
智能阶段
其实这一块的话,目前我们也仅仅通过一些监控的数据做到了监控任务的最大消耗资源大小,然后按照任务的需要进行动态的增减。这一块也是调度的价值所在,统一的提交平台可以很容易的做到做一些钩子,这些钩子用来采集用户任务的性能指标,在用户无感知的情况下就接入到了监控系统中去,享受到了我们给他提供的资源的弹性分配需求。因为数仓的小伙伴对任务的调优也没啥经验,配置参数的时候很可能配置的过大或者过小,所以这一块的意义和价值还是蛮大的。另外随着数据量的不断增加,一些存量作业也需要用户子增加资源,所以这些弹性可能减少人工介入的环节,在超过一个阈值后就可以做出一些响应了
总结
调度系统的迭代是一个循序渐进的过程,早期可以直接拿别人开源的系统直接来用,后续最好还是按照公司的业务发展选择一条合适的路去演进。在这个过程中,需要注意抽象出场景,把用户常见的操作复杂的功能去做流程简化操作,减少用户操作出错的概率,比如我们按照用户的操作习惯就提炼出了修复模式,重跑模式等新的调度场景,前者用来简化用户在任务失败的时候选中那些出错任务的步骤,后者用来解决用户去跑一些历史数据的时候,不需要改现有任务。在做b端系统的过程中一定要聆听用户的声音,但是也要注意提炼归纳,要考虑用户需求背后的价值,只有这样才能持续迭代我们的系统