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

186 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记

核心架构

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

数据流

任务创建:用户添加任务基础信息、设置触发规则(时间、事件等)、任务代码,提交至 Admin,存储至任务数据库内。

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

这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记

功能架构

Admin

元数据存储、元数据状态流转、任务分片、任务以来、规则引擎、任务暂停/恢复、日志管理、监控报警、指标统计...

Job:任务元数据。基础信息、调度时机、执行行为、执行方式。

JobInstance:任务运行的实例(一个任务可以有多个运行实例)。Job_id、触发事件、状态&结果、过程信息(消息id等)

JobResult:任务实例运行结果(一个任务实例可以有多个结果)

JobHistory:任务历史(一个任务可以用多个不同的任务信息,任务历史存储任务信息修改历史)

Trigger

解析引擎、Scanner(扫描数据库中的任务)、可靠投递(Processor,借助消息队列)、状态流转、补偿策略...

设计约束

  • 大量任务
  • 秒级调度
  • 周期执行
  • 避免浪费

定时扫描、延时消息方案

Scanner 从 DB 中扫描任务,扫描后添加至 Processor 处理,Processor 交给消息队列(延时 MQ)

时间轮方案

使用环形数组存储任务列表。

缺点:环形数组刻度、能表示的时间有限

解决方案:添加 count(经过 count 轮再执行当前刻度的任务)。多级时间轮:秒轮、分轮、时轮

优点:时间复杂度查询和修改都是 O(1),易于扩展时间尺度、易于理解。

应用广泛,不止应用于此

高可用

避免单点故障,使用多机架构又要避免重复触发

解决方案:多个 Trigger 争夺数据库锁(使用 MySQL 行锁性能较差,使用 Redis 等较优),抢锁成功则调度,失败则放弃

Schedule

调度、负载均衡、幂等控制、容错、故障转移、限流、计费、优雅启停、状态管控...

资源:可供调度器调度的机器资源、内存资源、CPU资源、网络资源等

资源来源

与业务公用资源:利用率高,成本低。但相较下容易发生事故,不能由定时任务平台决定扩缩容。

定时任务平台专用资源:与业务隔离,避免相互影响,可扩缩容。但是成本更高,且需要额外设计和申请接口权限,无法复用业务平台的接口权限。

资源调度

随机节点执行:随机选择 Executor 执行任务

广播执行:所有 Executor 共同执行任务

任务分片:将任务分为 N 段,分别分配给 N 个 Executor

任务编排

使用有向无环图(Directed Asyclic Graph)进行可视化任务编排。

故障转移

单机任务:分配给一个 Executor 失败后就分配给其它机器执行

分片任务:分片任务基于一致性 HASH 策略分配任务,Executor 异常时分发到其它 Executor

高可用

Scheduler 本身无状态,可以进行集群部署。可以多个 Scheduler 从同一 MQ 中读取任务并调度。可以借助 MQ 的重试机制保证任务被调度。

Executor

注册(向调度器注册)、任务获取、任务执行、状态上报、日志处理、本地幂等、任务回调...

...