Spannerオートスケーリング環境の構築
社内でspannerを使用しているプロダクトがあります。
現状は固定値でノード数の管理を行っており今後顧客が増えた場合やバッチ処理、重い参照処理などが増えた場合に備えてスケーリングできる環境を構築しておく必要があり色々調べていたところ、spannerの長所としてダウンタイムなしでスケーリングができるDBといった部分もあるのですが、長所に反してどうやらgoogle cloud 純正では自動スケーリング機能は提供していないようでした。
2023年8月26日現在ではgoogle cloud blogの公式リファレンスでもサードパーティー製のautoscalerが推奨されていました。
google cloud blogで推奨されている
を使用してオートスケーリング環境を構築してみようと思います。
アーキテクチャ
google cloud blogから転載したアーキテクチャ図なのですがCloud Monitoringでリソースの使用状況を確認し、そこからトリガを叩くといった遠回りな手法となっています。
Cloud Monitoringベースなので今回はCloud Functionsでスケーラーを作成していますが、状況に合わせてここは何でも実装できます。
スケーリング対象アーキテクチャパターン
readmeを読んでみるとAutoscalerは以下の三種類のパターンがあるようです。
- Per-Project deployment: Autoscalerの全コンポーネントがSpannerインスタンスと同じプロジェクト内に存在する場合
- Centralized deployment: Autoscalerの全コンポーネントが一つのプロジェクト内にあり、Spannerインスタンスは異なるプロジェクトに存在する場合。
- Distributed deployment: Autoscalerのほとんどのコンポーネントが一つのプロジェクト内にあり、Cloud Schedulerだけが別の場所に存在する場合
今回は特にアーキテクチャには拘っていないためPer-Project deploymentを選択します。
セットアップ手順
1. リポジトリのクローンと環境変数設定
git clone https://github.com/cloudspannerecosystem/autoscaler.git
export AUTOSCALER_DIR="$(pwd)/autoscaler/terraform/cloud-functions/per-project"
2. GCPプロジェクトの準備と設定
プロジェクトを選択または新規作成
- 今回は割愛します。
環境変数を設定
export PROJECT_ID=<プロジェクトID>
gcloud config set project "${PROJECT_ID}"
export REGION=us-central1
export ZONE=us-central1-c
export APP_ENGINE_LOCATION=us-central
必要なCloud APIを有効化
gcloud services enable iam.googleapis.com \
cloudresourcemanager.googleapis.com \
appengine.googleapis.com \
firestore.googleapis.com \
spanner.googleapis.com \
pubsub.googleapis.com \
cloudfunctions.googleapis.com \
cloudbuild.googleapis.com \
cloudscheduler.googleapis.com \
cloudresourcemanager.googleapis.com
Google App Engine(Cloud Functions)を作成
gcloud app create --region="${APP_ENGINE_LOCATION}"
3. Autoscalerのデプロイ
Terraformの環境変数を設定
export TF_VAR_project_id="${PROJECT_ID}"
export TF_VAR_region="${REGION}"
export TF_VAR_zone="${ZONE}"
Terraformを初期化
cd "${AUTOSCALER_DIR}"
terraform init
リソースを作成
terraform apply -parallelism=2
上記のterrafromが適用出来たらリソースは作成完了しています。
4. コンフィグ設定の確認
terraformでデプロイしたCloud Schedulerのjsonで定義を行なっています。
key名もそれっぽく記載してくれているので値を変えることで基準の変更が可能です。
[
{
"projectId": "my-spanner-project",
"instanceId": "spanner1",
"scalerPubSubTopic": "projects/my-spanner-project/topics/spanner-scaling",
"units": "NODES",
"minSize": 1,
"maxSize": 3
},{
"projectId": "different-project",
"instanceId": "another-spanner1",
"scalerPubSubTopic": "projects/my-spanner-project/topics/spanner-scaling",
"units": "PROCESSING_UNITS",
"minSize": 500,
"maxSize": 3000,
"scalingMethod": "DIRECT"
}
]
所感
クローンしてデプロイするだけなのでかなり簡単に実装が可能なイメージです。
ただ、アーキテクチャ的にはpub subやらschedulerやらfunctionsやらモニタリングでかなりゴチャゴチャしているので早くspanner標準機能として実装が待ち遠しいです。 使用するリソースは少なければ少ないほど良いと考えています。
Discussion