BigQuery ジョブを Workflows と並行して実行する

1. はじめに

1c05e3d0c2bd2b45.png 74be7b376d45258a.png

Workflows はフルマネージドのオーケストレーション サービスで、定義した順序で Google Cloud または外部サービスを実行します。

BigQuery は、ML、地理空間分析、ビジネス インテリジェンスなどの組み込み機能を使用して、テラバイト規模のデータの管理と分析を支援する、フルマネージドのエンタープライズ データ ウェアハウスです。

この Codelab では、Wikipedia の公開データセットに対して BigQuery クエリを実行します。その後、Workflows オーケストレーションの一環として、複数の BigQuery クエリを順番に連続して実行する方法を確認します。最後に、Workflows の並列イテレーション機能を使用してクエリを並列化し、速度を最大 5 倍向上させます。

学習内容

  • Wikipedia データセットに対して BigQuery クエリを実行する方法。
  • Workflows オーケストレーションの一部として複数のクエリを順番に実行する方法。
  • Workflows の並列イテレーションを使用してクエリを並列化し、速度を最大 5 倍に改善する方法。

2. 設定と要件

セルフペース型の環境設定

  1. Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列です。この値はいつでも更新できます。
  • プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud コンソールでは一意の文字列が自動生成されます。通常、それが何であるかは関係ありません。ほとんどの Codelab では、プロジェクト ID を参照する必要があります(通常は PROJECT_ID として識別されます)。生成された ID が気に入らない場合は、別のランダムな ID を生成できます。または、ご自身でお試しになることもできます。このステップを終えた後は変更できず、プロジェクト期間中は維持されます。
  • なお、3 つ目の値は、一部の API で使用される [プロジェクト番号] です。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
  1. 次に、Cloud のリソースや API を使用するために、Cloud コンソールで課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルの終了後に課金が発生しないようにリソースをシャットダウンするには、作成したリソースを削除するか、プロジェクト全体を削除します。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

Cloud Shell の起動

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。

Google Cloud Console で、右上のツールバーにある Cloud Shell アイコンをクリックします。

55efc1aaa7a4d3ad.png

プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。

7ffe5cbb04455448.png

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が大幅に向上しています。この Codelab での作業はすべて、ブラウザ内から実行できます。インストールは不要です。

3. Wikipedia データセットを調べる

まず、BigQuery で Wikipedia データセットを探索します。

Google Cloud コンソールの [BigQuery] セクションに移動します。

ea75ab12a7c012a4.png

bigquery-samples の下に、Wikipedia 関連のデータセットなど、さまざまな一般公開データセットが表示されます。

c9484e305b8e1438.png

wikipedia_pageviews データセットには、さまざまな年のページビューに関するさまざまなテーブルが表示されます。

c540a4162640cbb3.png

テーブル(例:201207 など)を指定し、データをプレビューします。

b5b2a334cd6f63c0.png

テーブルに対してクエリを実行することもできます。たとえば、次のクエリは視聴回数が最も多い上位 100 件のタイトルを選択します。

SELECT TITLE, SUM(views)
FROM bigquery-samples.wikipedia_pageviews.201207h
GROUP BY TITLE
ORDER BY SUM(VIEWS) DESC
LIMIT 100

クエリの実行後、データの読み込みに約 20 秒かかります。

1df3877aed1653b4.png

4. 複数のクエリを実行するワークフローを定義する

単一テーブルに対してクエリを実行するのは簡単です。しかし、複数のテーブルに対して複数のクエリを実行して結果を照合するのはかなり面倒です。これを行うために、Workflows は iteration 構文の支援をします。

Cloud Shell 内で workflow-serial.yaml ファイルを作成し、複数のテーブルに対して複数のクエリを実行するワークフローを構築します。

touch workflow-serial.yaml

このファイルは Cloud Shell のエディタで編集できます。

33bf9325b078ad8.png

workflow-serial.yaml ファイル内の最初の init ステップで、テーブル名をキーとする各イテレーションを追跡する results マップを作成します。また、クエリを実行するテーブルのリストを含む tables 配列を定義します。この例では、5 つのテーブルを選択します。

main:
    steps:
    - init:
        assign:
            - results : {}
            - tables:
                - 201201h
                - 201202h
                - 201203h
                - 201204h
                - 201205h

次に、runQueries ステップを定義します。このステップは各テーブルに対して反復され、Workflows のBigQuery コネクタを使用してクエリを実行し、各テーブルでページビュー数が最も多い上位 100 件のタイトルを調べる。その後、結果マップの各テーブルで上位のタイトルとビューを保存します。

    - runQueries:
        for:
            value: table
            in: ${tables}
            steps:
            - runQuery:
                call: googleapis.bigquery.v2.jobs.query
                args:
                    projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                    body:
                        useLegacySql: false
                        useQueryCache: false
                        timeoutMs: 30000
                        # Find the top 100 titles with most views on Wikipedia
                        query: ${
                            "SELECT TITLE, SUM(views)
                            FROM `bigquery-samples.wikipedia_pageviews." + table + "`
                            WHERE LENGTH(TITLE) > 10
                            GROUP BY TITLE
                            ORDER BY SUM(VIEWS) DESC
                            LIMIT 100"
                            }
                result: queryResult
            - returnResult:
                assign:
                    # Return the top title from each table
                    - results[table]: {}
                    - results[table].title: ${queryResult.rows[0].f[0].v}
                    - results[table].views: ${queryResult.rows[0].f[1].v}

最後のステップでは、results マップを返します。

    - returnResults:
        return: ${results}

5. Workflows で複数のクエリを実行する

ワークフローをデプロイして実行する前に、Workflows API が有効になっていることを確認する必要があります。これは、Google Cloud コンソールから、または Cloud Shell で gcloud を使用して有効にできます。

gcloud services enable workflows.googleapis.com

Workflows のサービス アカウントを作成します。

SERVICE_ACCOUNT=workflows-bigquery-sa
gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Workflows BigQuery service account"

BigQuery ジョブを記録して実行するロールがサービス アカウントにあることを確認します。

PROJECT_ID=your-project-id
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --role roles/logging.logWriter \
  --role roles/bigquery.jobUser \
  --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

サービス アカウントを使用してワークフローをデプロイします。

gcloud workflows deploy bigquery-serial \
    --source=workflow-serial.yaml \
    --service-account=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

これでワークフローを実行する準備が整いました

Cloud コンソールの [ワークフロー] セクションで bigquery-serial ワークフローを見つけて、[Execute] ボタンをクリックします。

b6afa4747680334f.png

また、Cloud Shell で gcloud を使用してワークフローを実行することもできます。

gcloud workflows run bigquery-serial

ワークフローの実行は約 1 分(5 つのテーブルでそれぞれ 20 秒)継続するはずです。

最後に、上位のタイトルとビューを含む各表の出力が表示されます。

304d11a5bffdada4.png

baf31533d3671c9e.png

6. 並列ステップで複数のクエリを並列化する

前のステップのワークフローでは 5 つのクエリを実行し、それぞれに 20 秒かかっていたため、約 1 分かかりました。これらは独立したクエリであるため、実際には Workflows の並列反復処理機能を使用して並列実行できます。

workflow-serial.yaml ファイルを新しい workflow-parallel.yaml ファイルにコピーします。新しいファイルでいくつかの変更を加えて、シリアル ステップを並列ステップに変換します。

workflow-parallel.yaml ファイルで、runQueries ステップを変更します。まず、parallel キーワードを追加します。これにより、for ループの各反復処理を並列実行できます。次に、results 変数を shared 変数として宣言します。これにより、ブランチで変数に書き込めるようになります。この変数に各結果を追加します。

- runQueries:
    parallel:
        shared: [results]
        for:
            value: table
            in: ${tables}

並列ワークフローをデプロイします。

gcloud workflows deploy bigquery-parallel \
    --source=workflow-parallel.yaml \
    --service-account=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

ワークフローを実行する

gcloud workflows run bigquery-parallel

ワークフローの実行が約 20 秒間継続することがわかります。これは、5 つのクエリすべてが並行して実行されるためです。わずか数行のコード変更で最大 5 倍の速度向上

最終的には、各テーブルから上位のタイトルとビューを含む同じ出力が表示されますが、実行時間は大幅に短縮されています。

1825d49ef225c828.png

7. 完了

これでこの Codelab は終了です。詳細については、並列ステップに関する Workflows のドキュメントをご覧ください。

学習した内容

  • Wikipedia データセットに対して BigQuery クエリを実行する方法。
  • Workflows オーケストレーションの一部として複数のクエリを順番に実行する方法。
  • Workflows の並列イテレーションを使用してクエリを並列化し、速度を最大 5 倍に改善する方法。