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

89 阅读8分钟

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

这里主要是从抖音的春节项目切入,进而引出分布式定时任务的发展历程及当前主流的分布式定时任务的框架,对于分布式定时任务进行整体介绍。

春节活动

扫描符合条件的信息,定时开奖

image-20230125093500415

  • 挑战:

    • 亿级用户规模
    • 亿级资金规模
    • 百万级读写QPS
  • 诉求:

    • 自动化
    • 定时执行
    • 海量数据
    • 高效稳定

分布式定时任务出现啦!

发展历程

  • case 1: Linux还有xxs后,自动关机。
  • case 2: 也许可以Windows上设置定时任务工具,定时打卡?

image-20230125093758904

Win自带的定时任务

  • case 3: 每天02:30,定时清理机器的日志。 -> Linux里面就自带一个cronjob的定时任务,可以稳定帮助我们执行定时任务。

image-20230125093936846

缺点:单机,不能集群昂!

  • case 4: 每隔5min定时刷新本地缓存数据

image-20230125094053882

  • 优点:
    • 跨平台
  • 缺点:
    • 仅单机可用
  • case 5: 每5min执行多个任务-ScheduledExecutorService

image-20230125094203636

  • 优点:
    • 线程池,节省资源
  • 缺点:
    • 仅单机可用

Quartz

image-20230125094308722

市面上,最强大的工具,也其实就是事实上的标准啦。

Reference: zhuanlan.zhihu.com/p/306591082

  • 无负载均衡,对分布式环境支持并不好,还不能算是好的分布式框架。

分布式定时任务

image-20230125094610655

  • 特点:
    • 平台化管理
    • 分布式部署
    • 支持海量数据

定义

  • 定时任务是指系统为了自动完成特定任务,实时、延时、周期性完成任务调度的过程。

  • 分布式定时任务是把分散的、可靠性差的定时任务纳入统一的平台, 并实现集群管理调度和分布式部署的一种定时任务的管理方式。

  • 按触发时机分类:

    • 定时任务:特定时间触发,比如今天15:06执行
    • 延时任务:延时触发,比如10s后执行
    • 周期任务:固定周期时间,或固定频率周期调度触发,比如每天12点或者每隔5s执行
  • 分布式定时任务的特点:

    • 自动化:全自动完成定时任务的调度和执行
    • 平台化:基于平台化的思维管控一系列的分 布式定时任务
    • 分布式:在分布式系统环境下运行任务调度,突破单机定时任务的性能瓶颈
    • 伸缩性:采用集群方式部署,可以随时按需扩缩容
    • 高可用:单点故障不影响最终任务结果,可以做到故障转移
  • 分布式定时任务的执行方式:

    • 单机任务: 随机触发一台机器执行任务, 适用于计算量小、并发度低的任务
    • 广播任务: 广播到所有机器上执行同一个任务,比如所有机器一起清理日志
    • Map任务: 一个任务可以分出多个子任务,每个子任务负责一部分的计算。 适用于计算量大,单机无法满足要求的任务
    • MapReduce任务: 在Map任务的基础上,还可以对所有子任务的结果做汇总计算,适用于计算量大,并且需要对子任务结果做汇总的任务

后面两种能够跨过单机的瓶颈,好用很多昂!!!MapReduce适用于有汇总计算的场景,如果不需要汇总,Map就足够用了昂!!!

image-20230125100333690

  • 业内主流定时任务框架:

image-20230125100455032

知识面扩充

  • 分布式定时任务VS单机定时任务:
    • 关系: 都可以实现自动化的定时、延时、周都可以对海量数据做处理期任务调度。
    • 差异:
      • 分布式定时任务可支撑更大的业务体
      • 分布式定时任务的性能、伸缩性、稳大数据处理引擎往往致力于将源数据定性更高
  • 分布式定时任务VS大数据处理引擎
    • 关系:
      • 都可以对海量数据做处理
      • 性能、伸缩性、稳定性都很高
    • 差异:
      • 定时并不是大数据处理引擎要解决的核心问题
      • 大数据处理引擎往往致力于将源数据处理成结果数据,分布式定时任务除了能做这个之外,还可以调用HTTP和RPC服务

实现原理

核心架构

image-20230125101343340

主要就是这四个大的组件昂!!!

数据流

image-20230125101508518

功能架构

image-20230125101551925

控制台

基本概念

image-20230125101730449

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

任务元数据

image-20230125101823610

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

任务实例

image-20230125102058778

image-20230125101914557

Job Instance是一个确定的Job的一次运行实例。(类似于代码和进程)

触发器

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

方案一-Scan+延时消息

字节+腾讯目前在用

image-20230125102543950

定时 -> 延时

方案二-时间轮

时间轮,Quartz目前在用

image-20230125102805103

image-20230125102823727

image-20230125102706336

image-20230125103021372

插入是O(1),查询也是O(1)

局限:时间轮的“刻度有限”

多级时间轮

  • 多级时间轮 is very important!!!

image-20230125110217854

甚至可以天轮,周轮,月轮,年轮,类似于多级反馈队列。

例如一个任务1天1小时1分钟1秒执行。一开始任务放在天轮,如果天轮减少到0,任务就放入时轮,以此放入分轮,秒轮,直到执行。时间轮自上往下调度,很方便,也是O(1),放入和查都是O(1),自动调度,方便!!!

高可用

  • 核心问题

    • 不同业务之间,任务的调度相互影响怎么办?
    • 负责扫描和触发的机器挂了怎么办?
  • 解法思路

    • 存储上,不同国别、业务做资源隔离
    • 运行时,不同国别、业务分开执行
    • 部署时,采用多机房集群化部署,避免单点故障,通过数据库锁或分布式锁保证任务只被触发一次
  • 问题引出:

image-20230125110518227

  • 如何避免集群中,一个任务多次触发,抢锁嘛!

image-20230125110615088

资源浪费好多哦

  • 分布式锁模式:

image-20230125110722751

调度器

资源来源

  • 业务系统提供机器资源

    • 使用该方案的公司:
      • 阿里、美团、字节等
    • 优点:
      • 任务执行逻辑与业务系统共用同一份资源, 利用率更高
    • 缺点:
      • 更容易发生定时任务脚本影响在线服务的 事故
      • 不能由定时任务平台控制扩缩容
  • 定时任务平台提供机器资源

    • 使用该方案的公司:
      • 字节等
    • 优点:
      • 任务执行逻辑与业务系统提供的在线服务隔 离,避免相互影响
      • 可以支持优雅地扩缩容
    • 缺点:
      • 消耗更多机器资源
      • 需要额外为定时任务平台申请接口调用权限, 而不能直接继承业务系统的权限

节点选择

image-20230125111009490

任务分片

image-20230125111105272

大任务切小,然后方便分配调度到集群上运行昂!

高级特性

  • 任务编排:

image-20230125111151777

  • 故障转移:

image-20230125111215833

调度失败 -> 重新调度到别的Executor执行

  • 高可用:

image-20230125111239829

调度器无状态!!!就很方便,集群部署方便昂!!!

执行器

  • 注册,注册到调度中心,调度中心才能调度嘛。

image-20230125111412127

状态上报 -> heartbeat detection,方便调度昂!

注册的机制,可以做到机器的弹性扩缩容昂!

总结

  • 核心架构:

    • 控制台Admin、触发器Trigger、调度器Scheduler、执行器Executor
  • 业务模型

    • 任务元数据Job、任务实例JobInstance、任务结果JobResult、任务历史JobHistory
  • 触发器

    • 定时扫描+延时消息
    • 时间轮
      • 链表、最小堆、时间轮、多级时间轮
  • 调度器

    • 资源来源
    • 资源调度: 节点选择、任务分片、任务编排、故障转移
  • 执行器

    • 注册、调度、回调、心跳检测

业务应用

业务场景简介

  • 所有需要定时、延时、周期性执行任务的业务场景,都可以考虑使用分布式定时任务。下面介绍一些常见的:
    • 电商:
      • 订单30分钟未付款自动关闭订单
      • 定时给商家、达人发送消息,给字节春节集卡瓜分红包
    • 互动:
      • 支付宝集五福
      • 字节春节集卡瓜分红包
    • 游戏:
      • 活动结束后批量补发用户末领取的奖励
      • 定期更新游戏内榜单

某个时间,就要做什么事情 -> 分布式定时任务

其他解决方案

  • 发货后超过10天未收货时系统自动确认收货
    • 使用分布式定时任务的延时任务
    • 使用消息队列的延时消息或者定时消息
  • 春节集卡活动统计完成集卡的用户个数和总翻倍数
    • 使用分布式定时任务的MapReduce任务
    • 使用大数据离线处理引擎Hive离线做统计
    • 使用大数据实时处理引擎Flink实时做累计
  • 对比:

image-20230125112204660

Summary

image-20230125112401646

重点:

  • 历史:很多框架,Go & Java的,Linux的定时任务,怎么用哇?
  • 实现原理:架构理解很重要!!!
  • Trigger实现:Scan+DelayMsg & 时间轮之类的
  • 调度器实现:资源调度的方式等

References

  1. Quartz介绍: zhuanlan.zhihu.com/p/306591082