DolphinScheduler——奇富科技的调度实践

news/发布时间2024/9/20 5:53:33

目录

一、技术架构

二、业务挑战

2.1 调度任务量大

2.2 运维复杂

2.3 SLA要求高

三、调度优化实践

3.1 重复调度

3.2 漏调度

3.3 Worker服务卡死

3.4 任务重复运行

四、服务监控

4.1 方法耗时监控

4.2 任务调度链路监控

五、用户收益


原文大佬的这篇调度系统案例有借鉴意义,这里直接摘抄下来用作学习和知识沉淀。

一、技术架构

  在我们公司的大数据离线任务调度架构中,调度平台处于中间层,通过数据集成平台、数据开发平台将工作流提交给调度平台。

二、业务挑战

2.1 调度任务量大

    目前每天调度的工作流实例在3万多,任务实例在14万多。每天调度的任务量非常庞大,要保障这么多任务实例稳定、无延迟运行,是一个非常大的挑战。

2.2 运维复杂

    因为每天调度的任务实例非常多,经历了几次调度机器扩容阶段,目前2个调度集群有6台Master、34台Worker机器。

2.3 SLA要求高

    由于业务的金融属性,如果调度服务稳定性出问题,导致任务重复调度、漏调度或者异常,损失影响会非常大。

三、调度优化实践

   我们在过去一年,对于调度服务稳定,我们做了如下2个方向的优化。第一,调度服务稳定性优化。第二、调度服务监控。

3.1 重复调度

     用户大规模迁移工作流时,遇到了工作流重复调度问题。现象是同一个工作流会在同一个集群同一时间,生成2个工作流实例。经过排查,基于从A项目迁移到B项目的需求,在工作流上线时,用户通过提交工单,修改了调度数据库中工作流的项目ID,进行迁移。这么做会导致该工作流所对应的quartz(分布式调度器)元数据产生2条数据,进而导致该工作流重复调度。如图3所示,JOB_NAME为’job_1270’的记录,有2条数据,而JOB_GROUP不一样。查询源码job_name对应工作流的定时器ID,JOB_GROUP对应项目ID。因此修改工作流对应的项目ID,会导致quartz数据重复和重复调度。正确迁移工作流项目的方式是,先下线工作流,然后再修改项目ID。

SELECT count(1)FROM     (SELECT TRIGGER_NAME,        count(1) AS num    FROM QRTZ_TRIGGERS    GROUP BY  TRIGGER_NAME    HAVING num > 1 )t

3.2 漏调度

      凌晨2点调度太集中,有些工作流发生漏调度。因此优化了quartz参数,将org.quartz.jobStore.misfireThreshold从60000调整为600000。

如何监控和避免此问题,监控sql摘要如下:

select TRIGGER_NAME,NEXT_FIRE_TIME ,PREV_FIRE_TIME,NEXT_FIRE_TIME-PREV_FIRE_TIME  from QRTZ_TRIGGERS  where  NEXT_FIRE_TIME-PREV_FIRE_TIME=86400000*2

   sql逻辑是:根据quartz(分布式调度器)的元数据表QRTZ_TRIGGERS的上一次调度时间PREV_FIRE_TIME和下一次调度时间NEXT_FIRE_TIME的差值进行监控。如果差值为24小时就正常,如果差值为48小时,就说明出现了漏调度。

   如果已经发生了漏调度如何紧急处理? 我们实现了漏调度补数逻辑通过自定义工作流进行http接口调用。如果监控到发生了漏调度情况,可以立即运行此工作流,就能把漏调度的工作流立即调度运行起来。

3.3 Worker服务卡死

    这个现象是凌晨调度Worker所在机器内存占用飙升至90%多,服务卡死。

     思考产生该问题的原因是,调度worker判断本机剩余内存时,有漏洞。假设设置了worker服务剩余内存为25G时,才不进行任务调度。但是,当worker本机剩余内存为26G时,服务判断本机剩余内存未达到限制条件,那么开始从zk队列中抓取任务,每次抓取10个。而每个spark的driver占用2G内存,那么本地抓取的10个任务在未来的内存占用为20G。我们可以简单计算得出本机剩余内存为26G-20G为6G,也就是说抓取了10个任务,未来的剩余内存可能为6G,会面临严重不足。

    为了解决这个问题,我们参考Yarn,提出了”预申请”机制。预申请的机制是,判断本机剩余内存时,会减去抓取任务的内存,而不是简单判断本机剩余内存。 

    如何获取将要抓取任务的内存大小呢? 有2种方式,第一种是在创建工作流时指定本任务driver占用的内存,第二种是给一个固定平均值。

   综合考虑,采用了第二种方式,因为这种方式对于用户来说,是没有感知的。我们对要抓取的每个任务配置1.5G(经验值)内存,以及达到1.5G内存所需要的时间为180秒,抓取任务后,会放入缓存中,缓存过期时间为180(经验值)秒。剩余内存计算公式,本机剩余内存 =  【本机真实物理剩余内存】—【缓存中任务个数*1.5G】

     还是同样的场景,本机配置的剩余内存为25G,本机实际剩余内存为26G,要抓取的任务为10个。每个任务未来占用的driver内存为1.5G。简单计算一下,本机剩余内存=26G-10*1.5G。在“预申请”机制下,本机剩余内存为1G,小于25G,不会抓取,也就不会导致Worker机器的内存占用过高。那么会不会导致Worker服务内存使用率过低呢,比如shell、python、DataX等占用内存低的任务。结论是不会,因为我们有180秒过期机制,过期后,计算得到的本机剩余内存为变高。

   实施上文的内存预申请机制后,最近半年没有遇到由于内存占用过高导致worker服务卡死的问题。以下是我们加上内存预申请机制后,worker内存使用率情况,可以看见worker最大内存使用率始终稳定保持在80%以下。

3.4 任务重复运行

  在worker服务卡死时,我们发现yarn上的任务没有被杀死,而master容错时导致任务被重复提交到yarn上,最终导致用户的数据异常。

   我们分析后发现,任务实例有一个app_link字段,该字段存放用户提交的yarn任务的app id,而第一次调度的任务的app id为空。排查代码发现worker在运行任务时,只有完成的yarn 任务,才会更新app_link字段。这样导致master在容错时,拿不到app id,导致旧任务没有被杀死,最终导致任务重复提交。

   我们进行的第一个改进点为,在worker运行yarn任务时,从log中实时过滤出app id,然后每隔5秒将app id更新到app_link字段中。 这样yarn任务在运行时,也就能获取到app id,master容错时就能杀死旧任务。

   第二个改进点为,在worker服务卡死从而自杀时,杀死本机上正在运行的调度服务,这样可能master就不需要进行容错了。 实施改进点后,最近半年没有遇到重复调度的yarn任务了。

四、服务监控

    一个稳定的系统,除了代码上的优化,一定离不开完善的监控。DolphinScheduler 对外提供了 Prometheus 格式的基础指标,我们新增了一些高优指标,并集成到公司内部的监控系统。通过监控大盘来查看调度系统的健康状况,并针对不同级别的prometheus指标和阈值,配置电话 / 钉钉报警。

4.1 方法耗时监控

    我们通过byte-buddy、micrometer等,实现了自定义轻量级java agent框架。这个框架实现的目标是监控java方法的最大耗时、平均耗时、qps、服务的jvm健康状况等。并把这些监控指标通过http暴露出来,通过prometheus抓取,再通过grafana进行可视化展示,并针对不同级别的prometheus指标和阈值,配置电话 / 钉钉报警。

    例如以下是master访问zk和quartz的最大耗时,平均耗时,qps等。

以下是master服务的jvm监控指标

   通过该java agent,我们实现了api、master、worekr、zookeeper等服务方法耗时监控,提前发现问题并解决,避免将问题扩大到用户感知的状况。

4.2 任务调度链路监控

    为了保障调度任务的稳定性,有必要对任务调度的生命周期进行监控。DolphinScheduler服务调度任务的全流程是先从quartz(分布式调度器)中产生Command(待调度指令),然后将Command转化为工作流实例,再从工作流实例生成一系列对应的任务实例,需要对该任务链路的生命周期进行监控。

  • 监控quartz元数据

     前面已经讲了我们通过监控quartz元数据,发现漏调度和重复调度问题。

  • 监控command表积压情况

      通过监控command表积压情况,从而监控master是否服务正常,以及master服务的性能是否能够满足需求。

  • 监控任务实例

     通过监控任务实例等待提交时间,从而监控worker服务是否正常,以及worker服务的性能是否能够满足需求。

   综上,通过上述的全生命周期监控,可以提前感知到worker服务的性能问题,并及时解决。

五、用户收益

     通过对DolphinScheduler代码的优化,获得的最大收益是近半年没有因为调度服务故障导致用户的SLA受影响,当调度系统出现问题时,能及时感知并解决。

参考文章:

Apache DolphinScheduler 在奇富科技的首个调度异地部署实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.bcls.cn/HfaF/9748.shtml

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

excel 实现分组排序功能

我们经常会遇到按照分组进行排序,在excel如何实现呢? 如下列的数据,需要按照分组,将得分从高到底排名 我们可以使用如下的公式操作即可实现 SUMPRODUCT((A$2:A$15A2)*(C$2:C$15>C2))1

解读人工智能的理论基石

1956年的一个夏天,在达特茅斯学院的一个小会议室里,一群充满好奇和野心的年轻科学家聚集在一起,他们有一个共同的梦想:创造能够模仿人类智能的机器。这不仅仅是科幻小说的情节,更是人工智能历史上一个真实的起点。从那…

2023 re:Invent 用 Amazon Q 打造你的知识库

前言 随着 ChatGPT 的问世,我们迎来了许多创新和变革的机会。一年一度的亚马逊云科技大会 re:Invent 也带来了许多前言的技术,其中 Amazon CEO Adam Selipsky 在 2023 re:Invent 大会中介绍 Amazon Q 让我印象深刻,这预示着生成式 AI 的又一…

ABAP 发送带EXCEL邮件

前言 没啥特殊需求,就是有个库龄报表用户想整邮件发送 实现 用的最简单的XLS文件作为excel附件发送出去 观察XLS文件的纯文本格式,每列之间用TAB制表符分隔,每行之间用回车符分隔 思路也比较明确,在SAP中实现这种格式&#xf…

React之组件定义和事件处理

一、组件的分类 在react中,组件分为函数组件和class组件,也就是无状态组件和有状态组件。 * 更过时候我们应该区别使用无状态组件,因为如果有状态组件会触发生命周期所对应的一些函数 * 一旦触发他生命周期的函数,它就会影响当前项…

微信小程序图片展示淡入淡出纯WXSS实现,无需使用消耗性能的动画引擎

进入下面小程序可以体验效果: 以下代码的淡入淡出是切换图片的时候动画效果显示的。需要用其他方式,可以基于这个wxss修改即可 原理就是,图片默认样式的opacity 是 0,通过变量改变样式的opacity即可,然后需要有transi…

苍穹外卖知识点总结(一)

简介 技术选型 展示项目中使用到的技术框架和中间件。 用户层:node.js Vue.js ElementUI 微信小程序 apache echarts 网关层:nginx 应用层:Spring Boot Spring MVC Spring Task httpclie…

IntelliJ IDEA 使用 spring Initializr 快速搭建 spring boot 项目遇到的坑

maven使用的是3.5.3 一、创建SpringBoot 二、项目创建成功,启动右键,没有run方法 三、在pom.xml上右键,将其添加为maven项目,然后发现Test模块报错 四、查看pom.xml文件,发现2.3.5Release版本变红,怀疑是版…

mac flutter 配置

下载Flutter Sdk 直接访问官网无法下载,需要访问中国镜像下载 Flutter SDK 归档列表 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter Start building Flutter Android apps on macOS - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 下载后解压…

androidapp的开发流程,王者笔记

昨天去面了一家公司,价值观有受到冲击。 面试官技术方面没的说,他可能是个完美主义的人,无论什么事情到了他那里好像都有解决的方案,我被说的无所适从,感觉他很厉害。 但我不能认可的是,面试官觉得加班是…

会计师人物百度百科词条如何创建?腾轩科技传媒分享创建技巧不容你错过!

随着社交网络的发展,人物在互联网上的影响力变得越来越大。随之而来的是大家都希望在网络上拥有自己的百度百科词条,让更多人了解自己的事业和成就。腾轩科技传媒将为大家介绍会计师人物百度百科词条如何创建?人物百度百科创建技巧不容你错过…

32单片机基础:GPIO输入

1.1按键控制LED 按键介绍: 两种方式,我们一般用下接的方式。 第一个图:注意点。当按键按下,PA0接地,被置为低电平, 但是一旦按键松手,PA0悬空,引脚电压不确定。所以无论怎么读引脚…

Qt程序设计-柱状温度计自定义控件实例

Qt程序设计-柱状温度计自定义控件实例 本文讲解Qt柱状温度计自定义控件实例。 效果演示 创建温度计类 #ifndef THERMOMETER_H #define THERMOMETER_H#include <QWidget> #include <QPainter> #include <QDebug> #include <QTimer> #include <QPr…

element ui富文本编辑器的使用(quill-editor)

引用组件 <el-form-item label"内容"><editor v-model"obj.activity_content" :min-height"192"/> </el-form-item> 组件封装 <template><div><el-upload:action"uploadUrl":before-upload"…

开发知识点-Python-conda

Python-conda https://conda.io/miniconda.html conda search python conda env list conda deactivate conda activate python11 conda 是一个流行的开源包管理系统&#xff0c;它支持多种 Python 版本。 使用 conda 来创建和管理不同的 Python 环境&#xff0c;并在这些环…

电商网站数据采集配合socks5代理ip怎么进行?

电商网站数据采集是一项重要的任务&#xff0c;可以帮助企业了解市场需求、竞品分析、用户行为等方面。在进行电商网站数据采集时&#xff0c;有时需要配合使用socks5代理IP。本文将介绍如何进行电商网站数据采集配合socks5代理IP。 一、代理IP介绍 代理IP是一种可以隐藏用户真…

可用于智能客服的完全开源免费商用的知识库项目

介绍 FastWiki项目是一个高性能、基于最新技术栈的知识库系统&#xff0c;专为大规模信息检索和智能搜索设计。利用微软Semantic Kernel进行深度学习和自然语言处理&#xff0c;结合.NET 8和MasaBlazor前端框架&#xff0c;后台采用.NET 8MasaFrameworkSemanticKernel&#xff…

HTML5:七天学会基础动画网页4

backgorund-size 值与说明 length(单位像素):设置背景图片高度和宽度&#xff0c;第一个值设置宽度&#xff0c;第二个值设置高度&#xff0c;如果只给出一个值&#xff0c;第二个是设置为auto。 percentage(百分比):以父元素的百分比来设置背景图像的宽度和高度&#xff0c…

Mac电脑输入正确密码后提示密码错误

&#x1f3dd; 背景 Mac Pro 在擦键盘时&#xff0c;屏幕一直亮起&#xff0c;导致密码一致输入错误&#xff0c;想来没有什么问题便没有处理。但是&#xff01;&#xff01;&#xff01;在擦完键盘后输入正确的密码依旧提示密码错误&#x1f631; 接下来就是不断的重启、关机…

黑马c++ STL部分 笔记(3) vector容器

vector可以动态扩展&#xff08;不是在原有基础上扩展&#xff0c;而是找更大空间&#xff0c;然后将元数据拷贝新空间&#xff0c;释放原空间&#xff09; vector容器的迭代器是支持随机访问的迭代器 1. vector容器的构造 // vector容器的构造&#xff08;一般用拷贝构造&am…
推荐文章