Workflowsの並列処理実装方法を考えてみた

Workflowsの並列処理実装方法である並列forと並列ブランチに関して、向いているケース向いていないケースなどを考えてみました。
2024.06.05

Workflowsと日々向き合っているデータアナリティクス事業本部の根本です。Workflowsで並列処理をする場合、並列forループを用いてループ内で並列処理することが多いですが、Workflowsには並列ブランチという機能もあります。今回の記事では並列ブランチと並列forを用いた並列処理の実装方法に関して考えてみました。Workflowsが好きな方はぜひ読んでみてください。

この記事の対象者

  • Workflowsで並列処理を行いたいひと

※Workflowsの並列処理とはなんぞや、という方は以下の記事を先に読んでみてください。

はじめに:Workflowsの並列処理実装方法

まずはWorkflowsで並列処理を行うときに用いる並列ブランチ並列forに関してご説明します。

並列ブランチ

parallelステップ内でbranchesステップを用いることで並列ブランチとして実装することができます。branchesステップ内にある処理が並列で実行されます。
イメージとしては以下となります。

branchesは「枝」の英単語ですし、並列処理が枝のように分けて定義できるというようなイメージとなります。
並列ブランチの構文は以下となります(公式サイトから引用)

  - PARALLEL_STEP_NAME:
      parallel:
          ...
          branches:
            - BRANCH_NAME_A:
                steps:
                    ...
            - BRANCH_NAME_B:
                steps:
                    ...

並列ブランチを用いた実装例としては以下となります。

parallel:
    branches:
        - getDateBranch:
            steps:
                - getDate:
                    call: http.get
                    args:
                        url: 'Cloud Functions関数のURL'
                    result: get_date_result
        - getUserNameBranch:
            steps:
                - getUserName:
                    call: http.get
                    args:
                        url: 'Cloud Functions関数のURL'
                    result: get_user_name

上記の処理の場合、getDateBranchgetUserNameBranchが並列で実行され、それぞれのステップが順次実行されます。

並列for

Workflowsでの並列処理をする際には、並列forも用いることができます。例としては以下の実装です。

assigh:
    - loop_counter: [1, 2, 3, 4, 5]
parallel:
    for:
        value: num
        in: ${loop_counter}
        steps:
            - notify:
                call: http.post
                args:
                    url: "Cloud Functions関数のURL"
                    body:
                        loop_number: ${num}

並列でCloud Functions関数を呼び出すイメージの実装です。上記のような並列forループを実行すると、Cloud Functions関数を5回、並列実行で呼び出します。
[1, 2, 3, 4, 5]の順序で実行されるわけではありません。通常のfor文ではイテレーションが配列などの順序通りに行われますが、並列forループでは並列実行となるため順序が不定となります。
[1, 3, 5, 4, 2]であったり、[5, 4, 3, 2, 1]となるなど実行するたびに実行順序は変わります。よって並列処理をする際には当たり前ですが処理の順序関係には気をつける必要があります。

並列ブランチと並列forの使い分け

どんなケースが向いているか考えてみました。

パターン 向いているケース 向いていないケース
並列ブランチ 並列処理する対象が固定 並列処理する対象が可変。反復処理
並列for 並列処理する対象が可変。反復処理 並列処理する対象が固定

並列ブランチはあらかじめ並列処理する対象をブランチとして実装しておく必要があります。
一方で並列forはリストを元にイテレーションすることができるので、例えば並列forでCloud Functions関数の呼び出して、関数の引数にリスト内容をそれぞれ渡す、というような処理を実装することができます。
ただ、1回だけこの処理を並列で行いたい!という場合には並列forでは1回だけループするようにする、という実装になるので可読性も悪く勿体無い実装になってしまいます。こういったときは並列ブランチが向いています。

パターン ユースケース
並列ブランチ 1回だけ並列処理したい場合
並列for リスト内容を元に並列処理したい場合。反復的に並列処理したい場合

例えば、Cloud Functions関数でCloud Storageの指定バケット内のファイル一覧を取得してそのリストを元に並列forで対象ファイルを並列処理する、なんてことも並列forではできてしまいます。
一方で日次で決まりきったバッチ処理を並列でサクッと行なってしまいたい、という場合には並列ブランチを活用することができます。
どっちが優れている劣っている、なんてことはなくどちらもとっても優れていていい子達なんです。

おわりに

みなさんのワークロードはどちらの並列処理が向いていたでしょうか?それぞれ向いているユースケースがあるので並列処理を行う際はどっちにするか考えてみると面白いかもしれません。また、Workflowsの並列処理には上限があるのでご注意ください。
この記事がWorkflowsでの並列処理に困っている方のお役に立てば嬉しいです。それではまた。