ログデータを GCP の Dataflow SQL 経由で BigQuery に保存する
はじめに
こんにちは、 Zaim でサーバーサイドを担当している naoki85 です。
アプリケーションのログなどを BigQuery に保存してサービスに役立てたい、という方も多いのではないでしょうか。
Zaim でも BigQuery にデータを保存して、サービス分析や監視に使用しています。
最近、新しいプロジェクトにて、アプリケーションのログデータを BigQuery に保存する実装を担当することになりました。
Zaim の従来の実装だと、AWS のサービスを経由させて BigQuery にインポートしていました。
今回は要件の制約が少なかったため、GCP のサービスを使って BigQuery に保存することを試しました。
幸いなことに、「まさにこれ」といったチュートリアルが GCP にございます。
本記事では、このチュートリアルをなぞりつつ、私が詰まった点も追記していこうと思います。
なお、サンプルソースについては、 Pub/Sub へのパブリッシュができればいいだけなので割愛します。
作業者に権限を追加する
チュートリアルではオーナー権限を使用していますが、そこまで権限がなくても大丈夫だろうとたかを括っていました。
チュートリアルをぱっと見た限り、以下の権限が必要だということは想像できました。
ただ、これだけだと途中でパーミッションエラーになります。
他にも、
が必要なようです。
また、チュートリアルで指示のある API を有効にしておく必要があります。
特に Data Catalog は当初、何に使っているかよく分からなかったのですが、Pub/Sub の型を定義したメタデータを保存するために使用しているようです。
Pub/Sub にトピックを作成しスキーマを割り当てる
Zaim では権限管理に Deployment Manager を使っているので、毎回、権限の追加を申請するのが申し訳なかったです……。
gcloud pubsub topics create transactions
その後、トピックに対し、スキーマを割り当てます。
こちらはアプリケーションからパブリッシュするデータ型です。
最終的には Dataflow SQL で BigQuery にインサートするので、 Dataflow の型を参考にしながら設定すると良いかと思います。
なお、 Pub/Sub から取り込む場合、アプリケーションから送信したアイテムに event_timestamp カラムが追加されるようです。
なので、 BigQuery でテーブルを作る際には event_timestamp のカラムも作っておくと楽だと思います。
BigQuery にテーブルを作成する
チュートリアルでは、 Dataflow SQL を設定すると自動的に対応するテーブルが作成されるようになっています。
(準備の段階で作成するのは、マスターデータのセットのようです。)
ただ、 Dataflow SQL 経由でテーブルを作ると、パーティションが設定できないようです。
パーティションを設定する場合は、あらかじめパーティションつきでテーブルを作成しておくと良いです。
この時、 Pub/Sub に割り当てたスキーマのカラム名やスキーマと一致するようにします。
後述する、 Dataflow SQL の設定時に、テーブルを指定し、「追加する」を選べば、作成されたテーブルに追加してくれます。
Dataflow ジョブを作成する
Dataflow SQL のコンソールからジョブを作成していきます。
Pub/Sub のスキーマと BigQuery のテーブルのカラム定義が一致していれば、 SQL は以下のようなものでいいかと思います。
SELECT tr.* FROM pubsub.topic.`project-id`.transactions as tr
この設定時ですが、どうやらジョブを実行する worker には、 Dataflow サービスエージェントの権限を付与しておく必要がありそうです。
(デフォルトで Compute Engine 用のサービスアカウントが割り振られる)
デフォルトの Compute Engine にサービスエージェントの権限を付与しても問題ないと思いますが、今回は新しくサービスアカウントを作成しました。
そのサービスアカウントには編集者権限と Dataflow サービスエージェント権限を付与しました。
作成したサービスアカウントはオプションパラメータで設定できます。
適切に設定されていれば、 Dataflow のジョブが起動するはずです。
試しにアプリケーションから Pub/Sub にパブリッシュしてみて、 BigQuery のテーブルに追加されているか確認してみてください。
さいごに
主に権限周りで詰まりましたが、それ以外では特に問題なく構築できました。
アプリケーションからも Pub/Sub に送信する処理だけ追加すればいいので、容易に構築できるのではないでしょうか。
同じようなことを実施される方の参考になれば幸いです。
Zaim では、このように新しい仕組みを導入してより良い環境を作ってくれる方を募集しております。