DataflowからBigQueryへのストリーミングを、BigQueryサブスクリプションに置き換える
大量のログデータをBigQueryに書き込むシステムでは、BigQueryサブスクリプションが有効だと考えています
BigQueryサブスクリプションがオススメな理由
公式のガイドでは4つの利点が紹介されています
- シンプルな導入
- 低コスト
- 最小限のモニタリング
- 柔軟性
この内重要なのは「低コスト」です
Dataflow ジョブを含む同様の Pub/Sub パイプラインの追加コストとレイテンシを削減します
pullサブスクリプションやpushサブスクリプションと比べるとPub/Subのスループット費用は高いのですが、代わりにDataflowを省略できることで総じてコストが低くなるようです
具体的な試算例
決定が必要なBigQueryサブスクリプションのプロパティ
決定する必要があるのは、スキーマの指定方法です
- テーブルスキーマ:トピックではスキーマの確認を行わず、BigQueryスキーマに従って書き込みます
- トピックスキーマ:Pub/Subスキーマを作成・トピックで利用するPub/Subスキーマを指定することで、トピックがメッセージとスキーマの整合性をチェックします。その後BigQueryスキーマに従い書き込みます
- data列のみを使用:どちらも選ばないとBigQueryのdata列にデータを書き込みます
これらから選定する基準として、料金と管理コストが軸になると言えそうです
料金:トピックスキーマ
トピックスキーマでのみ、メッセージをAvroのバイナリ形式もしくはProtocol Buffer形式でpublishすることができます
他テーブルスキーマはJSONのみです
管理コスト:テーブルスキーマ
トピックスキーマでは余分にPub/Subスキーマを作成/管理する手間が増えてしまいます
具体的な使い方
サービスアカウントへの権限付与
BigQuery サブスクリプションを作成するには、Pub/Sub サービス アカウントに、特定の BigQuery テーブルへの書き込みとテーブル メタデータの読み取りを行う権限が必要です。
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