12 分布式定时任务 | 青训营笔记

144 阅读7分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第13天

资料: juejin.cn/post/719632…

课程1: juejin.cn/course/byte…

课程2: juejin.cn/course/byte…

课程3: juejin.cn/course/byte…

讲师: 王伟强

课程目标

 知识面扩充
     对分布式定时任务建立起宏观的认知, 并深入了解其实现原理
     了解关联的单机定时任务, 大数据处理引擎, 通过了解不同实现方案的优劣来拓展知识面
 项目实践能力加强
     了解在哪些实际业务场景中使用分布式定时任务
     对于实际业务场景的中间件选型, 技术方案设计做到成竹在胸

01 前言

1 春节集卡瓜分20亿

 作为后端开发同学, 怎么设计最终开奖环节技术方案?
 集卡信息
 ↑扫描
 扫描脚本
 ↓汇总计算
 发奖金额
 ↓发奖
 定时开奖
 ​
 用户规模 亿级
 资金规模 亿级
 读写QPS 百万级
 自动化 + 定时执行 + 海量数据 + 高效稳定 = 分布式定时任务

02 发展历程⭐

1 Windows批处理

2 Windows定时任务

3 Linux命令 - CronJob

 优点: Linux系统命令, 使用简单, 稳定可靠
 缺点: 只能控制单台机器, 且无法适用于其他操作系统

4 单机定时任务

Timer, Ticker

 public static void main(String[] args) throws ParseException {
     Timer timer = new Timer();
     timer.schedule(new TimerTask() {
         @Override
         public void run() {
             SyncLocalCache();
         }
     }, 5000, 5*60*1000);
 }
 func main() {
     ticker := time.NewTicker(5*time.Minute)
     for {
         select {
             case <- ticker.C:
                 SyncLocalCache()
         }
     }
 }
 优点: 跨平台
 缺点: 单机可用

ScheduledExecutorService

 private static ScheduledExecutorService scheduler;
 ​
     public static void main(String[] args) throws Exception {
         scheduler = Executors.newScheduledThreadPool(5);
         scheduler.scheduleAtFixedRate(((
             new Runnable() {
                 @Override
                 public void run() {
                     DoSomething();
                 }
             }))
         0, 300,
         TimeUnit.SECONDS);
     }
 优点: 拥有线程池功能
 缺点: 只能单机使用

5 Quartz

优点: 单任务极致控制
缺点: 没有负载均衡机制

6 分布式定时任务

平台化管理
分布式部署
支持海量数据
定时任务: 系统为了自动完成特定任务, 实时, 延时, 周期性完成任务调度的过程
分布式定时任务: 把分散的, 可靠性差的定时任务纳入统一的平台, 并实现集群管理调度和分布式部署的一种定时任务的管理方式
    按触发时机分类:
		定时任务: 特定时间触发 (如今天15:06执行)
		延时任务: 延时触发 (如10s后执行)
		周期任务: 固定周期时间, 或固定频率调度触发 (如每天12点执行, 或每隔5s执行)
特点:
	自动化: 全自动完成定时任务的调度和执行
	平台化: 基于平台化的思维管控一系列的分布式定时任务
	分布式: 在分布式系统环境下运行任务调度, 突破单机定时任务的性能瓶颈
	伸缩性: 采用集群方式部署, 可以随时按需扩缩容
	高可用: 单点故障不影响最终任务结果, 可以做到故障转移
(如何做到故障转移?)
执行方式:
	单机任务: 随机触发一台机器执行任务, 适用于计算量小, 并发度低的任务
	广播任务: 广播到所有机器上执行同一任务, 比如所有机器一起清理日志
	Map任务: 一个任务可以分出多个子任务, 每个子任务负责一部分的计算, 适用于计算量大, 单机无法满足要求的任务
	MapReduce任务: 在Map任务的基础上, 还可以对所有子任务的结果做汇总计算, 适用于计算量大, 并且需要对子任务结果做汇总的任务

7 业内定时任务框架

Xxl-job 美团点评
SchedulerX 阿里巴巴
TCT 腾讯
Elastic-job 当当网
Saturn 唯品会
字节内部有多个框架, 还没有统一

Xxl-job开源且免费, 轻量级, 开箱即用, 操作简单, 上手快, 维护成本不高, 在中小型公司使用非常广泛

SchedulerX 可在阿里云付费使用, 功能非常强大, 在阿里巴巴内部广泛使用并久经考验

TCT 腾讯内部使用, 未开源

8 知识面扩充

分布式定时任务 VS 单机定时任务
关系:
都可以实现自动化的定时, 延时, 周期任务调度
差异:
分布式定时任务可支撑更大的业务体量
分布式定时任务的性能, 伸缩性, 稳定性更高

分布式定时任务 VS 大数据处理引擎
关系:
都可以对海量数据做处理
性能, 伸缩性, 稳定性都很高
差异:
定时并不是大数据处理引擎要解决的核心问题
大数据处理引擎往往致力于将源数据处理成结果数据
分布式定时任务除了能做这个, 还可以调用HTTP和RPC服务

9 本章小结

生活用途:
Windows批处理
Windows任务计划程序
工作用途:
Linux命令--cronjob
单机定时任务--Timer, Ticker
单机定时任务--ScheduledExecutorService
任务调度--Quartz
分布式定时任务
分布式定时任务
触发时机: 定时, 延时, 周期
执行方式: 单机, 广播, Map, MapReduce
业内流行框架: Xxl-job, SchedulerX, TCT
关联技术: 单机定时任务, 大数据处理引擎

03 实现原理

1 核心架构⭐

分布式定时任务核心要解决触发, 调度, 执行三个关键问题:
触发器: Trigger, 解析任务, 生成触发事件
调度器: Scheduler, 分配任务, 管理任务生命周期
执行器: Executor, 获取执行任务单元, 执行任务逻辑
除此之外, 还需要提供一个控制台(Admin), 提供任务管理和干预的功能\

即: 控制台Admin 触发器Trigger 调度器Scheduler 执行器Executor

1.1 数据流

--任务创建--
↓任务基础信息, 触发规则, 任务代码
控制台Admin -> 任务DB

--任务执行--
触发器, 调度器 -> 执行器

1.2 功能架构

Admin
元数据存储 元数据状态 任务分片 任务依赖 规则引擎
任务暂停/恢复 日志管理 监控报警 指标统计 ......
Trigger
解析引擎 Scanner 可靠投递 状态流转 补偿策略
Scheduler
调度 负载均衡 幂等控制 容错 故障转移
限流 计费 优雅启停 状态管控 ......
Executor
注册 任务获取 任务执行 状态上报
日志处理 本地幂等 任务回调 ......

2 控制台

2.1 基本概念

任务: Job, 任务元数据
任务实例: JobInstance, 任务运行的实例
任务结果: JobResult, 任务实例运行的结果
任务历史: JobHistory, 用户可以修改任务信息, 任务实例对应的任务元数据可以不同, 因而使用任务历史存储\

E-R图: Entity Relationship Diagram 实体关系图

mermaid语法: blog.csdn.net/horsee/arti…

|o o|: 0

|| ||: 1

}o o{: 0或多

}| |{: 1或多

erDiagram
	Job ||--|{ JobInstance : correspond
	Job ||--|{ JobHistory : correspond
	JobInstance || -- |{ JobResult : correspond

2.2 基本概念 - 任务元数据

任务元数据(Job)是用户对任务属性定义, 包括任务类型调度时机, 执行行为等\

Job
基础信息 Who
调度时机 When
执行行为 What
执行方式 How\

任务实例(JobInstance)是一个确定的Job的一次运行实例

JobInstance
Job_id
触发时间
状态&结果
过程信息

3 触发器

1 核心职责

核心职责: 给定一系列任务, 解析它们的触发规则, 在规定的时间点触发任务的调度
设计约束:
	需支持大量任务
	需支持秒级的调度
	周期任务需要多次执行
	需保证秒级扫描的高性能, 并避免资源浪费

2 方案⭐

图见PPT: bytedance.feishu.cn/file/boxcn5…

方案1: 定期扫描+延时消息(腾讯, 字节方案)
方案2: 时间轮(Quartz所用方案)
    时间轮是一种高效利用线程资源进行批量化调度的一种调度模型. 时间轮是一个存储环形队列, 底层采用数组实现, 数组的每个元素可以存放一个定时任务列表
    ⭐多级时间轮应用非常广泛

3 高可用

核心问题:
不同业务之间, 任务的调度相互影响怎么办?
负责扫描和触发的机器挂了怎么办?
解法思路:
存储上, 不同国别, 业务做资源隔离
运行时, 不同国别, 业务分开执行
部署时, 采用多机房集群化部署, 避免单点故障, 通过数据库锁或分布式锁保证任务只被触发一次

单Trigger模式
会有单点故障
机器故障时平台故障
Trigger集群模式
可避免单点故障
需要避免同一任务被多次触发, 导致业务紊乱

数据库行锁模式: 在触发调度之前, 更新数据库中JobInstance的状态, 成功抢锁的才会触发调度
缺点: 多台机器频繁竞争数据库锁, 节点越多性能越差
分布式锁模式: 在尝试抢占分布式锁, 可使用Redis锁或Zookeeper锁
性能较高, 多家公司使用此方案

4 调度器

解决问题: 资源来源, 资源调度, 任务执行

1 资源来源

业务系统提供机器资源
使用该方案的公司:
阿里, 美团, 字节等
优点:
任务执行逻辑与业务系统公用同一份资源
利用率更高
缺点:
更容易发生定时任务脚本影响在线服务的事故
不能由定时任务平台控制扩缩容
定时任务平台提供机器资源
使用该方案的公司:
字节等
优点:
任务执行逻辑与业务系统提供的在线服务隔离, 避免相互影响
可以支持优雅地扩缩容
缺点:
消耗更多机器资源
需要额外为定时任务平台申请接口调用权限
而不能直接继承业务系统的权限

2 资源调度⭐

节点选择
随机节点执行: 选择集群中一个可用的执行节点执行调度任务
适用场景: 定时对账
广播执行: 在集群中所有的执行节点分发调度任务并执行
适用场景: 批量运维
分片执行: 按照用户自定义分片逻辑进行拆分, 分发到集群中不同节点并行执行, 提升资源利用效率 适用场景: 海量日志统计

3 高级特性⭐

任务编排: 使用有向无环图DAG(Directed Acyclic Graph)进行可视化任务编排
故障转移: 确保部分执行单元任务失败时, 任务最终成功
分片任务基于一致性hash策略分发任务, 当某Executor异常时, 调度器会将任务分发到其他Executor

4 高可用⭐

调度器可用集群部署, 做到完全的无状态, 靠消息队列的重试机制保障任务一定会被调度

分片, 故障转移, 实现高可用是分布式定时任务与单机定时任务的核心差异

5 执行器

    		    执行器     调度中心		
-----------	    机器注册 -> 注册服务
Jobhandler|   <--   调度请求 <- 调度器
执行线程   |  -->   日志服务 -> 日志服务
-----------   -->   回调请求 -> 回调服务
		    状态上报 -> 状态监测
基于注册中心, 可用做到执行器的弹性扩缩容

6 本章小结

核心架构
控制台Admin 触发器Trigger 调度器Scheduler 执行器Executor
业务模型
任务元数据Job 任务实例JobInstance 任务结果JobResult 任务历史JobHistory
触发器
定时扫描+延时消息
时间轮
链表, 最小堆, 时间轮, 多级时间轮
调度器
资源来源
资源调度: 节点选择, 任务分片, 任务编排, 故障转移
执行器
注册, 调度, 回调, 心跳检测

04 业务应用

所有需要定时, 延时, 周期性执行任务的业务场景, 都可以考虑使用分布式定时任务
其他解决方案:
	业务场景: 发货后超过10天未收货时系统自动确认收货
        1 使用分布式定时任务的延时任务
        2 使用消息队列的延时消息或者定时消息
	业务场景: 春节集卡活动统计完成集卡的用户个数和总翻倍数
        1 使用分布式定时任务的MapReduce任务
        2 使用大数据离线处理引擎Hive离线做统计
        3 使用大数据实时处理引擎Flink实时做累计
        
分布式定时任务
	时效性: 秒级
	可控性: 高
	简洁性: 高
单机定时任务
	时效性: 秒级
	可控性: 高
	简洁性: 高
	缺点: 无法支撑很大业务体量
延时消息
	时效性: 实时
	可控性: 低
	简洁性: 中
	缺点: 任务有变化时, 已发送的延时消息不便于做变更
离线计算
	时效性: 小时级
	可控性: 中
	简洁性: 高
	缺点: 时延至少小时级
实时计算
	时效性: 秒级
	可控性: 高
	简洁性: 中
	缺点: 仅能做数据处理, 无法调用HTTP/RPC请求完成业务逻辑处理