资讯动态

一次“没有运行日志”的DolphinScheduler任务失败排查

发布时间:2026/8/24 4:07:18 来源:尧图企业网站定制
引子失败了却没有一行运行日志生产调度中最让人困惑的场景之一是任务页面明确显示“失败”告警也已经生成但任务的开始时间、执行主机、执行目录和日志路径全部为空。没有Worker日志没有YARN Application ID更没有Spark Driver、Executor或MapReduce Container日志。面对这种现象很多排查会本能地从Worker、脚本路径、YARN和网络连通性入手。但本案例最终证明任务甚至还没有进入Worker故障发生在Master构造任务执行上下文的阶段。真正的根因不是脚本也不是虚拟IP而是工作流没有绑定有效租户。核心结论当 task_instance 已是失败状态但 host、start_time、log_path、execute_path 全部为 NULL 时应优先排查 Master 提交与分发阶段而不是继续寻找不存在的任务运行日志。1.故障现场前端失败、告警失败、日志为空案例中的批量任务每天14:15触发。调度前端显示首个Shell节点失败后续节点未执行。告警表中已经产生“scheduler failed”记录但告警发送日志又出现“no bind plugin instance”。从 t_ds_alert 反查最近一条失败告警SELECT id, title, content, alert_status, warning_type, log, alertgroup_id, create_time, process_instance_id FROM t_ds_alert ORDER BY create_time DESC LIMIT 1;告警内容里包含工作流实例ID、任务Code、任务名称、任务类型和失败状态因此可以用它作为整条证据链的入口。但这里必须区分两个问题任务执行失败与告警发送失败是相互独立的。排查原则不要把“告警发送失败”当成任务失败原因。先定位任务在哪个生命周期阶段失败再单独处理告警路由。2.第一条证据元数据表证明任务从未进入Worker通过告警中的 process_instance_id 和 taskCode可以精确查询 t_ds_task_instance。结果显示任务实例已创建状态为6FAILURE但除了 submit_time 外其余运行字段均为空。定位任务实例的生命周期字段SELECT id AS task_instance_id, name, state, host, submit_time, start_time, end_time, log_path, execute_path, app_link FROM t_ds_task_instance WHERE process_instance_id process_instance_id AND task_code task_code ORDER BY id DESC;到这里可以做出第一个关键判断任务失败发生在Worker执行之前。继续SSH到Worker寻找日志、执行 yarn logs 或分析Spark Executor没有意义因为对应的执行实体根本没有创建。3.一个容易误判的支线Master为什么显示成另一个IP排查过程中Master节点的主IP与调度前端显示的Master地址不一致。SSH到前端显示地址后主机名和Shell提示符仍然显示主IP一度怀疑发生了错误路由或地址注册异常。同时确认SSH连接四元组、主机名和全部网卡地址echo $SSH_CONNECTION hostname -f ip -br addrip -br addr 最终显示主IP以 /24 绑定另一个地址以 /32 绑定在同一块 eth0 上。后者解析为EMR虚拟主机名因此它不是另一台机器而是同一节点的辅助/虚拟服务IP。仅在Master本机SSH虚拟IP只能证明本机可达。为了验证调度通信是否真的正常必须从一台实际Worker节点测试Master端口。从实际Worker节点测试两个Master地址nc -vz -w 3 master-primary-ip 5678 nc -vz -w 3 master-virtual-ip 5678两个地址的5678端口都能连通Master心跳日志也持续成功写入 /nodes/master/:5678。至此可以排除Master注册地址不可达。经验前端显示IP与主机主IP不一致不等于地址错误。先确认是否为同机辅助IP/VIP再从真实通信对端验证业务端口不要只做本机自连接测试。3.决定性证据Master日志中的 Tenant does not exists既然任务从未进入Worker真正的日志应当在Master。使用工作流实例ID、任务实例ID、任务Code和任务名称检索Master日志后故障链路被精确还原。使用多个稳定标识关联同一次调度grep -R -nE WorkflowInstance-id|TaskInstance-id|task_code|task_name /var/log/.../master-server/故障发生在几毫秒内尚未真正分发到Worker14:15:00.650 Task is ready to dispatch to worker 14:15:00.651 Tenant does not exists 14:15:00.651 Task state changes to FAILURE 14:15:00.652 Get taskExecutionContext fail 14:15:00.653 Dispatch standby task failed 14:15:00.690 Workflow state changes to FAILURE日志对象进一步给出决定性字段processDefinition.tenantId-1、tenantCodenullprocessInstance.tenantId-1、tenantCodenull、queuenull。Master在构造TaskExecutionContext时必须确定执行租户而当前工作流没有任何有效租户因此任务直接失败。根因工作流定义与工作流实例的 tenantId 均为 -1tenantCode 为空。Master无法生成任务执行上下文任务在分配Worker之前被置为FAILURE。5.为什么没有日志理解DolphinScheduler任务生命周期DolphinScheduler的任务日志不是在TaskInstance写入数据库时产生而是在Master成功构造上下文、选中Worker并由Worker创建执行目录后才会拥有log_path。理解这个顺序是处理“失败但无日志”的关键。这套字段判断还能快速指导日志采集策略host为空时查Masterhost有值但start_time为空时查分发与Worker接收log_path有值时查Worker日志出现Application ID后才进入YARN日志采集。6.Tenant到底承担什么角色在DolphinScheduler中Tenant不仅是一个界面上的分类字段它通常关联任务的运行身份与资源队列。Master构造任务执行上下文时需要从工作流定义、执行用户和租户表中解析出tenantCode与queue。缺少这组信息Master无法安全地告诉Worker“用谁的身份、在哪个队列执行”。在启用了Linux用户切换、HDFS权限、Kerberos或YARN队列隔离的环境中租户配置还会进一步影响系统用户、HDFS目录、票据身份和资源队列。因此修复租户后仍应验证对应OS用户和大数据平台权限。7.用元数据确认租户关系核对工作流、用户与租户的关联SELECT pd.id, pd.code, pd.name, pd.version, pd.user_id, u.user_name, pd.tenant_id AS workflow_tenant_id, u.tenant_id AS user_tenant_id, t.id AS matched_tenant_id, t.tenant_code, t.queue_id FROM t_ds_process_definition pd LEFT JOIN t_ds_user u ON u.id pd.user_id LEFT JOIN t_ds_tenant t ON t.id pd.tenant_id WHERE pd.code process_definition_code;确认租户是否存在并检查历史工作流版本SELECT * FROM t_ds_tenant ORDER BY id; SELECT * FROM t_ds_user WHERE id user_id OR user_name user_name; SELECT code, name, version, tenant_id, release_state FROM t_ds_process_definition_log WHERE code process_definition_code ORDER BY version DESC;本案例的预期异常结果是 workflow_tenant_id-1并且无法关联到 t_ds_tenant。若用户已有租户但工作流仍为-1说明工作流创建、导入或版本迁移时没有正确继承租户只修改用户并不一定会自动回填既有工作流。8.修复步骤不要直接UPDATE元数据库推荐通过调度前端完成修复避免绕过版本日志、缓存、权限关系与审计信息。标准处理步骤如下在安全中心的租户管理中创建或选择有效租户并关联正确的YARN Queue。在用户管理中为工作流负责人绑定该租户。编辑故障工作流重新选择有效租户并保存生成新的工作流版本。重新上线工作流与定时调度确认最新 t_ds_process_definition.tenant_id 大于0。从新版本发起一次全新的手动运行不直接恢复旧的失败实例。任务进入Worker后再验证Linux用户、脚本权限、HDFS/Kerberos以及YARN Queue权限。为什么不重跑旧实例旧实例保存的是旧工作流版本快照其中 tenantId 仍为 -1。直接恢复失败节点可能继续使用旧配置发布新版本后应创建新实例验证。9.修复后如何验收修复后的验证不能只看页面变绿还要确认任务确实跨过了原故障点。建议同时检查定义层、实例层和运行层。定义层最新工作流版本 tenant_id 为有效正数能够关联到 t_ds_tenant。实例层新流程实例 tenantCode、queue 不再为空。分发层TaskInstance.host 不为空并能看到Worker接收记录。运行层start_time、execute_path、log_path 正常生成。大数据作业层若脚本提交Spark/MR能够提取Application ID并查询YARN日志。结语没有日志本身就是日志在调度系统里“没有日志”并不意味着没有线索。相反host、start_time、execute_path、log_path 和 app_link 同时为空已经非常明确地告诉我们任务尚未进入执行层。沿着这个事实回到Master几毫秒级的时间线最终指向 Tenant does not exists。一次高质量排障不是把所有组件都查一遍而是用元数据划定边界用日志建立时间线用网络测试排除支线再把任务失败与告警失败分别闭环。只有这样才能从“经验式排查”走向可解释、可复用、可产品化的诊断体系。一句话总结TaskInstance失败且所有运行字段为NULL先查Master本案例的直接根因是工作流 tenantId-1Master无法构造TaskExecutionContext。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价