☆GCP☆ Spanner を定期削除/復元してコスト削減する☆技術/サービス紹介
2020/06/30
こんにちは。DOUZO ブログ担当です。
ブログでは業務で触れた技術やサービスについてざっくり紹介しています。
最近、Spanner を利用するプロジェクトに携わっています。
Spanner は最小構成でも 24 時間稼働させた場合は月間で 70,000 円ほどとなり、
開発環境としては高めで導入のハードルの一つかなと思います。
そこでコスト削減のために、Spanner インスタンスの定期削除/復元を自動化してみました。
Spanner 標準のバックアップはインスタンスを削除すると一緒に消えてしまうので、エクスポート機能を利用して database 毎に GCS へアウトプットする必要があり少し工夫が必要です。
結果的には、夜間/土日は停止することで半分以上のコスト削減をすることができました。
今回は対応した内容をざっくり紹介したいと思います。
・利用したサービスなど
GCP: CloudScheduler, CloudBuild, ContainerRegistry, CloudFunction
他: GitHub, bash, slack
・流れ
CloudScheduler -> CloudBuild ( -> Pubsub -> CloudFunction -> Slack )
※ Pubsub 以降は実行結果通知のためのものです
今回は gcloud コマンドを利用したかったので、スクリプトは bash で書いてみました。スクリプトを実行可能な docker image を用意し、CloudBuild で実行するようにビルドトリガーを構成します。実行時間や曜日は CloudScheduler で制御しました。
・手順(ざっくり)
1. スクリプト作成
< gcloud コマンドでのインポート/エクスポート >
インポート/エクスポートは dataflow のジョブを実行するかたちとなります。gcloud コマンドはそれぞれ以下の通り。
※実行したジョブが割とよく失敗するので再実行など工夫が必要です
# export
$ gcloud dataflow jobs run <ジョブの名前> \
--gcs-location='gs://dataflow-templates/latest/Cloud_Spanner_to_GCS_Avro' \
--region=us-central1 \
--parameters=instanceId=<インスタンスの名前>,databaseId=<DBの名前>,outputDir=< GCS の場所>
# import
$ gcloud dataflow jobs run <ジョブの名前> \
--gcs-location='gs://dataflow-templates/latest/GCS_Avro_to_Cloud_Spanner' \
--region=us-central1 \
--parameters=instanceId=<インスタンスの名前>,databaseId=<DBの名前>,inputDir=< GCS の場所>
< スクリプトの流れ >
エクスポート:
database 毎に gcloud dataflow コマンドでエクスポート実行 -> 成功したら GCS 操作(latest 配下へ移動) -> Spanner インスタンス削除
インポート:
Spanner インスタンス作成 -> database 作成 -> database 毎に gcloud dataflow コマンドでインポート実行 -> 成功したら終了
2. CloudBuild トリガー作成
作成したスクリプトを実行するよう yaml を用意します。例えばこんな感じです。
steps:
- name: 'gcr.io/$PROJECT_ID/hogehoge:hoge'
entrypoint: './scripts/export_spanner_database.sh'
args: [ '$_SPANNER_INSTANCE_NAME' ]
3. CloudScheduler 設定
HTTP ターゲット認証で Cloud Build を実行するよう構成します。
https://freelance-recruit-douzo.com/blog/detail/20200129145457/
(4. 通知設定)
https://cloud.google.com/cloud-build/docs/configure-third-party-notifications
・GCS ディレクトリ構成
DB のデータは GCS へ格納されるようになるのですが、ディレクトリ構成を少し工夫しました。まず、最新のバックアップは常に latest 配下に保管されるようしました。また、バックアップ時はインスタンス配下の全ての database をエクスポートし、リストア時には latest 配下にあるデータを全てインポートするよう構成しています。
gs://xxxxxx-spanner-backup
└── instance_name
├── YYYY-MM-DD-hh-mm
│ ├── database_name1/xxxxxx
│ ├── database_name2/xxxxxx
│ └── database_name3/xxxxxx
└── latest
└── YYYY-MM-DD-hh-mm
├── database_name1/xxxxxx
├── database_name2/xxxxxx
└── database_name3/xxxxxx
いつもざっくりめの説明ですみません。興味のある方は試してみてください。
---------------------------------------------------------------------------------------
DOUZO の営業担当者は全員フリーランスエンジニアの経験があり、私も含め現役のエンジニアだったりします。
なるべく多くをエンジニアへ還元するよう努めていますので、どうぞお気軽にご相談ください!