如何做好分布式任务调度——Scheduler 的一些探索

PART 01

初识 Scheduler

1、找准定位:分布式任务调度平台

无论是互联网应用或者企业级应用,都充斥着大量的任务。我们常常需要一些任务调度系统帮助我们解决问题。随着微服务化架构的逐步演进,单体架构逐渐演变为分布式、微服务架构。在此的背景下,很多原先的单点式任务调度平台已经不能满足业务系统的需求。于是出现了一些基于分布式的任务调度平台。

  • Scheduler 是飞书内的分布式任务调度平台。分布式任务调度能力主要包括:

  • 分布式:平台是分布式部署的,各个节点之间可以无状态和无限的水平扩展(保证可扩展);

  • 任务调度:涉及到任务状态管理、任务调度请求的发送与接收、具体任务的分配、任务的具体执行;(集群中哪些机器什么时候执行什么任务,所以又需要一个可以感知整个集群运行状态的配置中心);

  • 配置中心:可以感知整个集群的状态、任务信息的注册。

2、摸清脉络:Scheduler的结构和核心模块

名词解释:

  • Processor: 编程处理器, 拥有一定的编程规范, 用户自定义实现。

  • Executor: 一个 SDK,运行 Processor 的进行容器,与 Scheduler 通信的载体。

  • Job:用户创建的任务,其中包含任务的调度规则、调度模型、执行器名称等信息。

  • Instance:运行态的Job,每当Job触发后会生成一个Instance,记录本次执行的调度信息。

  • Task:最小执行单元,不同调度模型的任务产生的Task数量不同。

如何做好分布式任务调度——Scheduler 的一些探索_第1张图片

通过架构图可以发现,Scheduler主要有以下三个部分:

  • 调度器 (Scheduler):任务调度中心,负责管理任务的生命周期。接受任务注册,准时准确找出待触发的任务,进行任务拆分下发。找出与之关联的执行器并下发对应任务;

  • 执行器 (Executor):接收调度任务,并将自身状态上报给调度器;

  • 控制台 (Web 前端):负责配置执行器的信息以及调度任务的配置、任务状态、信息展示。

因此,我们可以用一句话解释清楚 Scheduler 所做的事情,即:在「指定时间」「通知执行器」以「指定方式」执行任务

这句话中包含了三个关键点,也分别代表着 Scheduler 的三个核心模块:

  • 指定时间:任务的触发规则,如:每天早上8点、每周二、每月15号等。触发器模块(Launcher Cron)负责任务触发;

  • 指定方式:任务的执行形式,如:单播任务-指定一个机器执行;广播任务-指定所有机器执行;分片任务-任务分阶段分批的执行。分派器模块(Assignment Cron)负责任务的执行方式;

  • 通知执行器:将任务发送到指定执行器,执行任务。派遣器模块(Dispatcher Cron)负责任务的发送,采用流式通信,调度器以推送的方式将任务发送给执行器。

在一个Job的调度周期中,各个模块各司其职,整个流程如下:

如何做好分布式任务调度——Scheduler 的一些探索_第2张图片

拥有这三个核心模块后,Scheduler 已具备了成熟的任务调度功能。另外,为了增加 Scheduler 的稳定性,有额外两个模块为其保驾护航:

  • 健康管理模块 (Service Health Cron): 负责管理 Job 的生命周期,检测未正常派发执行的 Job、Instance 和 Task,并将结果上报给运维人员。

  • 任务进度刷新模块 (Task Cron): 异步更新 Task 状态,流量较高时进行削峰,保证依赖的 mysql 及 redis 不因为流量过高而出现问题。

本篇文章不对 Scheduler 所支持的定时任务能力作赘述,而是从三个方面(易用性、多功能性、稳定性)介绍 Scheduler 对于分布式任务调度的思考和探索:

  • 易用性: 决定了用户是否选择使用该框架的意愿,一个好的框架必须是易用且快速接入的;

  • 多功能性: 接入方需求多种多样,要站在用户角度想问题,不能闭门造车;

  • 稳定性: 对于分布式任务调度平台来说,不仅仅局限于自身的稳定性,接入方的稳定性也十分重要。

PART 02

换位思考-快速接入

1、背景:效率至上,时间是金

以字节跳动内部为例,当前团队想要实现一个定时任务有多种方式:接入字节云的 cronjob 平台、自己实现一套定时任务框架或者接入第三方定时任务框架。

对于第一种接入 cronjob 平台,每一种定时任务都需要注册各自的 psm 和运行时环境(镜像),当任务需要访问依赖资源如 redis/db 等时,需要各自添加授权。任务代码逻辑有变化时也需要各自升级,导致开发、管理起来较为复杂。

对于第二种自己实现一套定时任务框架,不仅整体开发时间较长,且需要大量时间进行测试回归来保证框架的稳定性。如果项目内使用到的定时任务较多,那么自身研发一套框架用途也较广泛;若项目中使用到的定时任务较少,则 ROI 较低,很多时候也只是为了造轮子而造轮子。

因此,大多数项目面对增加定时任务的需求时,都会寻求直接接入第三方成熟的定时任务框架。对于他们来说,是否易于接入、与现有代码联系是否紧密、调试是否方便是很重要的选取指标。

基于这种背景,Scheduler 在设计时就站在了接入方的角度,思考了如何让接入方能够在最短时间内以最低成本接入 Scheduler,实现自己的定时任务。

2、分析:站在用户角度想问题

站在接入方角度,对定时任务框架进行选型时最关注的几个点无非是定时任务执行准确性、最高支持 qps、定时设置多样性、接入成本这几个。对于前两个指标,Scheduler 目前接入业务方 50+,日均调度任务 20w+ 次,与公司内其他第三方定时任务框架相比也较有竞争性,同时对于后两个关注点,Scheduler 也有自己的风格。

3、丰富的调度设置

一般的定时任务框架只支持 crontab 表达式,例如 0 1 * * * ,代表每天凌晨一点执行一次。cronTab 功能强大,但是若配置复杂的定时策略,有一定学习成本࿰

你可能感兴趣的:(java,网络,运维)