这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天
今日笔记内容: 分布式定时任务
定时任务简介
定时任务的发展
- Windows 批处理/ Linux shell 脚本 (非跨平台, 单机)
- 单机定时任务, 编程语言自带api: Timer(Java), Ticker(Go)
- 任务调度框架: Quartz (单任务, 没有负载均衡)
- 分布式定时任务
定时任务是指系统为了自动完成特定任务, 实时, 延时, 周期性完成调度任务的过程 分布式定时任务是把分散的, 可靠性差的定时任务纳入统一的平台, 并实现集群管理调度和分布式部署的一种定时任务的管理方式
触发时机分类:
- 定时任务: 特定时间触发
- 延时任务: 延迟一定时间触发
- 周期任务: 固定周期时间, 循环触发 分布式定时任务的特点:
- 自动化: 全自动完成定时任务的调度和执行
- 平台化: 基于平台化的思维管控一系列的分布式定时任务
- 分布式: 在分布式系统环境下运行任务调度, 突破单机定时任务的性能瓶颈
- 伸缩性: 采用集群方式不部署, 可以随时按需缩扩容
- 高可用: 单点故障不影响最终任务结构, 可以做到故障转移 执行方式:
- 单机任务:
- 广播任务
- Map任务
- MapReduce任务 业内主流任务框架
- XXl-job 美团, 开源
- SchedulerX 阿里
- TCT 腾讯
- Elastic-job 当当
- Saturn 唯品会
分布式定时任务与单机的差异:
- 支撑更大的业务体量
- 性能, 伸缩性, 稳定性更高 与大数据引擎的差异:
- 定时并不是大数据处理引擎要解决核心问题
- 大数据处理引擎往往致力于将源数据处理成结构数据, 分布式定时任务除了该功能, 还可以调用HTTP/RCP服务
实现原理
分布式定时任务的三个核心问题: 触发, 调度, 执行
- 触发器(Trigger), 负责解析任务, 生成触发事件
- 调度器(Scheduler), 分配任务, 管理任务生命周期
- 执行器(Executor), 获取执行任务单元, 执行任务逻辑
- 控制台(Admin), 任务管理和干预 ![[Pasted image 20230208230428.png]]
控制台
- 任务: Job, 任务元数据
- 基础信息
- 调度时机
- 执行行为
- 执行方式
- 任务实例: JobInstance, 任务运行的实例
- JobId
- 触发时间
- 状态/结果
- 过程信息
- 任务结果: JobResult, 任务实例运行的结果
- 任务历史: JobHistory 对任务修改的历史存储
触发器
核心职责: 给定一系列任务, 解析它们的触发规则, 在规定的时间点触发任务的调度
约束
- 大量任务
- 秒级调度
- 周期任务需要自动重复执行
- 秒级扫描的高性能, 避免资源浪费
实现方案
定时扫描+延时消息
![[Pasted image 20230208222621.png]]
定时扫描出近期需要触发的任务, 交付给延迟MQ触发, 并修改任务DB状态
时间轮: 环形队列, 每个元素代表固定长度的时间段, 类似于桶, 将待触发任务放置到对应桶中. 当前时间扫描到对应桶时, 触发其中的任务. 多级时间轮: 不同级别代表不同的时间段长度
触发器的高可用:
核心问题:
- 不同业务之间, 任务的调度相互影响怎么办?
- 负责扫描和触发的机器挂了怎么办? 解决思路:
- 存储, 运行: 不同国别, 业务隔离执行
- 部署时采用多机房集群化部署, 避免单点故障. 通过数据库锁/分布式(Redis, Zookeeper)锁保证任务只被触发一次
调度器
核心问题
- 资源来源(业务提供/平台提供)
- 资源调度
- 节点选择
- 随机节点执行
- 广播执行
- 分片执行
- 任务编排
- DAG
- 故障转移
- 分片任务基于一致性hash策略分发任务, 当某Executor异常时, 调度器会将任务分发到其他Executor
- 高可用
- 集群部署, 做到完全的无状态, 依赖消息队列的重试机制保障任务一定会被调度
- 节点选择
- 任务执行
执行器
基于注册中心, 做到执行器的弹性缩扩容
- 调度器发送调度请求
- 执行器内部执行
- 向调度中心汇报内部状态
- 存储日志
- 返回执行结果
![[Pasted image 20230208230305.png]]