当前位置: 首页 > news >正文

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

目录

一、技术架构

二、业务挑战

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 在奇富科技的首个调度异地部署实践

相关文章:

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

目录 一、技术架构 二、业务挑战 2.1 调度任务量大 2.2 运维复杂 2.3 SLA要求高 三、调度优化实践 3.1 重复调度 3.2 漏调度 3.3 Worker服务卡死 3.4 任务重复运行 四、服务监控 4.1 方法耗时监控 4.2 任务调度链路监控 五、用户收益 原文大佬的这篇调度系统案例…...

2024年最全洗地机选购攻略盘点丨希亦、小米、云鲸、海尔洗地机哪款值得入手?

在现代家居清洁中,洗地机是不可或缺的得力助手,它融合了吸尘、拖地等多种功能。面对市场上琳琅满目的洗地机品牌和型号,选择一个可靠的品牌至关重要。优质的品牌能够提供高品质的产品,使您的清洁工作更加轻松高效。本文将向您推荐…...

HTML笔记3

21&#xff0c;label标签 <label for"...">...</label> <label>...</label> <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content&qu…...

利用Python副业赚钱,看完这篇你就懂了!

Python都可以做哪些副业&#xff1f; 1、兼职处理数据Excel整理数据功能虽然很强大&#xff0c;但在Python面前&#xff0c;曾经统治职场的它也的败下阵来。因为Python在搜集数据整理分析数据的过程中更加便捷&#xff0c;通过几行代码还可以实现自动化操作。 如果你学会Pyth…...

FP16(半精度浮点数)、FP32(单精度浮点数)和INT8

在深度学习和计算机视觉领域中&#xff0c;FP16&#xff08;半精度浮点数&#xff09;、FP32&#xff08;单精度浮点数&#xff09;和INT8&#xff08;8 位整数&#xff09;是常见的数据类型或精度表示方式。它们在不同的场景下有各自的优势和用途。 FP16&#xff08;半精度浮…...

MySQL数据管理二

1.数据库的完整性 数据库中的数据是从外界输入的&#xff0c;而数据的输入由于种种原因&#xff0c;会发生输入无效或错误信息。保证输入的数据符合规定&#xff0c;成为了数据库系统&#xff0c;尤其是多用户的关系数据库系统首要关注的问题。 它是应防止数据库中存在不符合语…...

sqoop-import 详解

文章目录 前言一、介绍1. sqoop简介2. sqoop import的作用3. 语法3.1 sqoop import 语法3.2 导入配置属性 二、导入参数1. 常见参数2. 验证参数3. 导入控制参数4. 用于覆盖映射的参数5. 增量导入参数6. 输出行格式参数7. 输入解析参数8. Hive 参数9. HBase 参数10. Accumulo 参…...

第二周opencv

一、边缘检测算子 边缘检测算子是用于检测图像中物体边界的工具。边缘通常表示图像中灰度值或颜色发生显著变化的地方。边缘检测有助于识别图像中的物体形状、轮廓和结构。这些算子通过分析图像的灰度或颜色梯度来确定图像中的边缘。 梯度算子 要得到一幅图像的梯度&#xff0c…...

python_读取txt文件绘制多条曲线II

从给定的列表中来匹配txt文件对应列的数据&#xff1b; import matplotlib.pyplot as plt import re from datetime import datetime from pylab import mplmpl.rcParams["font.sans-serif"] ["SimHei"] # 设置显示中文字体 mpl.rcParams["axes.un…...

java排序简单总结和推荐使用套路(数据排序,结构体排序)

了解int和Integer的区别 int是Java的基本数据类型&#xff0c;用于表示整数值。Integer是int的包装类&#xff0c;它是一个对象&#xff0c;可以包含一个int值并提供一些额外的功能。 Java集合框架中的集合类&#xff08;如List、Set、Map&#xff09;只能存储对象&#xff0c;…...

掘根宝典之C语言联合和枚举

联合 C语言中的联合&#xff08;Union&#xff09;是一种特殊的数据类型&#xff0c;它允许在同一块内存空间中存储不同类型的数据。 联合与结构体类似&#xff0c;但不同的是&#xff0c;在给联合变量赋值时&#xff0c;它只能存储最后一次赋值的值。 创建联合 在C语言中&…...

【debug】element-ui时间控件回显后不可编辑且显示为空

问题&#xff1a;使用element-ui的时间控件回显数据&#xff0c;编辑数据没有反应&#xff1a;点时间和“确认”按钮都没反应。 输入框中会显示数据&#xff0c;但提交时的校验显示为空。 <el-form-item label"开始时间" prop"limitStartTime"><…...

【Linux从青铜到王者】进程信号

——————————————————————————————————————————— 信号入门 在了解信号之前有许多要理解的相关概念 我们可以先通过一个生活例子来初步认识一下信号 1.生活角度的信号 你在网上买了很多件商品&#xff0c;再等待不同商品快递的到来…...

MyBatis-Plus 快速入门

介绍 j​​​​​MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window)的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 官网&#xff1a;MyBatis-Plus (baomidou.com) 1.…...

iOS调起高德/百度/腾讯/谷歌/苹果地图并使用GCJ02坐标进行导航

使用演示: 2.地图API相关网站 : 高德:...

HarmonyOS Full SDK的安装

OpenHarmony的应用开发工具HUAWEI DevEco Studio现在随着OpenHarmony版本发布而发布,只能在版本发布说明中下载,例如最新版本的OpenHarmony 4.0 Release。对应的需要下载DevEco Studio 4.0 Release,如下图。 图片 下载Full SDK主要有两种方式,一种是通过DevEco Studio下载…...

小程序嵌套H5-真机突然无法使用

今天测试反馈了一个问题&#xff0c;测试环境的小程序突然就登录不了了。我自己拿手机扫码登录是正常的&#xff0c;用其他同事的手机扫描登录也是正常。 下面是排查的路线&#xff1a; 1、其他环境使用测试手机扫码登录是否正常&#xff1f;(正常) 2、H5地址改为本地IP&#…...

自然语言处理 | 语言模型(LM) 浅析

自然语言处理&#xff08;NLP&#xff09;中的语言模型&#xff08;Language Model, LM&#xff09;是一种统计模型&#xff0c;它的目标是计算一个给定文本序列的概率分布&#xff0c;即对于任意给定的一段文本序列&#xff08;单词序列&#xff09;&#xff0c;语言模型能够估…...

全量知识系统问题及SmartChat给出的答复 之13 解析器+DDD+文法型

Q32. DDD的领域概念和知识系统中设计的解析器之间的关系。 那下面&#xff0c;我们回到前面的问题上来。 前面说到了三种语法解析器&#xff0c;分别是 形式语言的&#xff08;机器或计算机语言&#xff09;、人工语言的和自然语言的。再前面&#xff0c;我们聊到了DDD设计思…...

华中某科技大学校园网疑似dns劫持的解决方法

问题 在校园网ping xxx.ddns.net&#xff0c;域名解析失败 使用热点ping xxx.ddns.net&#xff0c;可以ping通 尝试设置windows dns首选dns为114.114.114.114&#xff0c;重新ping&#xff0c;仍然域名解析失败 猜测【校园网可能劫持dns请求】 解决方法 使用加密的dns请求…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...