DolphinScheduler 任务失败排查:依赖未触发与无日志失败定位
从 Master 分发元数据边界切入,拆解依赖未触发与无日志失败两条排查链路,给出恢复与预防步骤
工作流实例显示失败却查不到运行日志,或者依赖节点显示条件已满足却没有触发下游,这两种现象可以先用同一个判据切开:看任务实例元数据里 host 与 start_time 是否为 NULL。只要这两个字段还是空的,任务就没有被 Master 分发到任何 Worker,执行日志为空是必然结果,问题出在调度侧;反过来,两个字段已有值而任务失败,才进入 Worker 执行与状态上报侧。以这条"分发边界"把故障拆成"依赖未触发"和"无日志失败"两条独立排查链路,比在日志里反复空转高效得多。
一、先用分发元数据定位故障落在哪一侧
打开工作流实例的任务实例详情,或直接查询元数据库的 t_ds_task_instance 表,重点看 state、host、submit_time、start_time、retry_times 几个字段:
SELECT task_code, task_type, state, host,
submit_time, start_time, retry_times
FROM t_ds_task_instance
WHERE process_instance_id = 12345;判断规则只有两句:host 与 start_time 同时为 NULL,任务停留在调度侧,包括依赖检查未通过、分发失败、没有可用 Worker;host 已有值但任务失败,才进入 Worker 侧,去查任务实例日志、Worker 日志和重试记录。任务实例日志既可以在界面的日志按钮里看,也落在 Worker 节点日志目录中按流程与任务实例组织的文件里。如果连日志文件都不存在,先回到这条判据确认任务是否真的被分发过——社区里记录的"实例失败但拿不到任何日志"现象(任务失败了,日志却消失了?)大多能用这个方法归类。
二、链路 A:依赖条件满足后仍未被触发
依赖类任务(DEPENDENT 类型)检查的是"被依赖工作流在指定调度周期内是否成功",而不是"上游今天有没有跑"。排查顺序建议如下。
先核对依赖取值与上游调度周期是否对齐。依赖配置里选的是"日/周/月/年"加偏移量的周期取值,如果上游按业务日期调度、依赖却取了当前日期,或者上游跑的是补数实例而依赖只认正常调度实例,就会出现"上游明明成功了、依赖却永远不满足"的错觉。这是依赖链路里最常见的根因。
再确认上游侧的三个前置条件:被依赖工作流的定时是否已上线(定时处于下线状态时不会生成实例)、调度时区与服务器时区是否一致、上游周期内是否真的生成并成功了工作流实例。任何一项不满足,依赖任务会一直停留在等待依赖状态,或在检查超时后失败。
最后区分"依赖未满足"和"依赖满足但当前实例没起来"。后者要查当前工作流自身的定时是否上线、Master 日志里是否有实例生成记录、工作流是否处于被下线或被冻结状态。这两类故障的现象相同,处置完全不同:前者改依赖配置或上游调度,后者修当前工作流的调度状态。
离线开发 BatchWorks
支持多模态、覆盖集成开发调度运维的一站式离线数据开发平台
三、链路 B:实例失败但没有任何运行日志
任务实例已经有 host 与 start_time 却查不到日志的情况相对少见,而 host 为空的失败更为多见,典型原因有四类。
一是没有可用执行资源。任务被分发到的 Worker 分组不存在、分组内 Worker 全部下线或心跳超时,Master 找不到目标节点,任务实例既不会启动也不会产生日志,host 始终为空。去查 Master 日志里的分发记录和 Worker 列表的存活状态,必要时核对任务所绑定的 Worker 分组配置。
二是 Master 故障转移后的残留。Master 发生容错切换时,处于分发过程中的任务可能被标记为失败而未真正启动,表现为实例失败、host/start_time 为空、重试次数已耗尽。此时查新 Master 日志中的容错恢复记录,并确认任务的失败重试次数与失败重试间隔配置是否允许系统自动拉起。
三是状态机与上报异常。任务实际已在 Worker 执行,但上报中断或状态流转卡住,界面上显示失败。这种情况 host 有值,去 Worker 日志里按任务实例 ID 检索执行痕迹,对比实例表中的结束时间与 Worker 实际执行时间。
四是"任务失败"与"告警失败"被混为一谈。任务失败但没收到通知,属于告警链路问题,与任务执行无关:核对工作流绑定的告警组与告警插件配置是否有效、Alert 服务日志里发送是否成功、通知渠道本身是否可用。告警通道应当单独做连通性验证,不要默认任务失败就一定有人收到通知。
四、恢复与重跑
定位清楚之后,恢复动作按影响范围选择。
- 单个任务出问题:修正配置后从失败节点重跑,避免重跑整条链路浪费上游产物。
- 依赖配置改过之后:先让被依赖的上游实例按正确周期生成并成功,再触发当前工作流,否则依赖依旧不满足。
- 历史数据缺失:使用补数(complement)能力按业务日期重刷历史区间,注意补数实例的调度时间与依赖取值要能被依赖任务识别。
- 分发侧故障恢复后:关注失败重试机制是否已把任务拉起,避免手工重跑与自动重试重复执行造成重复写入。
数据治理
统一标准、质量、安全与资产管理,沉淀高质量数据集,支撑经营决策、监管合规与 AI 应用。
五、预防清单
- 把依赖取值与上游调度周期的对齐关系写进工作流设计文档,新增依赖时逐项核对周期与偏移量。
- 定时上线前检查清单固定包含:时区一致、Worker 分组有效、告警组绑定并测试通过。
- 巡检里加入分发元数据检查:统计长时间
host为空的失败任务,这是调度侧故障的直接信号。 - 为关键工作流配置失败重试与多渠道告警,告警通道定期做一次真实发送演练。
当自建调度的排障成本持续上升时,一体化离线开发平台可以降低这类故障的定位与恢复成本——例如同时提供复杂依赖编排、历史数据重刷与多渠道告警,并把调度、血缘与质量校验贯穿到集成、开发、调度、运维全链路的方案,能让上面这些检查点从"人工翻表"变成平台能力。
六、排查示例:依赖未触发的一次完整走查
以一条每日定时的下游工作流出现"上游实例明明成功、依赖节点却始终不触发"为例(示意流程,字段与取值按实际环境替换)。第一步查 t_ds_task_instance:依赖任务的 host 与 start_time 为空、状态停留在等待依赖,问题被收窄到调度侧。第二步查被依赖的上游工作流实例:目标周期内确实存在成功实例,但该实例是补数生成的,调度时间落在业务日期上,而依赖配置取的是"当天"的调度周期——取值错位,依赖检查永远匹配不到。第三步把依赖取值改成与上游调度周期一致,重跑下游工作流,依赖检查通过、实例正常生成并执行。
这个走查里没有一步需要打开 Worker 日志:分发元数据在第一步就把范围收窄到了调度侧。反之,如果第一步看到 host 已有值,走查重心就换成任务日志、Worker 心跳与状态上报记录。先定边界、再走链路,是这类故障最省时间的顺序。


