更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群

背景介绍

业务场景

在日常工作中,我们时不时需要对某些逻辑进行重复调度,这时我们就需要一个调度系统。根据不同的调度需求,可以广义分为两类:

定时调度

根据一定的周期对任务进行重复调度。这类比较容易实现,通常一个crontab就可以对任务进行定期调度。但是简单的crontab任务在实际生产中应用会有一些挑战,包括失败处理、监控以及部署、跨机器部署、重试等。

依赖调度

依赖调度类型,通常是指某个逻辑的触发需要在特定的“事件”发生之后,这个事件可以是上游某个任务完成,也可以是某个指定路径数据就绪,或者其他外部触发等。任务间的依赖会形成一个Worflow,典型的一个简单WorkFlow 如下图:
上图中,“计算用户留存率”需要等待“数据预处理”完成,那么“计算用户留存率”就对“数据预处理”任务产生了依赖。任务间的依赖可以有“业务时间偏移”需求,如“计算留存率”需要根据今天的数据与7天前的数据进行计算,那么这个节点需要同时依赖“数据预处理”当前业务日期的任务实例以及7天前的任务实例。只有当两个业务日期的实例都成功了,才会触发当天的“计算用户留存率”任务,避免产生脏数据。

业界选择

调度系统在业界已经有不少方案,初期也调研了相关的开源调度系统。主要包括以下几个

Airflow

Airflow最早是由Airbnb开发然后贡献到Apache中的一个调度系统,目前使用较多,社区也比较活跃。用户可以通过Python定义工作流以及调度频率等。Airflow 定位是一个通用的调度系统,支持单节点以及多节点部署。整体架构图如下
其中调度的主要逻辑在 Scheduler 模块中,Scheduler 通过“轮询“的方式从数据库中拉取需要运行的任务交由 Worker 去运行。多节点模式下,Scheduler 是通过 Celery 进行任务分发给多个Worker中。需要说明的一点是,即使在多节点模式下,Scheduler本身也是一个单点故障。

Azkaban/Oozie

Azkaban和Oozie分别是由LinkedIn和Apache开源的调度系统,重点专注于Hadoop Batch的调度,更好的集成了Hadoop 相关功能,方便用户可以简单跑起Spark/Hive 等任务。其中与Airflow 不同的是Azkaban 和Oozie是通过配置/DSL 的形式来进行DAG的配置。在社区活跃度上与Airflow相比有一定的差距。

其他开源系统

其他开源的还有一些类似DolphinScheduler等,既然有了这么多开源的系统,我们为什么还决定自己造轮子 - FlowX?
  • 我们需要的调度系统定位是一个通用的的调度系统,能够处理多种节点类型;
  • 高可用,可伸缩。这个调度系统会承载着类似基础数仓等一些核心链路,需要保证调度的高可用。同时随着公司业务的不断发展,预期调度的任务数会快速上涨,需要能够水平扩容;
  • 易二次开发,公司的业务针对调度系统会有一些定制化需求,如支持自定义镜像、增加控制节点、增加超时自动重试等功能,需要可以低成本地对系统改造;
  • 易于集成,做为一个集中化的调度系统,计划与公司其他系统进行集成,如根据任务的依赖关系可以提供数据血缘功能,供数据地图工具使用;

调度能力介绍

Functional

  • 支持定期调度(分钟级、小时级、天级、每周或者每月的某几天)
  • 支持依赖执行 -- 任务间的依赖 -- 外部HDFS/Hive partition 依赖 -- 任务自依赖(依赖前一个业务时间的实例) -- 支持不同周期的任务依赖,比如小时级别的任务可以依赖天级别的任务 -- 支持依赖业务时间偏移(如当前实例依赖n天前上游任务实例,或者历史某段时间的上游任务实例)
  • 支持暂停、取消运行中实例,失败自动重试和告警
  • 历史数据回补
  • 可以针对Worflow中指定节点以及全部下游进行重跑以修复如数据质量引起的问题
  • 任务并行量的控制
  • 依赖推荐 -- 系统会根据用户的SQL逻辑自动提取出所需依赖的上游表 -- 如果上游表是调度系统内的任务产出的,那么会推荐出上游任务 -- 如果上游表不是系统内的任务产出的,那么会推荐Sensor探针任务

Non-functional

  • 保证高可用、扩展性和故障恢复的准确性,不漏调度和不重复调度
  • 调度延迟秒级
  • UI以及API多重配置方式

技术实现

基本概念

DAG

DAG全称是Directed Acyclic Graph(有向无环图)。调度系统里,一个DAG表示一组相关的任务,任务之间的依赖关系用一个有向边来表示。如下图所示,A到B有一条边,代表A是B的前置任务,即任务B依赖任务A的运行。
如图所示的任务依赖关系,一种有效的执行顺序是A -> G -> B -> D -> C -> E -> F。

任务

调度系统中DAG中的每个节点代表一个任务,代表着一段逻辑,用户可以在任务里面实现不同的业务逻辑。

实例

系统根据每个任务指定的业务日期会产生的一个实例,实例是调度的基本单位。同时任务之间的依赖关系最终都会转化为实例间的依赖关系。

系统架构图

模块解析

WebService

WebService做为外部系统与用户交互的主要入口,用户通过UI/API创建任务等操作是通过WebService进行交互的。主要的功能如下:
  • 权限检查
  • 任务开发以及运维
  • 实例运维
  • 日志信息获取
  • 项目管理

Master

Master 是系统的“心脏”。目前Master的容灾是通过ZK进行主备的。Master的主要功能包括任务依赖图的管理、调度优先级管理、Quota管理、实例分发、Scheduler和Worker的监控。
  • 任务依赖图管理
    • 维护任务间的依赖关系,并且提供Service给其他模块,如查询某个任务的上游以及下游等信息。
    • 生成计划/重跑实例,向 scheduler 发送 INSTANCE_CREATE 事件。同时Master会定期提前生成未来一段时间内需要运行的实例。
  • 调度优先级管理
    • 借鉴yarn的公平调度算法思路来解决高负载情况下调度顺序的问题。通过任务属性划分优先级队列,确保任务根据优先级有序调度,达到流控&加权均衡的目的
  • Quota管理
    • 通过多维度指标 + 正/反向匹配 + 时间区间限制来灵活匹配目标任务,限制对应的并发度,来达到“凌晨保证系统调度资源,白天保证回溯重跑数据资源”或者“限制eval task占用过多资源”等提高系统资源利用率的目的
  • 实例分发
    • 通过依赖检查并且到达计划时间的实例会由master进行分发
    • 根据不同的任务类型,Master会决定交由worker去执行还是直接提交到K8s中
  • 模块监控
    • 维护当前活跃的Scheduler列表,创建的实例会交由对应的Scheduler 去进行调度检查。
    • 维护当前活跃的Worker列表,将实例分发到对应的Worker/k8s去执行。
    • 监控scheduler以及Worker状态,在状态异常的时候主动将实例分发到其他节点上。

Scheduler

Scheduler部分主要包含三个子模块
  • Dependency Checker
    • 从事件队列中获取Master分发过来的事件,检查相应实例的上游依赖。如果依赖都满足的话则会将事件丢入下一个队列中
    • 如果此时依赖还不满足,那么此次事件会被丢弃,当前实例会由上游的成功事件来主动进行触发,避免占用大量资源轮询上游状态
  • Time Checker
    • 从队列(DelayedQueue)中取出通过依赖检查且到达运行时间的事件(实例)。如果是普通任务类型交由master去分发执行,如果是Sensor探针类型的任务则会丢到Sensor Processor去检查外部数据的就绪情况
  • Sensor Processor
    • 目前实现了两种类型的Sensor检查,HDFS路径以及Hive table/partition。
    • Sensor会去检查对应的HDFS/Hive 数据是否已经就绪,如果就绪,就走触发下游流程。如果未就绪,在Sensor的一次检测中不会进行不停轮询,而是借助了任务自动重试机制,等待指定的时间(目前是5分钟)之后会再次进行检查。直到外部数据ready或者超过重试次数。
Scheduler同时会将自己注册到ZK里面。Master是通过Zk进行感知哪些Scheduler是处于可用状态。Scheduler重启的时候会从数据库中捞回本Scheduler 处理中的任务进行恢复。

Worker

Worker是具体负责任务执行的模块。通过依赖检查的实例会由Master分发到Worker中由Worker进行执行并且监控任务运行状态。Worker中会启动子线程对任务进行提交以及监控,并且主动向Master汇报状态以及进行失败重试等操作。 Worker同样会将自己注册到ZK里面以便Master进行感知。

Zookeeper

系统中用到的ZK主要是以下几个目的
  • 选主:Master 是由ZK进行选主的来实现主备,达到系统高可用目的。
  • 探活:Master 是通过ZK来感知Scheduler和Worker可用列表。
  • 服务发现: Scheduler和Worker会通过ZK来发现Master的监听ip和port。

未来规划

未来这个调度系统主要是会针对“功能增强”以及“易用性”进行完善。主要包括:
  • 提供更多交互方式,包括CLI以及配置文件等形式
  • 完善节点类型(如控制节点)
  • 接入更多系统,如公司的Cronjob以及FaaS平台
  • 轻量化部署

总结

当前自研的调度系统FlowX已经具备比较完善的功能,已通过火山引擎DataLeap对外提供服务,经过一年多的打磨,系统稳定性也已经有了保障。系统上已经承载了很多基础数据链路以及多方向业务应用。针对业务真正做到了“集数据产生、数据传输、数据处理、业务流程”于一体。交互方式上,除了以Web UI的操作方式接入,同时有一定的API接入能力。
 
点击跳转大数据研发治理套件 DataLeap了解更多

火山引擎DataLeap背后的支持者 - 工作流编排调度系统FlowX的更多相关文章

  1. 如何又快又好实现 Catalog 系统搜索能力?火山引擎 DataLeap 这样做

      摘要 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维.治理.资产.安全等全套数据中台建设,降低工作成本和数据维护成本.挖掘数据价 ...

  2. 火山引擎 DataLeap:3 个关键步骤,复制字节跳动一站式数据治理经验

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维.治理. ...

  3. 火山引擎 DataLeap:揭秘字节跳动数据血缘架构演进之路

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维 ...

  4. 火山引擎 DataLeap 的 Data Catalog 系统公有云实践

      Data Catalog 通过汇总技术和业务元数据,解决大数据生产者组织梳理数据.数据消费者找数和理解数的业务场景.本篇内容源自于火山引擎大数据研发治理套件 DataLeap 中的 Data Ca ...

  5. 火山引擎DataLeap数据调度实例的 DAG 优化方案

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 实例 DAG 介绍 DataLeap 是火山引擎自研的一站式大数据中台解决方案,集数据集成.开发.运维.治理.资产管理能力 ...

  6. 火山引擎 DataLeap:一家企业,数据体系要怎么搭建?

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 导读:经过十多年的发展,数据治理在传统行业以及新兴互联网公司都已经产生落地实践.字节跳动也在探索一种分布式的数据治 ...

  7. JuiceFS 在火山引擎边缘计算的应用实践

    火山引擎边缘云是以云计算基础技术和边缘异构算力结合网络为基础,构建在边缘大规模基础设施之上的云计算服务,形成以边缘位置的计算.网络.存储.安全.智能为核心能力的新一代分布式云计算解决方案. 01- 边 ...

  8. 火山引擎MARS-APM Plus x 飞书 |降低线上OOM,提高App性能稳定性

    通过使用火山引擎MARS-APM Plus的memory graph功能,飞书研发团队有效分析定位问题线上case多达30例,线上OOM率降低到了0.8‰,降幅达到60%.大幅提升了用户体验,为飞书的 ...

  9. 还原火山引擎 A/B 测试产品——DataTester 私有化部署实践经验

      作为一款面向ToB市场的产品--火山引擎A/B测试(DataTester)为了满足客户对数据安全.合规问题等需求,探索私有化部署是产品无法绕开的一条路.   在面向ToB客户私有化的实际落地中,火 ...

  10. 火山引擎 A/B 测试产品——DataTester 私有化架构分享

    作为一款面向 ToB 市场的产品--火山引擎A/B测试(DataTester)为了满足客户对数据安全.合规问题等需求,探索私有化部署是产品无法绕开的一条路. 在面向 ToB 客户私有化的实际落地中,火 ...

随机推荐

  1. 放弃老旧的Mybatis,强类型替换字符串,这是一款你不应该错过的ORM

    一款轻量级.高性能.强类型.易扩展符合C#开发者的JAVA自研ORM github地址 easy-query https://github.com/xuejmnet/easy-query gitee地 ...

  2. angular,vue,react三大框架选型

    三大框架,本质都是基于js的web应用(前端做的都是web应用包括移动)框架,他们都是帮助我们解决问题的工具,具体用哪个,要结合具体场景. 这三者中,Angular的适用领域相对窄一些,React可以 ...

  3. tomcat nio2源码分析

    一. 前言 ​ 最近在看tomcat connector组件的相关源码,对Nio2的异步回调过程颇有兴趣,平时读源码不读,自己读的时候很多流程都没搞明白,去查网上相关解析讲的给我感觉也不是特别清晰,于 ...

  4. .NET Conf 2023 将在 11 月 15日-17 日 举行 ,附中文日程表

    北京时间 11月15-17日,.NET Conf 2023 即将到来!大会上将发布.NET 8, 以今为止运行最快的.NET 平台, .NET Conf 始终致力于为所有与会者创造世界级的.引人入胜的 ...

  5. 如何实现一套简单的oauth2授权码类型认证,一些思路,供参考

    背景 组内人不少,今年陆陆续续研发了不少系统,一般都会包括一个后台管理系统,现在问题是,每个管理系统都有RBAC那一套用户权限体系,实在是有点浪费人力,于是今年我们搞了个统一管理各个应用系统的RBAC ...

  6. 实例讲解SpringBoot集成Dubbo的步骤及过程

    首先,让我们先了解一下Spring Boot和Dubbo. Spring Boot 是一个开源的 Java Web 框架,它可以帮助开发者快速创建独立的.生产级别的 Spring 应用程序.Sprin ...

  7. [计蒜客20191103D] 坐车

    n 个学生将要坐车去餐厅,每辆车最多可以坐 5 个人并且出于对环境的考虑他们不会使用多余的车.车的速度为每秒 1 个单位.现在 ii 号同学需要去 \(i\) 号点停 5 分钟(此时整车都在 i 号点 ...

  8. Blazor入门100天 : 自做一个支持长按事件的按钮组件

    好长时间没继续写这个系列博客了, 不知道大家还记得我吗? 话不多说,直接开撸. 1. 新建 net8 blazor 工程 b19LongPressButton 至于用什么模式大家各取所需, 我创建的是 ...

  9. 这些 git 高级命令你知道几个

    大家好,我是 dom 哥.今天给大家分享几个 git 的高级应用. git 是目前最流行的版本控制工具.git 玩的 6 不 6,轻则影响自己的开发幸福指数 ,重则影响下班时间 .本文介绍一些日常开发 ...

  10. TypeScript Vs JavaScript 区别

    一.观察 1. JS 平常的复制类型 let val; val = 123; val = "123"; val = true; val = [1, 3, 5]; 注意点: 由于JS ...