2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[DWH取り込み設計] BQパーティションとシャーディングを考える

Last updated at Posted at 2022-04-24

モチベーション & ターゲット

既に出尽くされているであろうGoogle BigQueryのテーブル設計について改めて考えてみます。
特にこれからBQを使おうという方や、データサイズがそれほど大きくなく特に検討する必要がなかった
(ただし、これから大きなデータ扱うかも)という方向けという感じです。あと自分の備忘録としてメモ的に書いています
(私見なので間違いもあります、ご指摘いただければ幸いです)

取り扱うアーキテクチャ

  • データを転送したい「元」はサービスやDB・ストレージなどを想定します(要は何でもOK)
  • 転送するためのサービスはembulkを使用するイメージ
  • 転送先はDWHを想定し、今回はGoogle BigQueryをチョイス
  • 特にそれぞれの何が良い/悪いみたいな話は割愛します
image.png

転送元で考えること

  • BigQueryに入れるので、基本的には構造化なデータが取得できるサービスやシステムを想定
  • ポイントとなるのは、転送元のデータ構造がどれほど変わるものなのかという点
    • 例えばSaaSサービスなどの場合は取得できるカラムが増えることが合っても、取得できるカラムが減るということは少ないかも
    • スプレッドシートみたいな表計算ツールになると、ガンガンデータ構造も変わるかも など
  • あとは地味に転送元側でも地味にSQLを書ける環境があるかどうかなどもポイント
    • 例えば、SalesForceであればSQLライクなSOQLが書けるなど、転送元がDBであればやはり楽かもしれない

embulkで考えること

  • データを取得する側のinputプラグインについては今回割愛
    (主にはBQ側のテーブル設計にフォーカスをあてたい)
  • BigQueryへのoutputプラグインはこちらを利用検討
  • GCS(Google Cloud storage)に一時ファイルを吐き出して、それをロードする形式
  • ポイントとなるのはデータの転送モード、一次テーブルを作って扱うかという挙動(下図参照)
    • REPLACE : データ置き換え
    • APPEND : データ積み上げ
image2.png

パーティションとシャーディング

  • 少し雑ですが、まとめたものは下図
  • 公式的にも迷ったらパーティションがおすすめという感じですが、公式Docが書くシャーディングおすすめの場合はこちら
image3.png

ちなみにBQコンソール上でのシャーディングの見え方はこんな感じです。個人的には結構好みです。
image4.png

上記から考えるユースケースと設計イメージ

転送元のデータ構造があまり変わらない場合 かつ 転送はAPPEND

  • ユースケースとして「アプリケーションのログ」などをイメージ
  • 基本的にはログファイルとしてストレージに吐き、日付(ログ日付 or 取り込み日付)でパーティションを設定するのがよさそう
    • ただしデータ量がそれなりに大きい場合は、取り込み日付(1ログファイル内で統一した値) でパーティション設定したほうが良い
    • 再度データの入れ直しが発生したときにリカバリが楽になる(DELETEが楽で速い)
  • シンプルに取り込み直しはクエリを用意する必要があるので、面倒(再取り込みにおける同じキーへのDELETE/INSERTの機構を用意する必要あり)
  • ストレージ側にログファイルがあるので、リストアもしやすそう
image4.png

転送元のデータ構造があまり変わらない場合 かつ 転送はREPLACE

  • ユースケースとして、「DBにおけるマスタ情報」を転送する際に該当
  • トランザクションが発生しないテーブルであり、データ量としても大きくないイメージ
  • こちらも上記同様パーティションを設定するのが良いが、用途的にはパーティションを必要としないケースも多いイメージ
  • 後続の処理に応じてパーティションの要否を検討するレベル
image5.png

転送元のデータ構造が変わる場合

  • このユースケースをさらに転送元のデータ量で分けるとしたら下記のようなイメージ
    • データ量が多い:SaaSサービスやSFA、CRMなど
    • データ量が少ない:スプシ(表計算ツール)やMAなど
  • 選べるアーキテクチャの選択肢としては
    • 転送モードは APPEND を選択して、パーティション を使う
    • 転送モードは REPLACE を選択して、シャーディング を使う

転送モード APPEND & パーティション

  • どちらかというと転送量のデータ量が大きい場合の用途をイメージ
  • 取り込み時にデータ構造の違いがある場合、エラーとなる(これが頻発すると調査が面倒)
  • 後続の参照用テーブルもパーティションキーを踏襲しやすいので、設計が楽になる
  • (シャーディングの場合と対比して)1テーブルに積み上げで情報を持っているので、速度や処理に不安が少ない
  • この取り込みテーブルが大きくなればなるほど、クエリのパーティションキー指定を忘れられないのでリテラシーを求める必要がある
image6.png

転送モード REPLACE & シャーディング

  • どちらかというと転送量のデータ量が少ない場合の用途をイメージ
  • 各テーブルに対して取り込みを行う形となるため、取り込み時にはエラーが起きない
    • とりあえずデータは取り込んで、起こり得るエラーはBQ上で全て確認するという思想もあり
  • エラーパターンとしては、後続の参照用テーブルで存在しないカラムを呼び出した場合などが該当
    • 現状使用しないカラムが追加された場合などはエラーにならないので、その点は良い
  • シャーディングに該当する複数テーブルをワイルドカードで呼び出すときの不安
    • 速度もあるが、データ構造が統一化されていないこともあり、想定したデータが取れているか不安もある
    • そのためシャーディングで取り込んだテーブルをパーテイション化したテーブルで積み上げる方法もあり得る
image7.png

まとめ

  • ユースケースからも見る通り、やはり基本的にはパーティションを使うのが良い
  • ただし、シャーディングにも使うメリットが十分あるため、使い分けをお勧めする
  • 特に以下の場合などシャーディングを検討してもいいじゃないかと思う
    • 転送サイズが小さいがたくさんの転送元サービスから情報を持って来る場合
    • 各取り込み処理が日付やキーで独立しており、後続で積み上げる必要がない場合
    • 構造違いでエラー起こった際にBQ上で切り分けをしたい場合
    • 基本転送元サービスのカラム削除はなく、カラム追加が多い場合、そして後続ELT処理の修正と同期がとりやすい場合(チーム的にも)

最期に宣伝

  • embulkのマネージサービスとして、troccoを提供しています
  • 上記アーキテクチャに対しても、もちろん対応しており、テーブル取り込み前後のDML処理やシャーディングの動的な日付パラメータ管理なども含めて可能です
  • まだ一部とはなりますが、カラム変更におけるスキーマ追従などにもスポットをあてておりますので、気になった方は是非覗いてみていただければと思います!
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?