前回の続き
前回の記事では、本構成の全体像と、AivenまたはClickHouseのDBaaSを使った基本的なClickHouseサービスの立ち上げ方を取り上げました。今回は、データをClickHouseに取り込み、BigQueryとの間でレプリケーションを構成する手順に進みます。
GitHubリポジトリ
本記事では、Cloud FunctionとBigQueryジョブを取り上げます。これら2つのソースコードは、こちらのGitHubリポジトリに置いています。
なお、このコードは学習用途を想定してあえて非常にシンプルに作っています。そのため、実環境で利用する場合はカスタマイズがほぼ必須になる点をご承知おきください。
BigQueryからClickHouseへデータを取り出す
現時点では、BigQueryから任意の宛先へCDCやストリーミングでデータを自動的に出力する手段はありません。つまり、BigQueryに挿入する前にデータを取得しておくか、挿入後に抽出するかのいずれかが必要です。公式の方法が存在しないため、このテーマは非常に奥深いものになります。そこで本記事では、バッチロードに絞って解説します。
レプリケーションの話は次のセクションで扱いますが、その前にまずは初期データセットをBigQueryからClickHouseへ取り出し、ベースラインを作る必要があります。
BigQueryには、データを外部に取り出す最も手軽な手段としてエクスポート機能があります。ただし大きな欠点が2つあり、一度にエクスポートできるのは1テーブルだけ、かつ保存先がGCSに限られます。
1テーブルずつしか扱えないという制約があるからこそ、すべてのテーブルをClickHouseへレプリケーションする必要があるのか、あるいはLookerで使うためにレプリケーションすべき候補はどれか、を見極める良い機会になります。
すべてのテーブルを一覧化する手早い方法として、対象データセットに対して以下のクエリを実行すれば、全テーブルがリスト化されます。さらに、よく使われているテーブルが分からない場合は、こちらのクエリでデータセット内の各テーブルにヒットしたクエリ件数を確認できます。なお、このクエリは相応のコストがかかる可能性があるため、まずUIで料金見積りを確認し、スキャン対象日数を調整してから実行してください。
実際にエクスポートを行う際は、bq CLIコマンドでテーブル全体を取得するのが最善です。理由は、「EXPORT DATA…」SQLコマンドを使うとエクスポートしたデータ量に応じた処理/スキャン料金、Editions利用時はスロット料金が発生するのに対し、CLIコマンドやAPI呼び出しなら追加料金なしでテーブル全体をダンプできるためです。
テーブルの一部、たとえば特定のパーティションだけが必要な場合は、bq cpコマンドでパーティションを新しいテーブルにコピーし、それをClickHouseに直接ロードする方法があります。残念ながらこのコマンドはワイルドカードや複数パーティションの一括指定に対応していないため、パーティションごとに実行する必要があります。スクリプト化は比較的容易ですが、ここでコマンド例を載せておきます:
bq cp –append_table=true `<source_project_id>:<source_dataset>.<source_table>$<source_partition_name>` `<target_project_id>.<target_dataset>.<target_table>`
パーティション分割されておらず(かつ巨大すぎない)テーブルであれば、テーブル全体をClickHouseに読み込んでから、SQLで不要分を削るのがおすすめです。これならBigQuery側で処理料金が発生しません。
初期エクスポートの準備が整ったら、次に進みましょう。
ここではparquet形式でデータをダンプします。BigQueryが内部で使うファイルシステムに最も近い形式であり、列の型を保ったままClickHouseへ容易にロードできるためです。
BigQueryからテーブルをエクスポートするコマンドは次のとおりです:
bq extract — destination_format=PARQUET \
<project_id>:<dataset>.<table_name> \
gs://<bucket_name>/<path_and_filename>
(ファイルをサブフォルダに格納する場合は、そのフォルダがバケット内に存在することを必ず確認してください。存在しないと、位置引数に関する非常に分かりにくいエラーメッセージが出ます)
テーブルをGCSにエクスポートできたら、いよいよClickHouseへのロードに進みます。
初期データをClickHouseにロードする
ClickHouseへロードする際、本記事執筆時点で公式に推奨されているSQLは以下のとおりです:
CREATE TABLE <table_name>
ENGINE = MergeTree
ORDER BY tuple() AS
SELECT *
FROM S3Cluster(default,
'https://storage.googleapis.com/<bucket_name>/<path>/*.parquet');
注意: 一部のClickHouseバージョンには、上記クエリが失敗するもののテーブルだけは作成されてしまうバグがあります。回避策として、INSERT INTO






