📈

BigQueryテーブル構築と書き込み周りの調査メモ


TL;DR

  • Terraformを使用しての操作には制限があるため、必要に応じてコンソールから操作する
  • 書き込みリクエストの速度は、BigQuery直InsertでもPub/Subでも大差ない
  • Pub/Subへのリクエストに不要なフィールドを含めるとエラーになるので注意が必要

TerraformでBigQueryテーブルを構築した際のメモ

  • テーブルを編集しようとすると、一部の操作は編集でなく新規作成扱いになる
  • 新規作成になると、データが消えるので注意が必要
    • terraform planでリソースがupdateなら編集、replaceなら新規作成となる
  • Terraformだとdeletion_protectionによりデフォルトでテーブルの削除保護がかかっているので、データは消えずにterraform applyでエラーになる
  • データが消えてしまうテーブル編集を行う場合は、データを別の場所に退避しておく必要がある

Terraformを利用して編集可能なこと

  • カラムの追加
  • カラムのdescriptionの変更
  • クラスターの追加・削除

Terraformを利用するとテーブルが新規作成扱いになってしまうこと

  • モードの変更
  • 種類の変更
  • パーティションの操作
  • カラムの削除
    • ただし、TerraformでなくコンソールからALTER TABLEを実行した場合は問題なくカラム削除できた
    • その後、terraform refreshでstateの同期も可能

BigQuery書き込みをした際のメモ

  • BigQueryへの書き込みは、直接InsetするだけでなくPub/Subを経由する方法もある
    • BigQueryサブスクリプション
      • BigQuery Storage Write API によるバッチ処理
      • このサービスが使えるようになる前は、わざわざDataflowを構築・経由してBigQueryに書き込むのが一般的だった模様
  • 速度観点で比較してみたが、思ったより差がない
    • 速度はlocal->Pub/Subのほうが早いと思っていたが、差がなかった
      • ただし、大量書き込みの場合はPub/Sub経由の方がバッチ処理なのでスループットは上がると思われる
    • 閲覧できるまでの時間も、Pub/Sub経由してもラグを感じなかった
  • とはいえWeb視点でみると完全に無視できる時間でないため、場合によっては非同期処理として扱うなどの工夫をした方が良さそう

local -> Pub/Sub へのリクエスト

速度

  • 実行に0.2 - 0.6 s
  • インサートデータをコンソールで確認できるまでにラグは感じなかった
    • Pub/Sub -> BigQuery間は0.5s程で書き込みされるというブログもあったので、大したラグは発生しないと思われる

フィールドに過不足があった場合の挙動

  • BigQueryカラムはあるがリクエストJSONのフィールドに含めなかった場合、失敗せずにNULLとなる
  • 逆にBigQueryカラムにない名前をリクエストJSONのフィールドに含めるとエラーとなる
    • エラー内容はデッドレターキューのサブスクリプションを設定することで確認できる
      • xxx: Cannot find field.
  • つまり、カラム変更する場合は下記のような手順が必要
    • カラム追加時 -> BigQueryのカラムを変更してからアプリ側のリクエストJSONを変更する
    • カラム削除時 -> アプリ側のリクエストJSONを変更してからBigQueryのカラムを削除する

Insertしたデータはしばらく操作できない

  • Insert直後にレコードを削除しようとすると下記が発生した
UPDATE or DELETE statement over table xxx would affect rows in the streaming buffer, which is not supported

local -> BigQuery へのリクエスト

速度

  • 実行に0.2 - 0.6 s
  • Storage Write API でなくストリーミングAPIを利用して検証
  • 即座にコンソールからインサートデータが確認できた

検証した際のコード