🐌
BigQueryで大きいファイルをインポートするときの課題
目的
BigQueryで大きいファイルをGCSに転送してからインポートする。
課題
- 大きいファイルをGCSに転送すること自体に時間がかかる。
- 分割して転送する方法では上りの帯域がボトルネックになる。
- 対策としてGCSに転送する際にgz圧縮して転送することで時間を短縮できる。
- BigQueryはGCSからgz圧縮したファイルを取り込むことができるがサイズに制限がある。
- そのため事実上大きいファイルについては圧縮した状態では取り込めない。
- また圧縮した状態でファイルを取り込む際には分割して並列化実行できないので時間がかかる。
解決方法
- GCSにアップロードする際にはgsutilのオプションでgz圧縮して状態でアップロードするようにする。
- クラウド側でgzファイルを解凍し、元ファイルをGCSに配置する。
- ただしGCSではgzipコマンドを直接実行できないので、GCEを用意して解凍コマンドを実行する。
- その後に解凍したファイルをBigQueryにインサートする。
補足
GCEではなくCloud Shellを使うこともできます。
しかし結構大きなファイルだとCPU時間を使うので、すぐに制限に到達します。
そのため、必要なときだけGCEインスタンスを起動し終わったら停止するという運用としています。
アップロード時のコマンド
gsutil cp -Z input.tsv gs://バケット名//UPLOAD/input.tsv.gz
- ローカル側で実行
- -Zオプションで転送時に圧縮される
- 元ファイルのinput.tsvは非圧縮状態
- アップロードされた
gs://バケット名//UPLOAD/input.tsv.gz
は圧縮状態
GCEでGCSの圧縮ファイルを展開するコマンド
gsutil cp gs://バケット名//UPLOAD/input.tsv.gz - | gzip -d | gsutil cp - gs://バケット名//UPLOAD/input.tsv
- GCEインスタンスを稼働させてVM上で実行する。
- 実際はSSHで実施している。
- GCE自体の稼働停止も自動で実施している。
- BQへのインポートには
gs://バケット名//UPLOAD/input.tsv
を指定する。 - GCEのインスタンスから、gsutilでGCSへのアクセスのためのサービスアカウントの設定は事前に実施しておくこと。
Discussion