DataflowからBigQueryへのストリーミングを、BigQueryサブスクリプションに置き換える

2024/03/30に公開

大量のログデータをBigQueryに書き込むシステムでは、BigQueryサブスクリプションが有効だと考えています

BigQueryサブスクリプションがオススメな理由

公式のガイドでは4つの利点が紹介されています

  • シンプルな導入
  • 低コスト
  • 最小限のモニタリング
  • 柔軟性

この内重要なのは「低コスト」です

Dataflow ジョブを含む同様の Pub/Sub パイプラインの追加コストとレイテンシを削減します

pullサブスクリプションやpushサブスクリプションと比べるとPub/Subのスループット費用は高いのですが、代わりにDataflowを省略できることで総じてコストが低くなるようです

https://cloud.google.com/pubsub/pricing?hl=ja

具体的な試算例

https://qiita.com/kccs_kai-morita/items/4b5927ad393b9eb7de76#料金比較例

決定が必要なBigQueryサブスクリプションのプロパティ

決定する必要があるのは、スキーマの指定方法です

  • テーブルスキーマ:トピックではスキーマの確認を行わず、BigQueryスキーマに従って書き込みます
  • トピックスキーマ:Pub/Subスキーマを作成・トピックで利用するPub/Subスキーマを指定することで、トピックがメッセージとスキーマの整合性をチェックします。その後BigQueryスキーマに従い書き込みます
  • data列のみを使用:どちらも選ばないとBigQueryのdata列にデータを書き込みます

これらから選定する基準として、料金管理コストが軸になると言えそうです

料金トピックスキーマ

トピックスキーマでのみ、メッセージをAvroのバイナリ形式もしくはProtocol Buffer形式でpublishすることができます

他テーブルスキーマはJSONのみです

管理コストテーブルスキーマ

トピックスキーマでは余分にPub/Subスキーマを作成/管理する手間が増えてしまいます

具体的な使い方

サービスアカウントへの権限付与

BigQuery サブスクリプションを作成するには、Pub/Sub サービス アカウントに、特定の BigQuery テーブルへの書き込みとテーブル メタデータの読み取りを行う権限が必要です。

https://cloud.google.com/pubsub/docs/bigquery?hl=ja#service_account_permissions

Pub/Subスキーマにはリビジョンが存在する

publishしたメッセージにはAvroまたはProtocol Bufferのスキーマ情報が含まれるので、publish後トピックで一致するリビジョンが選択され、BigQueryに書き込みます

一致するスキーマのリビジョンが存在しないとpublishの段階でエラーになります

terraformでPub/Subスキーマを管理している場合、definitionフィールドを書き換えてapplyすることでPub/Subスキーマのリビジョンが追加されます

Pub/SubスキーマとBigQueryスキーマの差分はオプショナル/NULLABLEでないと、書き込みが失敗する

サブスクリプションで「不要な項目を削除する」オプションを有効にする

Goのpubsubクライアントではテーブルスキーマを用いたサブスクリプションを作成できない

テーブルスキーマは最近提供された機能ですので、そのうち出来るようになると思われます

他の言語は未調査です

注意事項

PARTITIONTIMEが即時に反映されない

BigQueryテーブルで取り込み時間パーティショニングを利用している場合、BigQueryサブスクリプション経由の書き込みでは_PARTITIONTIME疑似列に即時に値が入らずNULLになります

確認した限りでは、書き込みの約1時間後にNULLから取り込み時間に更新されます

Discussion