关于任务调度:亿级异构任务调度框架设计与实践

1次阅读

共计 7436 个字符,预计需要花费 19 分钟才能阅读完成。

背景

阿里云日志服务作为云原生可观测与剖析平台。提供了一站式的数据采集、加工、查问剖析、可视化、告警、生产与投递等性能。全面晋升用户的研发、运维、经营、平安场景的数字化能力。

日志服务平台作为可观测性平台提供了数据导入、数据加工、汇集加工、告警、智能巡检、导出等性能,这些性能在日志服务被称为工作,并且具备大规模的利用,接下来次要介绍下这些工作的调度框架的设计与实际。

本次介绍次要分为四个局部:

  • 任务调度背景
  • 可观测性平台的亿级
  • 任务调度框架设计任务调度框架在日志服务的大规模利用
  • 瞻望

任务调度背景

通用调度

调度

在计算机外面是一个十分常见的技术,从单机到分布式再到大数据系统,调度的身影无处不在。这里尝试总结出调度的一些独特特色。

  • 操作系统:从单机操作系统 Linux 来看,内核通过工夫片的形式来管制过程在处理器上的执行工夫,过程的优先级与工夫片挂钩,简略来说,过程的在单 CPU 或者某个 CPU 的执行由调度器来把握;K8s 被称为分布式时代的操作系统,在 Pod 创立后,K8s 的管制面调度器通过对节点进行打分排序,最终选出适宜的 Node 来运行 Pod。
  • 大数据分析系统:从最早的 MapReduce 应用偏心调度器反对作业的优先级和抢占,到 SQL 计算引擎 Presto 通过 Coordinator 的调度器将执行打算中的任务分配到适宜的 worker 上来执行,Spark 通过 DAGScheduler 拆分成 Stage,TaskScheduler 将 Stage 对应的 TaskSet 最终调度到适宜的 Worker 上来执行。
  • 任务调度框架:在数据处理中常见的 ETL 解决工作、定时工作,这些工作具备多模的特点:定时执行、继续运行、一次性执行等。在工作执行过程中须要思考工作的编排和状态一致性问题。

这里简略的对调度做一个形象,如上图所示,调度负责将不同的 Task 调配到不同的 Resource 上执行,Task 能够是过程、Pod、子工作;Resource 为具体执行 Task 工作的资源,能够是处理器、线程池、节点、机器。通过这个形象,能够看出调度在零碎中的地位。

调度的覆盖面很广,本文次要集中在任务调度框架的设计与实际,这里先通过一些例子来看下任务调度的一些特点,以下次要讲工作分为定时类的工作和依赖类的工作两种来开展。

任务调度

定时类工作

定时执行能够了解为每个工作之间有工夫先后顺序,并且要在特定的工夫点执行,比方每隔 1 小时对日志进行监控,00 点的监控工作须要首先执行,01 点的监控工作须要在 01 点准时执行;同样,相似的定时场景,还有仪表盘订阅、定时计算等。

依赖类工作

除了定时执行,还有另外一种编排模式,比方程序依赖,各个工作之间有先后执行的依赖,也叫 Pipeline 形式,还有一种比拟常见的编排模式,拓扑依赖,也称为 DAG,比方 Task2/Task3 须要等到 Task1 执行实现才能够执行,Task5 须要等到 Task3/Task4 执行完才能够执行。

任务调度特点

任务调度在执行的过程中须要尽可能平衡的将工作分派到适合的机器或者执行器下来执行,比方要依据执行器的以后负载状况,要依据工作本身的特色进行分派执行;在执行器执行的过程中也可能会解体,退出,这时候须要将工作迁徙到其余的执行器中。整个调度过程须要思考到调度策略、FailOver、工作迁徙等。接下来来看下任务调度的一个简略利用。

任务调度利用:一条日志的历险

上图中原始日志为一条 Nginx 拜访日志,其中包含 IP、工夫、Method、URL、UserAgent 等信息,这样一些原始日志并不利于咱们进行剖析,比方咱们想统计拜访最高的 Top 10 URL,通过命令解决是这样的:

cat nginx_access.log |awk ‘{print $7}’| sort|uniq -c| sort -rn| head -10 | more

抛开命令的复杂性和原始日志的数据量不谈,即便需要略微变动,命令就须要大量的改变,十分不利于保护,对日志进行剖析的正确形式必然是应用分布式日志平台进行日志剖析,原始日志蕴含着大量“信息”,然而这些信息的提取是须要一系列的流程。

首先是数据采集、须要通过 Agent 对散布在各个机器上的数据进行集中采集到日志平台,日志采集上来后须要进行荡涤,比方对于 Nginx 拜访日志应用正则提取,将工夫、Method、URL 等重要信息提取进去作为字段进行存储并进行索引构建,通过索引,咱们能够应用类 SQL 的剖析语法对日志进行剖析、例如查看拜访的 Top 10 URL,用 SQL 来表白就会十分简洁清晰:

select url, count(1) as cnt from log group by url order by cnt desc limit 10

业务零碎只有在服务,日志就会一直产生,能够通过对流式的日志进行巡检,来达到零碎异样的检测目标,当异样产生时,咱们能够通过告警告诉到零碎运维人员。

通用流程提取

从这样一个日志剖析零碎能够提取出一些通用的流程,这些通用的流程能够概括为数据摄入、数据处理、数据监测、数据导出。

除了日志,零碎还有 Trace 数据、Metric 数据,它们是可观测性零碎的三大支柱。这个流程也实用于可观测性服务平台,接下来来看下一个典型的可观测服务平台的流程形成。

典型可观测服务平台数据流程

  • 数据摄入:在可观测服务平台首先须要扩大数据起源,数据源可能包含各类日志、音讯队列 Kafka、存储 OSS、云监控数据等,也能够包含各类数据库数据,通过丰盛数据源的摄入,能够对系统有全方位的观测。
  • 数据处理:在数据摄入到平台后,须要对数据进行荡涤、加工,这个过程咱们把他统称数据处理,数据加工能够了解为数据的各种变换和富华等,汇集加工反对对数据进行定时 rolling up 操作,比方每天计算过来一天汇总数据,提供信息密度更高的数据。
  • 数据监测:可观测性数据自身反馈了零碎的运行状态,零碎通过对每个组件裸露特定的指标来裸露组件的衰弱水平,能够通过智能巡检算法对异样的指标进行监控,比方 QPS 或者 Latency 的陡增或陡降,当出现异常时能够通过告警告诉给相干运维人员,在指标的根底上能够做出各种运维或者经营的大盘,在每天定时发送大盘到群里也是一种场景的需要。
  • 数据导出:可观测性数据的价值往往随着工夫产生衰减,那么对于长时间的日志类数据出于留档的目标能够进行导出到其余平台。

从以上四个过程咱们能够形象出各类工作,别离负责摄入、解决、检测等,比方数据加工是一种常驻工作,须要继续对数据流进行解决,仪表盘订阅是一种定时工作,须要定时收回仪表盘到邮件或者工作群中。接下来将要介绍对各类工作的调度框架。

可观测性平台的亿级任务调度框架设计

可观测平台工作特点

依据上面对可观测平台工作的介绍,能够总结一个典型的可观测平台的工作的特点:

  • 业务简单,工作类型多:数据摄入,仅数据摄入单个流程波及数据源可能有几十上百个之多。
  • 用户量大,工作数数量多:因为是云上业务,每个客户都有大量的工作创立需要。
  • SLA 要求高:服务可用性要求高,后盾服务是降级、迁徙不能影响用户已有工作的运行。
  • 多租户:云上业务客户互相间接不能有影响。

可观测平台任务调度设计指标

依据平台工作的特点,对于其调度框架,咱们须要达到上图中的指标

  • 反对异构工作:告警、仪表盘订阅、数据加工、汇集加工每种工作的特点不一样,比方告警是定时类工作、数据加工是常驻类工作,仪表盘订阅预览是一次性工作。
  • 海量任务调度:对于单个告警工作,如果每分钟执行一次,一天就会有 1440 次调度,这个数量乘以用户数再乘以工作数,将是海量的任务调度;咱们须要达到的指标是工作数的减少不会对打爆机器的性能,特地是要做到程度扩缩容,工作数或者调度次数减少只须要线性减少机器即可。
  • 高可用:作为云上业务,须要达到后盾服务降级或者重启、甚至宕机对用户工作运行无影响的目标,在用户层面和后盾服务层面都须要具备工作运行的监控能力。
  • 简略高效的运维:对于后盾服务须要提供可视化的运维大盘,能够直观的展现服务的问题;同时也要对服务进行告警配置,在服务降级、公布过程中能够尽量无人值守。
  • 多租户:云上环境是人造有多租户场景,各个租户之间资源要做到严格隔离,相互之间不能有资源依赖、性能依赖。
  • 可扩展性:面对客户的新增需要,将来须要反对更多的工作类型,比方曾经有了 MySQL、SqlServer 的导入工作,在将来须要更多其余的数据库导入,这种状况下,咱们须要做到不批改任务调度框架,只须要批改插件即可实现。
  • API 化:除了以上的需要,咱们还须要做到工作的 API 化管控,对于云上用户,很多海内客户是应用 API、Terraform 来对云上资源做管控,所以要做到工作治理的 API 化。

可观测平台任务调度框架总体概览

基于上述的调度设计指标,咱们设计了可观测性任务调度框架,如上图所示,上面从下到上来介绍。

  • 存储层:次要包含工作的元数据存储和工作运行时的状态和快照存储。工作的元数据次要包含工作类型,工作配置、任务调度信息,都存储在了关系型数据库;工作的运行状态、快照存储在了分布式文件系统中。
  • 服务层:提供了任务调度的外围性能,次要包含任务调度和工作执行两局部,别离对应后面讲的工作编排和工作执行模块。任务调度次要针对三种工作类型进行调度,包含常驻工作、定时工作、按需工作。工作执行反对多种执行引擎,包含 presto、restful 接口、K8s 引擎和外部自研的 ETL 2.0 零碎。
  • 业务层:业务层包含用户间接在控制台能够应用到的性能,包含告警监控、数据加工、重建索引、仪表盘订阅、汇集加工、各类数据源导入、智能巡检工作、和日志投递等。
  • 接入层:接入层应用 Nginx 和 CGI 对外提供服务,具备高可用,地区化部署等个性。
  • API/SDK/Terraform/ 控制台:在用户侧,能够应用控制台对各类工作进行治理,对于不同的工作提供了定制化的界面和监控,同时也能够应用 API、SDK、Terraform 对工作进行增删改查。
  • 工作可视化:在控制台咱们提供了工作执行的可视化和工作监控的可视化,通过控制台用户能够看出看到工作的执行状态、执行历史等,还能够开启内置告警对工作进行监控。

任务调度框架设计要点

接下来从几方面对任务调度框的设计要点进行介绍,次要包含以下几方面来介绍:

  • 异构任务模型形象
  • 调度服务框架
  • 大规模工作反对
  • 服务高可用设计
  • 稳定性建设

任务模型形象

接下来看下任务模型的形象:

  • 对于告警监控、仪表盘订阅、汇集加工等须要定时执行的工作,形象为定时工作,反对定时和 Cron 表达式设置。
  • 对于数据加工、索引重建、数据导入等须要继续运行的工作,形象为常驻工作,这类工作往往只须要运行一次,能够有也能够没有完结状态。
  • 对于数据加工的预览、仪表盘订阅的预览等性能,是在用户点击时才会须要创立一个工作来执行,执行实现即可退出,不须要保留工作状态,这类工作形象为 DryRun 类型,或者按需工作。

调度服务框架

服务根底框架应用了 Master-Worker 架构,Master 负责工作的分派和 Worker 的管控,Master 将数据抽象为若干 Partitions,而后将这些 Partitions 分派给不同的 Worker,实现了对工作的分而治之,在 Worker 执行的过程中 Master 还也能够依据 Worker 的负载进行 Partitions 的动静迁徙,同时在 Worker 重启降级过程中,Master 也会对 Partition 进行移出和移入;

工作的调度次要在 Worker 层来实现,每个 Worker 负责拉取对应 Partitions 的工作,而后通过 JobLoader 对工作进行加载,留神:这里只会加载以后 Worker 对应 Partitions 的工作列表,而后 Scheduler 对工作进行调度的编排,这里会波及常驻工作、定时工作、按需工作的调度,Scheduler 将编排好的工作发送到 JobExecutor 进行执行,JobExecutor 在执行的过程中须要实时对工作的状态进行长久化保留到 RedoLog 中, 在下次 Worker 降级重新启动的过程中,须要从 RedoLog 中加载工作的状态,从而保障工作状态的准确性。

大规模工作反对

通过工作服务框架的介绍,咱们晓得 Partitions 是 Master 与 Worker 沟通的桥梁,也是对大规模工作进行分而治之的介质。如上图所示,假如有 N 个工作,依照肯定的哈希算法将 N 个工作映射到对应的 Partition,因为 Worker 关联特定的 Partition,这样 Worker 就能够跟工作关联起来,比方工作 j1、j2 对应的 partition 是 p1,而 p1 对应的 Worker 是 worker1,这样 j1、j2 就能够在 worker1 上执行。须要阐明的如下:

  • Worker 与 Partition 的对应关系并非变化无穷,是一个动静的映射,在 Worker 重启或者负载较高时,其对应的 Partition 会迁徙到其余的 Worker 上,所以 Worker 须要实现 Partition 的移入和移出操作。
  • 工作数量减少的时候,因为有 Partition 这个中间层,只须要减少 Worker 的数量就能够满足工作增长时的需要,达到程度扩大的目标。减少新 Worker 后,能够分担更多的 Partition。

服务高可用设计

服务的高可用次要是服务的可用性工夫,作为后盾服务必定有重启、降级的需要,高可用场景次要波及到 Partition 迁徙的解决,在 Worker 重启、Worker 负载较高时、Worker 异样时,都会有 Partition 迁徙的需要,在 Partition 迁徙的过程中,工作也须要进行迁徙,工作的迁徙就波及到状态的保留,相似 CPU 上过程的航线文切换。

对于工作的切换,咱们应用了 RedoLog 的形式来保留工作的状态,一个工作能够被分为多个阶段,对应工作执行的状态机,在每个阶段执行时都对其进行内存 Checkpoint 的更新和 RedoLog 的更新,RedoLog 是长久化到之前提到的分布式文件系统中,应用高性能的 Append 的形式进行程序写入,在 Partition 迁徙到新的 Worker 后,新的 Worker 在对 RedoLog 进行加载,就能够实现工作状态的复原。

这里波及一个优化,RedoLog 如果始终应用 Append 的形式进行写入,势必会造成 RedoLog 越来越收缩,也会造成 Worker 加载 Partition 时速度变慢,对于这种状况,咱们应用了 Snapshot 的形式,将过来一段时间的 RedoLog 进行合并,这样只须要在加载 Partition 时,加载 Snapshot 和 Snaphost 之后的 RedoLog 就能够缩小文件读取的次数和开销,进步加载速度。

稳定性建设

稳定性建设次要波及以下几方面内容:

  • 公布流程:
  • 从编译到公布全 Web 端白屏化操作,模板化公布,每个版本都可跟踪、回退。
  • 反对集群粒度、工作类型粒度的灰度管制,在公布时能够进行小范畴验证,而后全量公布。
  • 运维流程:提供外部运维 API、Web 端操作,对于异样 Job 进行修复、解决。缩小人工染指运维。
  • On-Call:
  • 在服务外部,咱们开发了外部巡检性能,查找异样工作,例如某些工作启动工夫过长、进行工夫过长都会打印异样日志,能够对异样日志进行跟踪和监控。
  • 通过异样日志,应用日志服务告警进行监控,呈现问题能够及时告诉运维人员。
  • 工作监控:
  • 用户侧:在控制台咱们针对各类工作提供了监控仪表盘和内置告警配置。
  • 服务侧:在后盾,能够看到集群粒度工作的运行状态,便于后盾运维人员进行服务的监控
  • 同时,对于工作的执行状态和历史都会存入特定的日志库中,以便呈现问题时进行追溯和诊断。

上面是一些服务侧的局部大盘示例,展现的是告警的一些执行状态。

上面是用户侧的工作监控状态和告警的展现。

大规模利用

在日志服务,工作的调度曾经有了大规模的利用,上面是某地区单集群的工作的运行状态,因为告警是定时执行且应用场景宽泛,其单日调度次数达到了千万级别,汇集加工在 Rolling up 场景中有很高场景的利用,也达到了百万级别;对于数据加工工作因为是常驻工作,调度频率低于相似告警类的定时工作。

接下来以一个汇集加工为例来看下工作的调度场景。

典型工作:汇集加工

汇集加工是通过定时对一段时间的数据进行汇集查问,而后将后果存入到另一个库中,从而将高信息密度的信息进行提取,绝对于原始数据具备降维、低存储、高信息密度的特点。适宜于定时剖析、全局聚合的场景。

这里是一个汇集加工的执行状态示例,能够看到每个工夫区间的执行状况,包含解决行数、解决数据量、处理结果状况,对于执行失败的工作,还能够进行手动重试。

对于汇集加工并非定时执行这么简略的逻辑,在过程中须要解决超时、失败、提早等场景,接下来对每种场景进行一个简略介绍。

调度场景一:

实例提早执行无论实例是否提早执行,实例的调度工夫都是依据调度规定事后生成的。尽管后面的实例产生提早时,可能导致前面的实例也提早执行,但通过追赶执行进度,可逐步缩小提早,直到复原准时运行。

调度场景二:

从某个历史工夫点开始执行汇集加工作业在以后工夫点创立汇集加工作业后,依照调度规定对历史数据进行解决,从调度的开始工夫创立补运行的实例,补运行的实例顺次执行直到追上数据处理进度后,再依照预约打算执行新实例。

调度场景三:

固定工夫内执行汇集加工作业如果须要对指定时间段的日志做调度,则可设置调度的工夫范畴。如果设置了调度的完结工夫,则最初一个实例(调度工夫小于调度完结工夫)执行实现后,不再产生新的实例。

调度场景四:

批改调度配置对生成实例的影响批改调度配置后,下一个实例依照新配置生成。个别倡议同步批改 SQL 工夫窗口、调度频率等配置,使得实例之间的 SQL 工夫范畴能够间断。

调度场景五:重试失败的实例

  • 主动重试
  • 如果实例执行失败(例如权限有余、源库不存在、指标库不存在、SQL 语法不非法),零碎反对主动重试
  • 手动重试
  • 当重试次数超过您配置的最大重试次数或重试工夫超过您配置的最大运行工夫时,重试完结,该实例状态被置为失败,而后零碎继续执行下一个实例。

瞻望

  • 动静工作类型:减少对于动静工作类型的反对,例如更简单的具备工作间依赖关系的任务调度。
  • 多租户优化:目前对于工作应用简略的 Quota 限度,将来对多租户的 QoS 进行的进一步细化,以反对更大的 Quota 设置。
  • API 优化、欠缺:目前的工作类型也在疾速更新中,工作 API 的迭代速度还有些差距,须要加强工作 API 的优化,达到减少一种工作类型,不须要批改或者大量更新 API 的目标。

原文链接

本文为阿里云原创内容,未经容许不得转载。

正文完
 0