珍岛集团致力于打造全球领先的智能营销云平台,在国内率先推出的Marketingforce(营销力)平台,专注于人工智能、大数据、云计算在数字营销及企业数字化智能化领域的创新与实践,面向全球企业提供营销力软件及服务,以一站式智能营销生态助力企业进行数字化转型。
之前,珍岛集团使用完全开源的Apache DolphinScheduler任务调度框架,随着业务的发展,以及数据集成平台和GMA,算法计算平台越来越多的业务需求,开源版本的Apache DolphinScheduler已经不能完全满足需求,迫切地需要对Apache DolphinScheduler做一些定制化的开发。以下是珍岛集团团队最近一年在开源版本的基础上进行的优化和改进。
1.期待简单易用,低代码的方式;
2.Plug-in足够多,能够符合各业务模块需求;
3.活跃的开源社区,优秀的人才;
4.技术栈能够和珍岛现有各业务模块高度吻合;
5.后期新建业务模块时,不需要过多的二次开发。
对调度系统的稳定性要求高;
高并发情况下,任务能够正常执行。
拿一个简单的业务来举例,当用户通过配置设置好受众的特征,需要能够在指定的时间内,通过离线数据和算法,将具体的目标受众计算出来,并且将优惠卷或者消息通过各种渠道推送给目标受众,如果产生延迟,或者错误,就会使用户产生损失。另外,还要满足能够抗住夜间4000个流程实例同时启动,并且正常运行的需求。
在珍岛集团,业务层以数据集为例,数据集将业务数据转换成二次开发后暴露的公共接口需要的参数,业务执行过程通过MQ将实例信息发送给业务方,当流程定义满足于配置的告警策略,将发送自定义邮件和企微信息,如果是DataX类型任务,则调用K8S的API,并通过异步的方式获取日志信息。
背景:
在珍岛内部,很多模块都需要调度中心调度,例如数据的ETL,标签模块、算法模型模块都需要系统调度,各模块需要Apache DolphinScheduler的状态,历史记录等数据,并在自己的模块实现自己的业务,然而各模块和Apache DolphinScheduler使用的不是同一个数据库。于是我们就需要将Apache DolphinScheduler中的一些信息推送给各个模块,使得各模块能够更灵活的使用这些信息。
当有新的业务模块需要使用Apache DolphinScheduler,只要按照给定的结构去保存,并接收处理Apache DolphinScheduler返回的MQ消息即可。
解决方案:
通过MQ将状态,流程实例,任务实例等状态传递给各模块。
我们新增了四个自定义注解,用于流程实例和任务实例的新增与状态变更。
以创建流程实例为例:
对于Apache DolphinScheduler而言,某个任务实例失败了,那么该任务实例的下游就不执行,也不生成记录了,但是对于有些业务来说,可能会想知道整个任务执行时涉及到了哪些节点(用户未运行整个画布),所以我们又稍微做了一些改造,将本次流程实例涉及到的节点也全部返回了。
背景:
Apache DolphinScheduler 默认的邮件消息格式过于死板,对于客户来说不够友好。
解决方案:
对于用户来说,用户是看不懂源生Apache DolphinScheduler的邮件的,我们将Apache DolphinScheduler 以及业务中的一些参数交给用户,使得用户能够自定义邮件内容,业务数据相关的占位符由业务解析,解析完成之后将数据再移交给Apache DolphinScheduler,Apache DolphinScheduler再接着处理和自身相关的占位符变量。
背景:
夜间定时任务多,并发量大,在该时间段内需要的资源多,但是日间需要资源相对少很多,如果使用K8S可以释放出来给其他模块使用;
DataX节点运行在worker 机器上,并发大的时候,资源使用率陡增,参数设置不正确,可能会导致OOM 的情况,交给K8S运行可保证其稳定性;
worker应该只做提交任务的工作,而不是负责具体任务的运行;
减少给予worker的配置资源。消耗资源小的可以运行在本地,消耗资源大的运行在k8s上。
解决方案:
改造DataX组件,再生成job 的JSON 之后交给K8S处理,k8s调用自定义的DataX镜像,并异步获取K8S 的job日志。当job完成之后就释放掉该job的资源。
对于数据集成平台来说,用户一定会有许多非JDBC类型的数据源需要抽取。所以我们做了以下改造:
解耦DataX的reader和writer 的生成方式
支持动态更新自定义模版,原先的DataX类型任务,开启自定义模版,保存后存储的信息就固定了。如果数据源的账号密码或者其他信息改变。再次执行还是历史保存的信息。
背景:
1. 目前客户的一些数据源信息,不一定是JDBC类型的数据源,例如抖音粉丝数据属于API接口调用,HDFS。又或者说HBase的结构和普通的RDBMS的结构不一样。所以目前的DataX节点不足以满足我们全部的需求。
2.对于业务模块来说,更倾向于使用JSON形式,因为JSON更灵活,能够完全使用DataX的功能,但是使用自定义模版会出现以下情况:用户新建数据源a,数据源a 的密码是123,并用数据源a生成流程定义A,运行A,没有问题能够正常执行,此时将数据源a的密码修改为456,再次执行A,报错。如果a关联了很多很多流程定义,手动改就会很累,而且找到a关联的流程定义也需要额外的接口去做,这不符合用户习惯。
解决方案:
将数据源Id 也放入JSON中,运行时重新拼接JSON,自定义抽象类,将DataX的reader 和writer 生成分离,JDBC走公共的一套,其他非JDBC或特殊类型走自己派生的逻辑。
在Apache DolphinScheduler中各类型节点使用同一套正则表达式隐藏日志,不够灵活。共用一套也可能产生互相影响。于是我们根据节点的类型来配置各自需要隐藏的内容。
另外,在使用Apache DolphinScheduler的过程中,我们还发现了一些或大或小的使用问题,为了更好地使用,我们对其中一些问题进行了优化修改,并提交了PR。比如:
今年Apache DolphinScheduler刚上线时,我们发现某些项目的SUB_PROCESS节点,明明已经运行完毕,但是还是运行中的状态。通过排查发现父流程实例的失败策略为结束,并且选择并行策略。当subprocess类型节点很多的时候,一部分子流程实例已经运行成功,但是subprocess 在父流程中的任务实例还未更新成完成状态,此时一个subprocess 类型节点失败了,父流程会杀死所有存活的任务实例,所有存活的subprocess关联的子流程实例会被强制更新为ready stop 状态,导致父流程中的任务实例无法更新,所以一直显示提交成功,或者运行中状态。对此,添加subprocess 任务状态的判断条件,即可解决此问题。#14169
当任务有有问题,会造成死循环,疯狂打日志,最后磁盘打满,Apache DolphinScheduler不再执行任务的问题,同时编辑画布导致任务死循环报错的问题。对此,建议当业务出现问题时跳出死循环,以此减少日志疯狂打印,避免磁盘刷满的问题。 #13045 #13053
Switch类型的任务,当switch的分支的扭转,再次交合时,执行的流程不符合预期。对此,当Switch 节点执行后续节点的分析出现了问题,可以将不该跳过执行的节点放入了skipTaskNodes中,修改switch的编排逻辑,以此解决该问题。#14537
针对当任务执行后,只会在执行完成后更新pid的问题,我们新增一个事件类型,在进程阻塞等待任务执行完毕之前,通过netty 将pid 传递给master 并及时更新到数据库。#13201
此外,在参数调优上,我们还调整了quartz 框架的org.quartz.jobStore.misfireThreshold参数,可以在夜间承载更多的并发。
还修改了check4timeOut的超时时间,以便能够减少日志大小,减少磁盘消耗。
Apache DolphinScheduler稳定的赋能业务增长的客户全域数据平台,整合客户全渠道数据,统一用户档案与标签体系,赋能用户洞察与业务增长。同时,它还支持多种数据源集成,如实时数据、离线数据,并实现了跨类型、跨源数据的全链路打通。利用Apache DolphinScheduler给类型节点,通过低代码的形式使得业务部门可参与编码,显著节省了 ETL 人力,降低了维护成本。
通过近一年我们对 Apache DolphinScheduler 进行优化,近半年公司没有出现高级别的BUG。
珍岛信息技术(上海)股份有限公司,简称珍岛集团,成立于2009年,致力于打造全球领先的智能营销云平台,也是国内率先推出的Marketingforce(营销力)平台,专注于人工智能、大数据、云计算在数字营销及企业数字化智能化领域的创新与实践,面向全球企业提供营销力软件及服务,现已形成IaaS(云计算)、PaaS(开放中台)、All-in-one AI SaaS智能营销云平台。以营销云、销售云两大业务体系为支撑,珍岛以一站式智能营销生态助力企业开启数字化转型之旅。
感谢韩玉林,顾琦琦,以及珍岛运维部和数据平台部的协助与优化意见
感谢Radeity,ruanwenjun,以及DolphinScheduler 社区的帮助与建议
作者简介
伏长海
珍岛集团开发工程师
Apache Dolphinscheduler Contributor
本文由 白鲸开源科技 提供发布支持!