BigQueryのストレージ費用は安く、GCSやS3に置くよりもBigQueryにおいたほうが安いということもしばしば発生します。
BigQueryの1ヶ月あたりのストレージの価格は 0.020 USD/GB
であり、さらに90日間変更をしていないテーブルでは自動的にこの半額の 0.010 USD/GB
になります。1
容量が大きくなりがちなログ系のテーブルを日付でパーティション設定することでこの恩恵を受けやすくなります。
S3の価格が標準ストレージで 0.023 USD/GB
、 低頻度アクセスでも 0.010 USD/GB
である2ことを考えると、S3に保存するよりもBigQueryに保存したほうが安いという現象が発生する理由も分かります。3
とはいえ、データの量が膨大になってくるとこのストレージの価格もバカになりません。
そのため、BigQueryのテーブルをより安価に保存する方法について紹介します。
GCS Archiveを使う
BigQueryの値段表だけ見ても、より安価なストレージはないのでGCSに目を向けます。
すると、いい感じに安いストレージが見つかりました。
Archive Storageの価格は 0.0012 USD/GB
4で、BigQueryの長期保存ストレージ価格と比較して88%OFFのお値段です。
その代わりに、データの取り出し時に 0.05 USD/GB
というけっこう高額な値段がかかるので、頻繁にアクセスされるデータの場合はかえって高くなってしまうことに注意が必要です。
このArchiveはS3 Glacier的な用途で使われることが多く課金体系もよく似ていますが、S3 Glacierとの違いは取り出し時間がかからないという点にあります。
そのため、BigQueryのテーブルをGCS Archiveに移したとしても、データの復帰のために数時間待つということは発生しません。
また、BigQueryはGCSのファイルを外部表として使うことができるので、実体がGCSにあるテーブルも透過的にクエリを実行できます。
手順
最初にBigQueryのデータを移すためのGCSバケットを作成します。
なお、外部表としてGCSを使うときにはBigQueryのリージョンとGCSのリージョンを揃える必要があるので、環境ごとに -l
オプションは変えてみてください。
また、BigQueryのデータセット単位で権限管理を行っている場合は、データセットごとにGCSバケットを作成するようにするとGCSでの権限管理上をしやすいです。
gsutil mb -c ARCHIVE -l US-CENTRAL1 gs://バケット名
そして、BigQueryのテーブルをこのバケットにエクスポートし、テーブルの削除を行います。
bq extract --destination_format AVRO データセット名.テーブル名 "gs://バケット名/テーブル名-*.avro"
bq rm -t データセット名.テーブル名
最後に、GCSにエクスポートしたテーブルをBigQueryの外部表として取り込みます。
bq mk --external_table_definition="AVRO=gs://バケット名/テーブル名-*.avro" データセット名.テーブル名
年間何回のアクセスならお得なのか
さてこの方法でGCS Archiveに移動させたデータはアクセス頻度が低ければ低いほうがお得になります。
年間何回程度のアクセスならばこの方法を使ったほうが安くなるのでしょうか?
BigQueryにデータを保存する場合、1ヶ月あたり 0.010 USD/GB
です。(長期保存ストレージ料金)
一方で、GCS Archiveは 0.0012 + データアクセス回数 * 0.05 USD/GB
です。
上記の2つの値が等しくなるデータアクセスは、月間で0.176回、すなわち年間で約2回です。
それ以上の頻度でアクセスを行うとかえって割高になってしまいます。
実際に運用する際には、ややバッファをもたせて年間アクセス頻度が1回以下の見込みであり、十分に巨大なテーブルに対してのみ適用しないとこの方法の旨味が少ないかと思います。
注意点
BigQueryの外部表は通常のテーブルと比べて制約を受ける点に注意が必要です。
特にワイルドカードクエリが使用できない点は運用に乗せたあとに発覚すると面倒なことになるので気をつける必要があります。
https://cloud.google.com/bigquery/external-data-sources#external_data_source_limitations