Atsushi2022の日記

データエンジニアリングに関連する記事を投稿してます

読書メモ〜Google Cloudではじめるデータエンジニアリング入門

概要

Google Cloudではじめるデータエンジニアリング入門」を読んだので、忘備としてメモしておく。
8章~11章のBigQueryへのデータ集約、BI、リアルタイム分析、発展的な分析はスキップする。
メモの順番は章立てと一致してない。なるべくサービス毎にメモを記述した。

BigQuery

BigQueryの内部構造

コンピュート、ストレージ、さらにメモリがそれぞれ独立してスケーリングできる。

コンポーネント

  • マスタ/スケジューラ
  • ワーカ:コンテナで動作する分散コンピュート環境。クエリが終了すると瞬時に破棄
  • ネットワーク:Jupiterと呼ばれる独自のデータセンター内部NW。1.3Gpbsの帯域
  • 分散ストレージ:複数のゾーンにまたがる。Capacitorファイルというカラム志向のファイルフォーマットにデータを圧縮して格納。複数のCapacitorファイルを束ねて、テーブルとして表示
  • 分散インメモリシャッフル:分散処理ではシャッフルと呼ばれるワーカ間のデータ移動処理が発生。オーバヘッドがでかい。分散インメモリシャッフルをワーカではなく、分散インメモリ上で行うことで効率化。

BigQueryサンドボックス

Google Cloudの無料枠とは別。クレカ登録不要。

クエリの応用機能

以下の応用機能がある。

  • クエリの保存と共有ができる。
  • クエリのスケジューリングができる。
  • ユーザ定義関数が利用できる(SQLまたはJavaScriptで定義し、SQLから利用可能)
  • ストアドプロシージャが利用できる(UDFとは異なり、独立したステートメントとして実行される)
  • クエリプランの可視化により、パフォーマンスチューニングができる(詳細は公式ドキュメントを確認のこと。BQ Visualizeといったツールもある)

クエリの最適化

クエリ最適化のポイントは以下の通り。

  • SELECT等で、必要なカラムのみ選択する
  • パーティション分割/クラスタ化(詳細は後述)
  • クエリのキャッシュ:24時間保管され、同じクエリが実行されるとキャッシュが返される(スキャン料金の対象にはならない)。キャッシュ自体もテーブルとしてアクセスできる。CREATE TEMP TABLE…により、明示的にキャッシュ(一時テーブル)を作成可能

BigQueryにおけるパーティション分割

パーティションを設定しないとカラムをフルスキャンしてしまう。パーティションにより効率的なスキャンができる。
さらにパーティション毎にデータの有効期限を設定可能。一定期間が過ぎたパーティションを自動的に削除することができる。

パーティションの分割方法

  • カラムの値によるパーティション分割。ただし、時間(年、月、日付、時間)整数値のみパーティション分割に利用可能
  • データの取り込み時間による分割(あまり使われない)

BigQueryにおけるクラスタ

パーティションの場合1つのカラムしか指定できないが、クラスタ化では複数のカラムを指定して分割できる。 例えば、日付と製品IDの両方で1つのグループとすることができる。これにより、さらにスキャン量を減らし、高速に結果を返すことができる。
ただし、BigQuery上でのスキャン量はパーティション分割と同じように見えてしまう(実際はパーティション分割より、スキャン量が小さい)

BigQueryのコストコトロール

以下の方法でコストをコントロールできる。

  • BigQueryカスタムコスト管理
    • プロジェクト、あるいはユーザ単位で1日あたりの最大値を設定
  • Cloud Billingの予算・予算アラート

BigQuery Reservationsによるパフォーマンス担保

  • BigQuery Reservationsでは、スキャン量による従量課金ではなく、占有するコンピュートリソースに対して課金することができる。
  • ワーカ上のコンピュートユニットをスロットと呼ぶ。BigQuery Reservationsでは、コミットメントという単位でスロットを購入する。秒、月、年という単位で購入できる。契約期間が長いほど、割引率は高い。
  • クエリプランで1秒間で4,000スロットを処理したいとなっても、2,000スロット/秒しか利用可能なリソースがない場合には、2秒かけて処理することになる。
  • 並列で複数のクエリが実行された場合には、フェアスケジューリングによって、クエリ間でスロットを均等に割り当てることで同時に処理する。これにより、クエリが長時間待機状態になることを防ぐ。
  • 予約は、スロットを名前を付けてまとめておく概念。予約しておくことで他で勝手に使われないようスロットを確保しておくことができる。
  • 割り当てプロジェクトは予約に紐づくプロジェクトのこと。割り当てプロジェクト内でフェアスケジューリングが働く。
  • 予約により、使われていないスロット(=アイドルスロット)がある場合、他の予約のスロットとして一時的に貸し出される(デフォルト動作)。アイドルスロットを貸し出したくない場合には、ignore_idle_slotsというオプションをtrueにする。

BigQuery Reservationsでのコストコトロール

以下の方法でコストをコントロールできる。

  • BigQuery Slot Recommenderを利用して、最適なスロット数を調べる。
  • BigQuery Slot Autoscalingで、予約したスロットを使い切った場合にスケーリングするよう設定する。これにより、スロットの事前購入量を必要最小限にしておくことができる。
  • 「プロジェクトあたり同時実行クエリ数」を設定する。

マテリアライズドビュー

自動で更新されるビューのこと。デフォルトでは30分間隔で更新される。行の挿入は5分程度で反映される。
ただのビューとは違い、パフォーマンスの向上が見込める、らしい(仕組みはよくわからなかった。。。)

BigQueryの可用性

BigQueryの可用性SLA99.99%。ストレージは、ゾーンをまたいでレプリケーションされているので、ゾーン障害でも大丈夫。

BigQueryのメンテナンス

BigQueryではメンテナンスによるダウンタイムは発生しない。ローリングアップデートしているため。
パブリッククラウドのDBマネージドサービスでは、一般的にSLAからメンテナンスウィンドウは除かれるらしい)

Disaster Recovery

やり方としては以下の2通りがある。

  • BigQueryをコピー
    • DRサイトにBigQueryを作成しておき、BigQuery Data Transferサービスにより、最短12時間毎にデータを定期コピーする。
  • Cloud Storageに保管しておき、災害時にBigQueryにロード
    • ローカルサイトにCloud Storage(GCS)を作成し、BigQueryからエクスポートする。
    • Cloud Storage Transferサービスにより、DRサイトのGCSに転送する。転送後ローカルサイトのGCSデータを削除する。
    • 災害時にDRサイトのGCSからBigQueryにロードする。

BigQueryのバックアップ/リストア

タイムトラベル機能により、最大7日間まで任意のタイムスタンプの時間帯の状態に戻せる。
SELECT * FROM FOR SYSTEM TIME AS OF
タイムトラベル分のストレージコストは課金されない。
タイムトラベルを利用して、別テーブルに保管することでバックアップがとれる。

BigQueryにおけるトランザクションの仕組み

DML処理は全て成功する、またはコミットされずに全ての変更が戻されるのどちらか。
DMLの結果をテーブルにコミットする前に、変更が現在のテーブルに競合しないか確認する。競合があった場合にはDMLの実行を3回までリトライする。
DML処理の対象パーティションが異なる場合には、DML処理は競合しない。
同時に同じパーティションに対してDML処理が発行された場合、最初に完了したDML処理のみコミット(適用)される。
DML処理をなるべき大きなジョブとしてまとめることで、トランザクションが失敗して再実行が必要となるケースを減らすことができる。
裏では、DML処理毎に小さなテーブルファイルが生成されており、それらを統合して1つのテーブルとして見せている。

BigQueryにおけるオーバヘッド

UPDATE、DELETE、MERGEといった変更DMLには無視できないオーバヘッド有り
一方、INSERTのオーバヘッドは大きくない

BigQueryのアクセス制御

IAMを利用してプロジェクト、データセット、テーブル単位でアクセス制御ができる。
さらにData Catalogのポリシータグを作成し、カラムに対してポリシータグを付与した上で、プロジェクト毎に「きめ細かい読み取り」ロールをユーザーに付与することで、カラムへのアクセス権を付与できる。組織オーナー、プロジェクトオーナーであっても、このロールなしではカラムのデータを読み取ることはできない。
承認済みビューを試用すると、ビューが参照するテーブルへのアクセス権限を付与することなく、クエリの実行結果のみを共有できる。

INFORMATION_SCHEMAを活用した監査

INFORMATION_SCHEMAは、データセットやテーブルのメタデータを参照できるビュー。
INFORMATION_SCHEMAで、「いつ、誰が、どのようなクエリを実行したか」というデータアクセス履歴が取得できる。

  • INFORMATION_SCHEMA.JOBS_BY_USER:現在のユーザが送信したジョブ
  • INFORMATION_SCHEMA.JOBS_BY_PROJEECT:現在のプロジェクトで送信されたジョブ
  • INFORMATION_SCHEMA.JOBS_BY_FOLDER:プロジェクトの親フォルダで送信されたジョブ
  • INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION:プロジェクトに関連付けられた組織で送信されたジョブ

Dataproc

  • Dataprocとは、マネージドHadoop/Sparkサービスのこと。
  • ストレージとコンピュートが分離されている。
  • 高速な起動(90秒以内)ができる。
  • ストレージ分離、高速起動という特徴を生かしてエフェメラクラスタとして利用できる。ジョブ実行時にクラスタを起動し、ジョブが完了したらクラスタを破棄する
  • Hadoop/SparkクラスタVMは自動スケーリングを設定できる。

Dataproc Hub

Dataprocクラスタを起動し、JubyterLab環境を提供する。

Data Catalog

テクニカルメタデータ、ビジネスメタデータの管理を提供するマネージドサービス。
テクニカルメタデータは自動的に連携される。一方、ビジネスメタデータはユーザがタグ付けを行って管理する。

Dataflow

Apache Beamを利用した、フルマネージドでサーバレスな分散データ処理基盤。
PythonでETL処理を記述する。
ジョブグラフ(ジョブの流れ)をCloud Console上で確認できる。
最適かつ利用可能なゾーンを自動で選択する。
データ処理量に応じて自動でスケール(オートスケールさせずに、ワーカ数を指定した方がより早く処理が完了するケースもある)
バッチ、ストリーミング両方とも処理できる。

補足)Apache Beamについて

データ処理に特化した統一プログラミングモデル。
バッチとストリーミングを同じ書き方で記述できる。
Apache Beamは、Dataflow以外にもApache SparkやApache Flinkといった分散処理基盤上で実行可能。
JavaPython、Goなどのプログラミング言語で記述できる。
Built-in I/Oと呼ばれる、様々なデータソースとのコネクタが提供されている。

Cloud Composer

Apache Airflowを利用した、フルマネージドのワークフロー管理サービス。
Cloud Composer環境は、Kubernetes Engineクラスタ、Cloud Storageバケット、Cloud Logging、Cloud Monitoringで構成される(バックグラウンドではCloud SQLも利用されている)
Airflowウェブサーバやデータベースのマシンタイプを選択できる。
Pythonでワークフローを定義する。
PythonファイルをCloud Storageにアップロードすることで、自動的にワークフローがデプロイされる。
AirflowのWeb UIで作成されたワークフローを見ることができる。
ベストプラクティスとして、変換処理はワーカ側(BigQueryなど)にやらせて、なるべくDAGはシンプルに保つことが推奨される。

  • DAG:一連のタスクを有効非巡回グラフとしてまとめたもの
  • タスク:DAGにおけるひとつひとつの処理。個々のタスクにはオペレータを利用して処理内容を記述する
  • オペレータ:Bashコマンドを実行するBashOperatorやPythonコードを実行するPythonOperatorなど。幅広いオペレータが提供されている

Cloud Composerにおけるアクセス制御

環境オプションで、ウェブサーバにアクセスできるIP範囲を指定できる。プライベートIPのみを指定することも可。

DAGで利用する接続情報の管理

DBやAPIの接続情報は、AirflowのAdminメニューでConnectionsとして保存することができる。しかし、Web UI上にアクセス可能なユーザ全員が接続情報を閲覧・編集できるのはよろしくない。Secret Managerに接続情報を保存することで、より安全に管理できる。

Cloud Data Fusion

CaskData社のCDAPと呼ばれるOSSのデータパイプライン構築サービスを利用した、フルマネージドなデータ統合サービス。
ノーコードでETLパイプラインを構築できる。
データ読み取りや変換といった個々のタスクをノードとして定義し、ノード間をつないでパイプラインを表現する。
ノードの定義にはプラグインを用いる。クラウドサービス、DB、ストレージ等と連携するための多様なプラグインが用意されている。
パイプラインの実行環境として、Dataprocを利用してエフェメラクラスタが作成される。
データリネージを管理できる。

Data Fusionの利用手順

  • まずインスタンスを作成する。
  • GUI上で、パイプラインを作成する。
  • パイプラインを実行する。

Cloud ComposerとCloud Data Fusionの比較

Cloud Composerはワークフロー制御が主眼。個々のETLジョブはBigQueryやDataflowを利用する。
一方、Cloud Data Fusionはデータ統合に軸足がある。作成した個々のパイプラインは独立しているので、複数のパイプラインでオーケストレーションが必要な場合には、Cloud Composerを利用する。

VPC Service Controlsによるアクセス制御

Cloud Storage、BigQueryなどのGoogle Cloudサービスに対して仮想的なセキュリティ境界を設定し、「特定のVPCネットワークや送信元IPアドレスからのアクセスのみ許可する」、「境界外の未承認リソースへのデータコピーを防ぐ」といったコンテキストベースのアクセス制御ができる。
サービス境界内では自由に通信できるが、境界を超える通信はデフォルトでブロックされる。
例えば、BigQueryにIP制限をかけたかったら、VPC Service Controlsを使えばよい。
対応サービスはこちらを参照のこと。
https://cloud.google.com/vpc-service-controls/docs/supported-products?hl=ja

Cloud Loggingでの監査

以下の3種類のログを保管、検索、管理するサービス。

  • 管理アクティビティログ
  • システムイベントログ
  • データアクセスログ


管理アクティビティログには、IAM権限変更や、VMインスタンス作成などが含まれる。デフォルトで有効で無効化できない。

システムイベントログは、Google Cloudによるシステムイベントのログ。利用者の操作に関係なくシステム上のイベントが記録される。デフォルト有効で、無効にできない。

データアクセスログは、BigQueryやCloud Storageなどのデータを含むリソースへのアクセスログのこと。BigQueryはデフォルトで有効だが、他サービスはは無効。読み取りアクセスは量が多いので注意が必要。「IAMと管理」→「監査ログ」で有効/無効にできる。

Cloud Loggingの集約シンク

組織、あるいはフォルダにシンクを作成し、その配下のリソース全てのログをエクスポートする機能。もれなくログを収集できる。

Cloud Asset Inventoryでの監査

Google Cloud上のすべてのリソースの状態、つまり「いつの時点で、どんなリソースが、どのような設定であったのか」を、アセットとして検索、エクスポートできる。

なぜデータレイクが考案されたか

将来的に発生し得る未知の質問に答えるため。データマートでは事前に定められた質問にしか答えることができない。