定期的に Cloud Spanner のデータを外部へ書き出したい場合 1 は、Cloud Scheduler から Cloud Dataflow を起動させるることで実現できる。
全体像まとめ
- Spanner のデータを Avro 形式で GCS に書き出す
- Cloud Scheduler から定期的に export 用の Dataflow Job を起動させる
Terraform 設定例
以下詳細
Spanner の export 方法
export を行うには主に、
- GCP コンソールから行う
- Google 提供のテンプレートを使って Dataflow job を作成する
方法がある。Dataflow のトリガーは gcloud CLI や HTTP API などから行えるので、これを使って定期実行させる。
export 用 Dataflow テンプレートを使う
Dataflow 向けに、典型的な操作を行うためのテンプレートが Google から提供されている
(Google 提供のテンプレートを使ってみる)。この中に Spanner からの export を行うテンプレートも用意されている。今回は Cloud Spanner to Cloud Storage Avro を使う。
このテンプレートは、次のような必須パラメータを取る。最低限これらを渡して Dataflow を起動させるだけでよい。
instanceIddatabaseId-
outputDir(Cloud Storage のパス)
その他のパラメータや gcloud での実行例等、詳細についてはドキュメントを参照のこと
Cloud Scheduler から Dataflow job を起動する
本記事とは別のテンプレートだが、こちらに例がある。
ざっくり言えば
- Dataflow job の作成権限をもったサービスアカウントを使う
- HTTP ターゲットで
https://dataflow.googleapis.com/v1b3/projects/<プロジェクト名>/locations/<リージョン>/templatesを叩く - リクエストボディに Dataflow テンプレートのパラメータを書く
な Scheduler job を作ればよい。
Terraform 設定例
- export 先 Cloud Storage
- 実行用サービスアカウント
- Scheduler job
を作るための Terraform 例。全ファイルを置いたレポジトリは こちら( komazarari/terraform-export-google-spanner )
パラメータ
variable "project_id" {
type = string
}
variable "spanner_instance" {
type = string
}
variable "spanner_db" {
type = string
}
variable "bucket_name" {
type = string
}
variable "region" {
type = string
default = "asia-northeast1"
description = "GCS と Dataflow job の実行リージョン. Spanner インスタンスと同じにする"
}
variable "export_schedule" {
type = string
default = "0 0 * * *"
}
variable "days_buckups" {
type = number
default = 7
description = "export したデータを保持する日数"
}
variable "dataflow_template_version" {
type = string
default = "2021-07-05-00_RC01"
}
Cloud Storage (期限付き)
今回は定期的に export して溜まっていく想定なので、一定期間を過ぎたものを lifecycle で削除するようにして Cloud Storage を作成する。
resource "google_storage_bucket" "bucket" {
name = var.bucket_name
location = var.region
lifecycle_rule {
condition {
age = var.days_buckups
}
action {
type = "Delete"
}
}
}
実行用サービスアカウント
GCP 管理ロールの dataflow.developer を付与する。アカウント名はなんでもよい。
resource "google_service_account" "export_user" {
account_id = "${var.spanner_instance}-${var.spanner_db}-export"
display_name = "${var.spanner_instance}-${var.spanner_db}-export"
}
resource "google_project_iam_member" "export_user_dataflow_role" {
role = "roles/dataflow.developer"
member = "serviceAccount:${google_service_account.export_user.email}"
}
Cloud Scheduler
テンプレートに必要なパラメータを base64エンコードした JSON で渡す。サービスアカウントの認証のために oauth_token ブロックを書く。
resource "google_cloud_scheduler_job" "export_job" {
name = "${var.spanner_instance}-${var.spanner_db}-export-job"
schedule = var.export_schedule
region = var.region
http_target {
http_method = "POST"
uri = "https://dataflow.googleapis.com/v1b3/projects/${var.project_id}/locations/${var.region}/templates"
oauth_token {
service_account_email = google_service_account.export_user.email
}
body = base64encode(<<-EOT
{
"jobName": "${var.spanner_instance}-${var.spanner_db}-export-job",
"parameters": {
"instanceId": "${var.spanner_instance}",
"databaseId": "${var.spanner_db}",
"outputDir": "${google_storage_bucket.bucket.url}/"
},
"gcsPath": "gs://dataflow-templates/${var.dataflow_template_version}/Cloud_Spanner_to_GCS_Avro",
"environment": {
"tempLocation": "${google_storage_bucket.bucket.url}/_staging"
}
}
EOT
)
}
}
動作確認
Cloud Scheduler を手動実行して Cloud Storage にファイルが生成されていることを確認する。
参考
- Exporting databases from Cloud Spanner to Avro
- Google 提供のバッチ テンプレート
- Schedule Dataflow batch jobs with Cloud Scheduler
- google_cloud_scheduler_job | Resources | hashicorp/google | Terraform Registry
-
Spanner のデータ保護の主な仕組みとして バックアップ、ポイントインタイムリカバリ、それと本記事で言及している export がある。それぞれ別の目的で使える (https://cloud.google.com/spanner/docs/backup) ので、そもそも定期的な export が必要かどうか、から要検討 ↩
