SpannerのデータをBigQueryに取り込む方法です。基本は以下の2つの内容を組み合わせます。
簡単に図にするとこんな感じです。
Dataflowジョブの登録
今回利用するのはGoogle製のテンプレートジョブです。ちゃんとSpannerからスキーマ情報等を引き抜いてAvroを作ってくれます。調整したい場合もこのコードを元に調整すると早そうです。
GCPの既製のテンプレートは gs://dataflow-templates/latest/
に保管されているので、これをDataflowで呼び出します。
SPANNER_INSTANCE="spanner-instance-name" SPANNER_DB="source_db_name" JOB_NAME="export_spanner_${SPANNER_INSTANCE}_${SPANNER_DB}_$(date +%Y%m%d_%H%M%S)" TEMPLATE_LOCATION="gs://dataflow-templates/latest/Cloud_Spanner_to_GCS_Avro" OUTPUT_LOCATION="gs://otomo-spanner-exp/avro" STAGING_LOCATION="gs://otomo-spanner-exp/temp" REGION="asia-northeast1" gcloud dataflow jobs run ${JOB_NAME} \ --gcs-location=${TEMPLATE_LOCATION} \ --region=${REGION} \ --staging-location=${STAGING_LOCATION} \ --parameters=instanceId=${SPANNER_INSTANCE},databaseId=${SPANNER_DB},outputDir=${OUTPUT_LOCATION}
実行すると、ジョブの情報が表示されます。
createTime: '2020-01-29T00:26:17.983241Z' currentStateTime: '1970-01-01T00:00:00Z' id: 2020-01-28_16_26_15-11984201559070487438 location: asia-northeast1 name: export_spanner_xxxx_xxxxx_20200129_092614 projectId: your_project startTime: '2020-01-29T00:26:17.983241Z' type: JOB_TYPE_BATCH
この出力の id
部分が揃うと、出力先のディレクトリが特定できます。
JOB_ID=2020-01-28_16_26_15-11984201559070487438 AVRO_DIR="${OUTPUT_LOCATION}/${SPANNER_INSTANCE}-${SPANNER_DB}-${JOB_ID}"
Dataflowの画面でもジョブが実行されているのが見られます。
ジョブが完了すると、指定したバケットにAvro形式のデータが吐かれます。
このディレクトリの下に、例えばDatabaseに入っているのが、SingersとUsersのテーブルの場合は以下のようにAvro形式のデータと、JSON形式のManufestファイルがExportされます。
Singers-manifest.json Singers.avro-00000-of-00002 Singers.avro-00001-of-00002 Users-manifest.json Users.avro-00000-of-00003 Users.avro-00001-of-00003 Users.avro-00002-of-00003 spanner-export.json
bqコマンドでAvroをロード
GCS上にあるAvroをBigQueryにロードします。
DATASET="otomo_ds" bq mk --location asia-northeast1 ${DATASET}
今まで定義してきた変数を使いながら、読み込むテーブル名のリストを並べてxargs使って並列で、bqでロードジョブ流し込んでみます。Avroはスキーマ情報を保持しているので、こちらから渡してあげる必要が無く、オプションはシンプルになります。
AVRO_DIR="${OUTPUT_LOCATION}/${SPANNER_INSTANCE}-${SPANNER_DB}-${JOB_ID}" cat <<EOT | xargs -P 4 -Ixxx bq load --source_format=AVRO ${DATASET}.xxx "${AVRO_DIR}/xxx.avro*" Singers Users TableA TableB TableC EOT
これでデータがロードされてBigQuery側でも、データをクエリすることができるようになりました。