一条数据链路每天都要跑,怎样保证它按时、按顺序、可重跑?

调度与编排:依赖与重跑

约 9 分钟5 道自测更新于 2026-10-31

一句话记住调度决定什么时候跑,编排决定先后和失败处理;无论工具怎么选,安全重跑和幂等都是底线。

01学完你能做到

  • 区分调度、编排、DAG、任务、运行和分区。
  • 说明 Airflow 与 Dagster 的主要设计差异。
  • 为行情流水线设计失败重试、分区重跑和历史回补。

02这课解决什么问题

收盘后要等数据到齐,再聚合、校验、发布;某天数据迟到或某一步失败时,怎样只重跑受影响的日期,而不是整条链路从头开始?

03核心概念

调度决定什么时候跑,例如工作日某时刻、每隔几分钟或上游文件到达后。编排决定任务顺序、依赖关系和失败处理。依赖关系通常表示为有向无环图(DAG),箭头表示先后关系,不能形成环。

Airflow 以流程和任务为中心:DAG 是流水线定义,Task 是步骤,Dag Run 是一次运行。按日运行时要区分逻辑日期、数据区间和实际启动时间;处理某个交易日的数据,不等于任务启动的那一刻就是该交易日。

Catchup 表示是否为过去缺失的数据区间创建运行;Backfill 表示主动为历史日期或分区创建运行。重试适合网络抖动、上游暂时不可用等临时故障,不适合数据口径错误或输入根本不存在的情况。

Dagster 以资产为中心:你声明要产出的表、文件或其他资产,以及它们的上游依赖;分区把资产按日期或其他维度切开,回补就是选择一批分区重新物化。

一句话比较:Airflow 先想“要跑哪些任务”,Dagster 先想“要产出哪些数据资产”。

04在行情链路中的位置

交易日历 → 判断是否交易日 → 等待上游到齐
       → 落地原始数据 → 聚合 / 复权 → 质量校验
       → 写发布分区 → 刷新缓存、记录血缘

调度系统本身不负责业务计算,它负责把各环节串起来。真实链路应按交易日历运行,而不是只用周一到周五的 cron;节假日和临时休市必须跳过。

05可重跑的最小设计

from pathlib import Path
import pandas as pd

def build_market_total(day, landing, output):
    source = Path(landing) / f"bars_{day}.csv"
    if not source.exists():
        raise RuntimeError(f"{day} 的输入还未到达")

    df = pd.read_csv(source)
    result = (df.assign(market=df["code"].str[-2:])
                .groupby("market", as_index=False)["turnover"]
                .sum())

    # 按日期覆盖写,而不是每次追加,确保同一日期重跑不会重复。
    target = Path(output) / f"turnover_{day}.csv"
    temp = target.with_suffix(".tmp")
    result.to_csv(temp, index=False)
    temp.replace(target)

任务读取指定日期的输入、写入指定日期的输出;不要在回补历史时读取“当前最新数据”。写出时使用临时文件再原子替换,或使用数据库事务,避免任务中途留下半份结果。

06常见误区

  1. 任务里读取“最新数据”,导致同一日期重跑时输入已变,结果不可复现。
  2. 用 cron 的 1-5 代替交易日历,漏掉节假日和临时休市。
  3. 混淆逻辑日期、数据区间和实际运行时间,造成差一天。
  4. 把重试当万能药,反复重试缺失数据或错误口径。
  5. 回补大量历史时不限制并发,打满上游和数据库。
  6. 结果使用追加写,重跑后出现重复记录。

07延伸阅读

08一分钟讲给别人

试着用自己的话讲一遍调度编排系统像后厨的厨师长:先等材料到齐,再按顺序加工,失败了重试或告警,哪天迟到就只重做哪天。Airflow 以任务流程为中心,Dagster 以数据资产为中心。无论使用哪个,任务都必须按指定日期读写,并做到重跑不重复、结果可复现。

想一想

5 道自测

先在心里答一遍,再展开对照。能说清理由,比答对数字更重要。

  1. 01调度和编排分别管什么?

  2. 02DAG 为什么不能有环?

  3. 03逻辑日期和实际运行时间有什么区别?

  4. 04什么情况下适合重试,什么情况下应直接失败告警?

  5. 05为什么任务不能读取“最新数据”?

已看 0/5 题

练动手练习

任务:为一个按交易日运行的两步流水线增加日期分区。模拟某天输入文件迟到:第一轮只让其他日期成功;文件补到后只重跑失败日期;最后重复重跑一个成功日期,检查输出内容和行数是否不变。

完成这一课

完成这一课

读完讲义、看完自测答案,这一课就算学完了。

  • 读完讲义
  • 看完全部自测

本课为投资者教育内容,案例数字均为示意,不构成任何投资建议,也不承诺收益。规则和费率会变,实际操作前请以交易所、监管机构和产品的最新公告为准。