Распределённое выполнение
Один граф воркфлоу. Воркеры на любой платформе.
Распределённый режим Dagu — это тот же единственный бинарный файл в двух ролях: координатор, раздающий работу, и воркеры, которые её опрашивают. Запустите dagu worker на Linux, macOS или Windows, опишите машину метками и направляйте целые DAG или отдельные шаги через worker_selector. Воркеры подключаются наружу по gRPC, защищённому взаимным TLS, поэтому не нужны ни брокер, ни общая база данных, ни входящий порт на воркере.
# 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]Один бинарный файл — это сервер, координатор и каждый воркер
Воркеры работают на Linux, macOS и Windows, на amd64 и arm64
worker_selector направляет целый DAG или отдельный шаг по меткам
Воркеры подключаются наружу по gRPC, защищённому mTLS, NAT и частные сети не помеха
At a glance
Распределённый Dagu и стек воркеров на брокере
Координатор и воркеры из одного бинарного файла; ни брокера, ни бэкенда результатов.
Планировщик, брокер, хранилище результатов и воркеры разворачиваются и обновляются по отдельности.
Нативные воркеры на Linux, macOS и Windows.
Воркеры обычно только для Linux; Windows — через WSL или контейнеры.
Декларативные метки worker_selector для DAG или шага.
Именованные очереди, прошитые и в конфиге воркеров, и в коде задач.
Воркеры подключаются наружу на один порт, защищённый mTLS.
Воркерам нужны доступные адреса брокера и общие учётные данные.
In depth
Where each tool fits
Масштабирование без внедрения платформы
Распределённое выполнение — это выбор способа развёртывания, а не переписывание. YAML, работающий на одной машине, без изменений работает на парке машин; очередь по-прежнему ограничивает параллелизм до диспетчеризации, а DAG, который должен остаться на основном инстансе, закрепляет себя там через worker_selector: local.
- Воркер — это одна команда: dagu worker --worker.coordinators=<host>:50055 --worker.labels gpu=true
- Определения DAG передаются воркерам по gRPC в момент диспетчеризации, поэтому воркерам не нужна копия репозитория
- default_execution_mode: distributed отправляет каждый запуск на парк машин; без него диспетчеризуются только DAG с worker_selector
Метки направляют работу, машины остаются взаимозаменяемыми
Воркер объявляет, что он такое, метками ключ-значение. DAG объявляет, что ему нужно, через worker_selector. Координатор сопоставляет одно с другим, поэтому добавить мощность — значит запустить ещё один воркер с теми же метками, а не править воркфлоу.
- Пустой селектор совпадает с любым воркером; селектор с метками требует точного совпадения каждого ключа
- Воркеры с дополнительными метками всё равно подходят, поэтому одна машина может обслуживать несколько пулов
- worker_selector на шаге dag.run отправляет этот под-DAG на другой воркер, отличный от родительского
Парк машин с разными ОС и архитектурами
Воркеры — это один и тот же бинарный файл на Go, выпускаемый для Linux, macOS и Windows на amd64 и arm64. В одном графе Windows-воркер выполняет шаги PowerShell рядом с Linux-воркером, выполняющим bash, а статус, логи и история видны в одном месте.
- Помечайте машины по соглашению, например os=windows или arch=arm64, и направляйте теми же селекторами
- Режим shared-nothing передаёт логи и статус координатору по gRPC, так что NFS и общий том не нужны
- Воркеры подключаются только наружу, поэтому машины за NAT, в VPN или в другом облаке могут присоединиться к парку
Готов к облаку и Kubernetes
Официальный Helm-чарт разворачивает в Kubernetes UI, планировщик, координатор и опциональные пулы воркеров. Воркеры могут присоединяться и извне кластера: виртуальные машины, bare metal или офисный Windows-хост, а взаимный TLS аутентифицирует обе стороны, когда трафик пересекает границу.
- helm repo add dagu https://dagucloud.github.io/dagu, затем helm install с вашими values
- Координатору нужен один доступный host:port; Kubernetes Service или внутреннего балансировщика достаточно
- Координатор проверяет сертификаты воркеров, а воркеры проверяют координатор по mTLS
FAQ
Practical questions before adopting Dagu
Нужен ли брокер сообщений или внешняя база данных?
Нет. Координатор раздаёт задачи по gRPC, воркеры опрашивают его и по тому же соединению отправляют обратно heartbeat, статус и логи. В режиме shared-nothing общего хранилища нет вовсе; в режиме shared-filesystem воркеры пишут в тот же том, который читает сервер.
Могут ли воркеры находиться за NAT или в частной сети?
Да. Единственный необходимый путь — от воркера к координатору по одному TCP-порту, и координатор никогда не открывает соединение обратно к воркеру. Машины за NAT, в VPN или в другом облаке присоединяются, просто набирая адрес координатора.
Как встроить Windows-воркеры?
Установите тот же бинарный файл, запустите dagu worker с метками вроде os=windows и задайте Windows-DAG соответствующий worker_selector. Шаги на этой машине выполняются в настроенной вами оболочке, например shell: powershell -NoProfile, а остальная часть графа работает в других местах.
Можно ли запустить весь Dagu в Kubernetes?
Да. Официальный Helm-чарт создаёт Deployment для UI, планировщика, координатора и определённых вами пулов воркеров, а перед координатором ставит ClusterIP Service. Воркеры вне кластера обращаются к этому Service через ingress или балансировщик, которым вы его открыли.
Что произойдёт, если воркер отключится посреди запуска?
Воркеры шлют heartbeat каждую секунду. Если heartbeat воркера не обновлялся более 30 секунд, координатор помечает его выполняющиеся задачи как неудавшиеся, поэтому срабатывают обработчики ошибок и уведомления, а запуск не зависает навсегда.
Next step
Start with one workflow.
Install Dagu, move one fragile script or agent task into YAML, and decide from a real run history.