wordpress 删除小工具栏,威海seo网站推广,wordpress网易云插件,生成图片的网站目录
一、技术架构
二、业务挑战
2.1 调度任务量大
2.2 运维复杂
2.3 SLA要求高
三、调度优化实践
3.1 重复调度
3.2 漏调度
3.3 Worker服务卡死
3.4 任务重复运行
四、服务监控
4.1 方法耗时监控
4.2 任务调度链路监控
五、用户收益 原文大佬的这篇调度系统案例…目录
一、技术架构
二、业务挑战
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对应工作流的定时器IDJOB_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_TIME86400000*2sql逻辑是根据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 idmaster容错时就能杀死旧任务。 第二个改进点为在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 在奇富科技的首个调度异地部署实践