コンピュートとストレージの分離から紐解くBigQueryの権限モデル

OGP

こんにちは。SRE部DATA-SREチームの塩崎です。Software Design誌の2021年9月号に弊社でのBigQuery活用事例を寄稿しましたので、書店などで見かけた際は購入していただけますと嬉しいです。

gihyo.jp

さて、BigQueryはコンピュートとストレージを分離することで高いスケーラビリティを達成しているData WareHouse(DWH)です。しかし、そのアーキテクチャを採用したがゆえに権限モデルが複雑化し、初心者にとって理解の難しい挙動をすることもあります。この記事ではBigQueryの権限モデルをコンピュートとストレージの分離という観点から紐解きます。

なお、記事中に記載している費用は全てUS Multi Regionにおけるものです。asia-northeast-1 Resion(東京)とは異なりますので、ご注意ください。

よくあるエラーとそこから湧く疑問

BigQueryを使い始めた人が高確率で遭遇する問題として、「BigQuery Data Viewerロールを割り当てたのにも関わらずSELECT文が実行できない」というものがあります。MySQLなどのRDBにおけるGRANT SELECT ON 〜と同じような感覚で権限を割り当てると発生しやすい問題です。

権限エラー

このケースでは、上記の権限に加えてBigQuery Job User権限の付与で問題なくSELECTが実行できます。ここで以下の疑問が浮かびます。

  • なぜ片方の権限だけではエラーになってしまうのか
  • これらの権限はセットで使うことが必須なのだろうか
  • 片方の権限のみで問題ないケースはどのような時だろうか

cloud.google.com

以降ではBigQueryのアーキテクチャに触れながらこれらの疑問に答えていきます。

BigQueryのアーキテクチャについて

BigQueryのアーキテクチャとして特徴的なものは、下図に示すコンピュートとストレージの分離です。それぞれが独立してスケールすることで、高いスケーラビリティが実現されています。

実は権限を考えるときにもそれらが分離されているということを念頭に置くと理解しやすいです。そのため、ここからはBigQueryの権限をストレージに関するものとコンピュートに関するものに分けて解説していきます。

コンピュートとストレージの分離

cloud.google.com

Dremel: A Decade of Interactive SQL Analysis at Web Scale

ストレージに関する権限

まずはストレージに関する権限です。ストレージに関する読み出し権限があると、ストレージからデータを読み出してコンピュート部分に送ることができます。注意するところは、読みだしたデータを処理して返すのがコンピュート部分という点です。ストレージの権限だけではコンピュート部分を操作できずエラーになります。ストレージの権限のみを持っている場合の典型的なエラーメッセージは以下のものです。

Access Denied: Project XXX: User does not have bigquery.jobs.create permission in project XXX.

さきほど例に挙げたBigQuery Data Viewerロール1はストレージに関する権限のみを持っているため、これ単独では権限不足のエラーになっていました。

ストレージに関する権限

コンピュートに関する権限

次がコンピュートに関する権限です。この権限があると、ストレージ部分から送られてきたデータを処理して、SELECT文の実行結果を作ることができます。前述したストレージに関する権限と同様に、この権限だけを持っていても権限不足のエラーになります。コンピュートの権限のみを持っている場合の典型的なエラーメッセージは以下のものです。

Access Denied: Table XXX: User does not have permission to query table XXX.

BigQuery Job Userロール2が代表的なコンピュートに関する権限です。

コンピュートに関する権限

課金との兼ね合い

ここからは少し話題を変えて、課金モデルについて説明します。一見すると権限と課金は無関係なように見えますが、この後に説明するマルチテナント構成を考える上で、課金モデルを知っていると理解がスムーズになるためここで説明します。

ストレージに関する課金

まずはストレージに関する課金です。ストレージは従量課金制で、1GB毎、1か月毎に0.020USDの費用がかかります3。この費用はそのデータを保持しているプロジェクトが支払います4

cloud.google.com

コンピュートに関する課金

次にコンピュートに関する課金です。こちらも従量課金制で、1TBのデータをスキャンする毎に5USDの費用がかかります5。この費用はコンピュートリソースを保有しているプロジェクトが支払います。

文章だけですと、分かりづらいかもしれないので、具体例を出して説明します。

課金

ここでは、プロジェクトAが保有しているデータに対してSELECTすることを考えます。クエリを実行するユーザーは、プロジェクトAのストレージの権限と、複数プロジェクト(A, B)のコンピュートに関する権限を保持しているとします。この時、プロジェクトA側のコンピュートリソースでクエリを実行した場合(図中1の経路)は、プロジェクトAが費用を負担します。同様に、図中2の経路でクエリを実行した場合は、プロジェクトBが費用を負担します。

なお、複数のプロジェクトのコンピュートに関する権限を保持している場合は、どちらのコンピュートリソースを利用するかを選択できます。bqコマンドで実行する場合は --project_id オプションで指定できます。Webコンソールからの実行の場合は、画面上部の青いバーでプロジェクトを指定できます。

webコンソールからプロジェクトを指定

先ほど、BigQuery Job Userロールが代表的なコンピュートに関する権限と説明しましたが、正確には言葉足らずな表現です。正しくは、その権限に加えて、コンピュート部分で発生した費用をそのプロジェクトに対して請求する権限を持ったロールです。この事が、以降の事例にて重要になります。

事例紹介

ここからは、BigQuery利用の拡大に伴う権限管理について、具体的な例を使って紹介します。

使い始め:シンプルに1プロジェクトを管理する

まずは、一番シンプルに、プロジェクトが1つだけパターンです。BigQueryを使い始めた時点では、この構成になっていることが多いかと思います。この場合はBigQuery Data ViewerとBigQuery Job Userの両方のロールが必要です。

単一プロジェクト

規模拡大:複数部署のBQ利用を管理会計する

次に紹介するのはプロジェクトが複数あるパターンです。BigQueryの利用者が多くなり、複数部署がBigQueryを使用するようになりました。この時、組織によっては部署毎のBigQuery利用費を分離して管理したいかもしれません。このパターンでは権限付与の方法がやや難しいため、注意が必要です。利用者には、「データを保持しているプロジェクトすべて」のBigQuery Data Viewerロールと、「クエリを実行するプロジェクト」のBigQuery Job Userロールの両方を付与します。

複数プロジェクト

なお、図には載せませんでしたが、実際のケースでは部署横断的なプロジェクトも分離すると管理がしやすくなります。例えば、ETL用のプロジェクトや専用線・VPNなどのネットワークリソースをホスティングするプロジェクトなどがこれに該当します。

外部連携:社外へデータ提供する

BigQueryの利用が更に進むと、社外に対してデータを提供することがあるかもしれません。社外に対するデータ提供も上記の複数部署パターンとほぼ同じです。重要なのは、自社管理のプロジェクトに対するBigQuery Data Viewerロールのみを付与し、BigQuery Job User権限は付与しないという部分です。

社外へのデータ共有

社外のユーザーに対して、自社管理のプロジェクトに対するBigQuery Job Userロールを付与しないのは、いわゆる「タダ乗り」を防止するためです。仮にBigQuery Job Userロールを付与してしまうと、以下の図に示すように、社外ユーザーの保持しているデータを自分たちのコンピュートリソースで処理できてしまいます。この場合のコンピュートに関する費用は自社側に請求されるため、「タダ乗り」となります。

社外へのデータ共有(ミス)

厳格化:特定のデータセットのみの閲覧権限をつける

最後はアクセス権限の厳格化です。今まではプロジェクトレベルの権限を考えていましたが、BigQuery Data Viewerロールはリソースレベルでも付与できます。その場合も今までと同様に考えれば問題ありません。「閲覧をしたいデータセットのみ」にBigQuery Data Viewerロールを付与し、「プロジェクト全体」のBigQuery Job Userロールを付与すればクエリを実行できます。

データセット単位の権限付与

まとめ

BigQueryの権限について、ストレージとコンピュートの分離という観点から解説しました。一見すると不思議に見える権限セットも内部アーキテクチャから理解することで体系的に理解しやすくなります。

ZOZOテクノロジーズでは、一緒にサービスを作り上げてくれる仲間を募集中です。ご興味のある方は、以下のリンクからご応募ください!

tech.zozo.com


  1. より具体的にはbigquery.tables.getDataパーミッション

  2. より具体席にはbigquery.jobs.createパーミッション

  3. 90日間変更されていないデータはLongTerm Storageという区分に自動的に変更され、料金が半額の0.010USDになります。

  4. より正確にはそのプロジェクトに紐付いている請求アカウントが支払います。

  5. Reservation機能を使えば定額にもできます。

カテゴリー