调度页面上最容易被低估的是“状态”这一列。很多系统只存等待、运行、成功、失败四个值,再由调度器、执行器、回调接口和人工操作一起修改。刚上线时看不出问题;一旦消息延迟、worker 重启或用户点了重跑,同一个实例会在几秒内来回变色,最后状态与实际进程各说各话。
我设计实例状态机时,先问三个问题:谁有权写这个状态,凭什么证据迁移,迟到事件还能不能改变结论。状态不是 UI 文案,而是控制依赖、重试、资源回收和告警的业务协议。
邓明瑞 / 纯粹
调度页面上最容易被低估的是“状态”这一列。很多系统只存等待、运行、成功、失败四个值,再由调度器、执行器、回调接口和人工操作一起修改。刚上线时看不出问题;一旦消息延迟、worker 重启或用户点了重跑,同一个实例会在几秒内来回变色,最后状态与实际进程各说各话。
我设计实例状态机时,先问三个问题:谁有权写这个状态,凭什么证据迁移,迟到事件还能不能改变结论。状态不是 UI 文案,而是控制依赖、重试、资源回收和告警的业务协议。
补数据最危险的做法,是改一个业务日期参数,然后把它当普通调度实例再跑一遍。页面上只有一个绿色的“成功”,实际发生的事情可能是:旧分区被覆盖了一半、下游提前启动、失败重试又写出一份重复数据,最后谁也说不清当前结果来自哪版代码。
我更愿意把补数据看成一类独立运行,而不是正常调度的快捷入口。它至少要回答四个时间:处理哪段业务数据、何时提出请求、何时真正执行、哪一刻把结果发布给下游。再加一个独立的 run_id,这件事才有可追踪的起点。
数据任务失败后,排查过程经常是这样的:先在调度平台找到实例,再去 YARN 搜 application,进入引擎页面找 stage,最后 SSH 到某个节点翻 container 日志。中间任何一层 ID 没记住,就只能靠任务名和时间范围碰运气。
这不是日志数量不够,而是缺少关联键。调度器、提交服务、资源管理器和计算引擎各自都有状态,却没有一条稳定标识把它们连成同一次运行。平台最后只能截取“最近 100 行”放在失败弹窗里,看起来集中,实际上丢掉了大量上下文。
我做数据任务可观测性时,第一步不会先搭新的日志检索页面,而是把 schedule_instance_id 从创建实例开始传到执行端,并在每次外部资源分配后立即保存映射。只要关联关系可靠,日志、指标、trace 和配置才有机会组成证据链。