分布式执行

一张工作流图。worker 覆盖每个平台。

Dagu 的分布式模式是同一个单二进制文件扮演两种角色:分发任务的 coordinator 和轮询任务的 worker。在 Linux、macOS 或 Windows 上启动 dagu worker,用标签描述这台机器,再用 worker_selector 路由整个 DAG 或单个步骤。worker 通过双向 TLS 保护的 gRPC 主动向外连接,因此不需要消息代理、共享数据库,也不需要在 worker 上开放入站端口。

一张夜间图,三个平台
# nightly-close.yaml
schedule: "0 2 * * *"
max_active_runs: 1

steps:
  # Windows box exports from the line-of-business system
  - id: export_sales
    action: dag.run
    with: { dag: export-sales }
    worker_selector:
      os: windows

  # Linux worker near the data transforms it
  - id: transform
    action: dag.run
    with: { dag: transform-sales }
    worker_selector:
      os: linux
      region: us-east-1
    depends: [export_sales]

  # GPU worker scores the result
  - id: score
    action: dag.run
    with: { dag: score-models }
    worker_selector:
      gpu: "true"
    depends: [transform]

一个二进制文件就是服务器、coordinator 和每个 worker

worker 可运行在 Linux、macOS 和 Windows 的 amd64 与 arm64 上

worker_selector 按标签路由整个 DAG 或单个步骤

worker 通过 mTLS 保护的 gRPC 向外连接,NAT 和私有网络都没问题

At a glance

分布式 Dagu 与基于消息代理的 worker 栈

组件数量
Dagu

一个二进制文件提供 coordinator 和 worker;没有代理,也没有结果后端。

消息代理栈

调度器、消息代理、结果存储和 worker 分开部署、分开升级。

混合 OS 机群
Dagu

在 Linux、macOS 和 Windows 上原生运行的 worker。

消息代理栈

worker 通常只支持 Linux;Windows 要走 WSL 或容器。

路由方式
Dagu

按 DAG 或步骤声明式设置 worker_selector 标签。

消息代理栈

命名队列,需要同时写进 worker 配置和任务代码。

worker 网络
Dagu

worker 通过 mTLS 保护的单一端口向外连接。

消息代理栈

worker 需要可达的代理端点和共享凭据。

In depth

Where each tool fits

01

横向扩展,而不引入一个平台

分布式执行是一种部署选择,不是重写。在一台机器上运行的 YAML 原样运行在集群上,队列在分发前仍然控制并发,必须留在主实例上的 DAG 用 worker_selector: local 把自己固定在那里。

  • 一个 worker 只需一条命令:dagu worker --worker.coordinators=<host>:50055 --worker.labels gpu=true
  • DAG 定义在分发时通过 gRPC 传给 worker,因此 worker 不需要保存仓库副本
  • default_execution_mode: distributed 会把所有运行发到集群;不设置时,只有带 worker_selector 的 DAG 会被分发
02

标签负责路由,机器保持可替换

worker 用键值标签声明自己是什么,DAG 用 worker_selector 声明自己需要什么,coordinator 负责匹配两者。因此扩容意味着再启动一个相同标签的 worker,而不是修改工作流。

  • 空选择器匹配任意 worker;带标签的选择器要求每个键都精确匹配
  • 带有额外标签的 worker 仍然匹配,因此一台机器可以同时服务多个池
  • dag.run 步骤上的 worker_selector 会把该子 DAG 发到与父级不同的 worker
03

混合操作系统与架构的机群

worker 是同一个 Go 二进制文件,为 Linux、macOS 和 Windows 的 amd64 与 arm64 发布。同一张图里,Windows worker 运行 PowerShell 步骤,Linux worker 运行 bash,状态、日志和历史都在一个地方查看。

  • 按约定打标签,例如 os=windows 或 arch=arm64,再用同样的选择器路由
  • shared-nothing 模式通过 gRPC 把日志和状态流式发送给 coordinator,不需要 NFS 或共享卷
  • worker 只向外连接,因此 NAT 之后、VPN 上或另一朵云里的机器都能加入机群
04

面向云与 Kubernetes

官方 Helm chart 在 Kubernetes 上部署 UI、调度器、coordinator 以及可选的 worker 池。worker 也可以从集群之外加入:虚拟机、裸金属或办公室里的 Windows 主机,跨边界流量由双向 TLS 认证两端。

  • helm repo add dagu https://dagucloud.github.io/dagu,然后用你的 values 执行 helm install
  • coordinator 只需要一个可达的 host:port;一个 Kubernetes Service 或内部负载均衡器就够了
  • coordinator 与 worker 通过 mTLS 互相校验证书

FAQ

Practical questions before adopting Dagu

需要消息代理或外部数据库吗?

不需要。coordinator 通过 gRPC 分发任务,worker 轮询它,并在同一条连接上回传心跳、状态和日志。shared-nothing 模式下完全没有共享存储;shared-filesystem 模式下,worker 写入服务器读取的同一个卷。

worker 能放在 NAT 之后或私有网络里吗?

可以。唯一必需的路径是 worker 到 coordinator 的一个 TCP 端口,coordinator 从不向 worker 反向发起连接。NAT 之后、VPN 上或另一朵云里的机器,只要拨通 coordinator 的地址即可加入。

Windows worker 怎么接入?

安装同一个二进制文件,用 os=windows 这样的标签启动 dagu worker,并给 Windows 的 DAG 配置匹配的 worker_selector。那台机器上的步骤在你配置的 shell 下运行,例如 shell: powershell -NoProfile,图的其余部分在别处运行。

可以把整个 Dagu 跑在 Kubernetes 上吗?

可以。官方 Helm chart 会渲染 UI、调度器、coordinator 以及你定义的各个 worker 池的 Deployment,并在 coordinator 前面放一个 ClusterIP Service。集群外的 worker 通过你暴露的 ingress 或负载均衡器指向该 Service。

worker 在运行中途下线会怎样?

worker 每秒发送一次心跳。当某个 worker 的心跳超过 30 秒没有更新时,coordinator 会把它正在运行的任务标记为失败,于是失败处理器和通知会被触发,而不是让运行永远挂起。

Next step

Start with one workflow.

Install Dagu, move one fragile script or agent task into YAML, and decide from a real run history.