ACK One Argo工作流:實現動態 Fan-out/Fan-in 任務編排

作者:莊宇

什麼是 Fan-out Fan-in

在工作流編排過程中,爲了加快大任務處理的效率,可以使用 Fan-out Fan-in 任務編排,將大任務分解成小任務,然後並行運行小任務,最後聚合結果。

由上圖,可以使用 DAG(有向無環圖)編排 Fan-out Fan-in 任務,子任務的拆分方式分爲靜態和動態,分別對應靜態 DAG 和動態 DAG。動態 DAG Fan-out Fan-in 也可以理解爲 MapReduce。每個子任務爲 Map,最後聚合結果爲 Reduce。

靜態 DAG: 拆分的子任務分類是固定的,例如:在數據收集場景中,同時收集數據庫 1 和數據庫 2 中的數據,最後聚合結果。

動態 DAG: 拆分的子任務分類是動態的,取決於前一個任務的輸出結果,例如:在數據處理場景中,任務 A 可以掃描待處理的數據集,爲每個子數據集(例如:一個子目錄)啓動子任務 Bn 處理,當所有子任務 Bn 運行結束後,在子任務 C 中聚合結果,具體啓動多少個子任務 B 取決由任務 A 的輸出結果。根據實際的業務場景,可以在任務 A 中自定義子任務的拆分規則。

ACK One 分佈式工作流 Argo 集羣

在實際的業務場景中,爲了加快大任務的執行,提升效率,往往需要將一個大任務分解成數千個子任務,爲了保證數千個子任務的同時運行,需要調度數萬核的 CPU 資源,疊加多任務需要競爭資源,一般 IDC 的離線任務集羣難以滿足需求。例如:自動駕駛仿真任務,修改算法後的迴歸測試,需要對所有駕駛場景仿真,每個小駕駛場景的仿真可以由一個子任務運行,開發團隊爲加快迭代速度,要求所有子場景測試並行執行。

如果您在數據處理,仿真計算和科學計算等場景中,需要使用動態 DAG 的方式編排任務,或者同時需要調度數萬核的 CPU 資源加快任務運行,您可以使用阿里雲 ACK One 分佈式工作流 Argo 集羣 [ 1]

ACK One 分佈式工作流 Argo 集羣,產品化託管 Argo Workflow [ 2] ,提供售後支持,支持動態 DAG Fan-out Fan-in 任務編排,支持按需調度雲上算力,利用雲上彈性,調度數萬核 CPU 資源並行運行大規模子任務,減少運行時間,運行完成後及時回收資源節省成本。支持數據處理,機器學習,仿真計算,科學計算,CICD 等業務場景。

Argo Workflow 是開源 CNCF 畢業項目,聚焦雲原生領域下的工作流編排,使用 Kubernetes CRD 編排離線任務和 DAG 工作流,並使用 Kubernetes Pod 在集羣中調度運行。

本文介紹使用 Argo Workflow 編排動態 DAG Fan-out Fan-in 任務。

Argo Workflow 編排 Fan-out Fan-in 任務

我們將構建一個動態 DAG Fan-out Fan-in 工作流,讀取阿里雲 OSS 對象存儲中的一個大日誌文件,並將其拆分爲多個小文件(split),啓動多個子任務分別計算每個小文件中的關鍵詞數量(count),最後聚合結果(merge)。

  1. 創建分佈式工作流 Argo 集羣 [ 3]

  2. 掛載阿里雲 OSS 存儲卷,工作流可以像操作本地文件一樣,操作阿里雲 OSS 上的文件。參考:工作流使用存儲卷 [ 4]

  3. 使用以下工作流 YAML 創建一個工作流,參考:創建工作流 [ 5] 。具體說明參見注釋。

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: dynamic-dag-map-reduce-
spec:
  entrypoint: main
  # claim a OSS PVC, workflow can read/write file in OSS through PVC. 
  volumes:
    - name: workdir
      persistentVolumeClaim:
        claimName: pvc-oss
  # how many tasks to split, default is 5.
  arguments:
    parameters:
      - name: numParts
        value: "5"
  templates:
    - name: main
      # DAG definition.
      dag:
        tasks:
          # split log files to several small files, based on numParts.
          - name: split
            template: split
            arguments:
              parameters:
                - name: numParts
                  value: "{{workflow.parameters.numParts}}"
          # multiple map task to count words in each small file.
          - name: map
            template: map
            arguments:
              parameters:
                - name: partId
                  value: '{{item}}'
            depends: "split"
            # run as a loop, partId from split task json outputs.
            withParam: '{{tasks.split.outputs.result}}'
          - name: reduce
            template: reduce
            arguments:
              parameters:
                - name: numParts
                  value: "{{workflow.parameters.numParts}}"
            depends: "map"
    # The `split` task split the big log file to several small files. Each file has a unique ID (partId).
    # Finally, it dumps a list of partId to stdout as output parameters
    - name: split
      inputs:
        parameters:
          - name: numParts
      container:
        image: acr-multiple-clusters-registry.cn-hangzhou.cr.aliyuncs.com/ack-multiple-clusters/python-log-count
        command: [python]
        args: ["split.py"]
        env:
        - name: NUM_PARTS
          value: "{{inputs.parameters.numParts}}"
        volumeMounts:
        - name: workdir
          mountPath: /mnt/vol
    # One `map` per partID is started. Finds its own "part file" and processes it.
    - name: map
      inputs:
        parameters:
          - name: partId
      container:
        image: acr-multiple-clusters-registry.cn-hangzhou.cr.aliyuncs.com/ack-multiple-clusters/python-log-count
        command: [python]
        args: ["count.py"]
        env:
        - name: PART_ID
          value: "{{inputs.parameters.partId}}"
        volumeMounts:
        - name: workdir
          mountPath: /mnt/vol
    # The `reduce` task takes the "results directory" and returns a single result.
    - name: reduce
      inputs:
        parameters:
          - name: numParts
      container:
        image: acr-multiple-clusters-registry.cn-hangzhou.cr.aliyuncs.com/ack-multiple-clusters/python-log-count
        command: [python]
        args: ["merge.py"]
        env:
        - name: NUM_PARTS
          value: "{{inputs.parameters.numParts}}"
        volumeMounts:
        - name: workdir
          mountPath: /mnt/vol
      outputs:
        artifacts:
          - name: result
            path: /mnt/vol/result.json
  1. 動態 DAG 實現

1)split 任務在拆分大文件後,會在標準輸出中輸出一個 json 字符串,包含:子任務要處理的 partId,例如:

["0", "1", "2", "3", "4"]

2)map 任務使用 withParam 引用 split 任務的輸出,並解析 json 字符串獲得所有 {{item}},並使用每個 {{item}} 作爲輸入參數啓動多個 map 任務。

          - name: map
            template: map
            arguments:
              parameters:
                - name: partId
                  value: '{{item}}'
            depends: "split"
            withParam: '{{tasks.split.outputs.result}}'

更多定義方式,請參考開源 Argo Workflow 文檔 [ 6]

  1. 工作流運行後,通過分佈式工作流 Argo 集羣控制檯 [ 7] 查看任務 DAG 流程與運行結果。

  1. 阿里雲 OSS 文件列表,log-count-data.txt 爲輸入日誌文件,split-output,cout-output 中間結果目錄,result.json 爲最終結果文件。

  1. 示例中的源代碼可以參考:AliyunContainerService GitHub argo-workflow-examples [ 8]

總結

Argo Workflow 是開源 CNCF 畢業項目,聚焦雲原生領域下的工作流編排,使用 Kubernetes CRD 編排離線任務和 DAG 工作流,並使用 Kubernetes Pod 在集羣中調度運行。

阿里雲 ACK One 分佈式工作流 Argo 集羣,產品化託管 Argo Workflow,提供售後支持,加固控制面實現數萬子任務(Pod)穩定高效調度運行,數據面支持無服務器方式調度雲上大規模算力,無需運維集羣或者節點,支持按需調度雲上算力,利用雲上彈性,調度數萬核 CPU 資源並行運行大規模子任務,減少運行時間,支持數據處理,機器學習,仿真計算,科學計算,CICD 等業務場景。

歡迎加入 ACK One 客戶交流釘釘羣與我們進行交流。(釘釘羣號:35688562

相關鏈接:

[1] 阿里雲 ACK One 分佈式工作流 Argo 集羣

https://help.aliyun.com/zh/ack/overview-12

[2] Argo Workflow

https://argo-workflows.readthedocs.io/en/latest/

[3] 創建分佈式工作流 Argo 集羣

https://help.aliyun.com/zh/ack/create-a-workflow-cluster

[4] 工作流使用存儲卷

https://help.aliyun.com/zh/ack/use-volumes

[5] 創建工作流

https://help.aliyun.com/zh/ack/create-a-workflow

[6] 開源 Argo Workflow 文檔

https://argo-workflows.readthedocs.io/en/latest/walk-through/loops/

[7] 分佈式工作流 Argo 集羣控制檯

https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Fcs.console.aliyun.com%2Fone%3Fspm%3Da2c4g.11186623.0.0.7e2f1428OwzMip#/argowf/cluster/detail

[8] AliyunContainerService GitHub argo-workflow-examples

https://github.com/AliyunContainerService/argo-workflow-examples/tree/main/log-count

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章