🌍

Aurora から PlanetScale に移設した

2023/10/07に公開

概要

個人開発で利用しているデータストア ( MySQL ) を Amazon Aurora から PlanetScale に乗り換えた話です。

何故乗り換えたか

今回対象としてるアプリケーションは個人で開発している小さなものです。
フロントエンドは Vercel 、バックエンドは Google Cloud の Cloud Run を利用しています。
アプリケーションのデータストアとしては Amazon Web Services の Amazon Aurora を利用しています。

データストアだけ Aurora を利用している理由は、個人開発で他のアプリケーションともデータストアを共有することでコストを抑えるためです。
Aurora のインスタンスタイプは db.t3.small を利用していました。 1 ヶ月のコストは約 4,000 円程でした。
一般的に会社などで利用することを考えたら格安で利用出来るのですが、利益も生み出さない個人の趣味プロジェクトにおいて毎月 4,000 円の出費はかなり手痛いものがあったので、別のソリューションを考え始めました。

そこで目についたのが去年くらいに目にした PlanetScale でした。 PlanetScale の詳細については後述しますが、何と言っても魅力的なのが MySQL 互換でありながら Hobby プランは制約はありつつも今回の想定利用範囲内だと無料[1]で利用出来る点でした。

PlanetScale とは

https://planetscale.com/

PlanetScale は裏側は Vitess と呼ばれる YouTube や Slack でも利用実績のある MySQL 互換なデータベースを利用しています。
https://vitess.io/

PlanetScale は、この Vitess を DBaaS として提供しているサービスです。

他にも、 Vitess の機能を利用したブランチによるスキーマ管理などの機能などもあります。
https://planetscale.com/docs/concepts/branching#development-and-production-branches

乗り換えにおける障壁

Aurora から PlanetScale に乗り換えるにあたり、既存のアプリケーションをいくつか修正する必要がありました。

スキーマ変更

今回の対象のアプリケーションは MySQL のテーブルスキーマの変更を ent の Auto migration を利用してアプリケーション起動時に流し込んでいました。
https://entgo.io/

しかし、 PlanetScale では main branch に対して直接 DDL を利用したスキーマ変更を受け付けていません。
https://planetscale.com/docs/concepts/branching#development-and-production-branches

そのため、アプリケーションによる Auto migration の廃止やスキーマ変更のフローを変更する必要がありました。
現状は頻繁にスキーマ変更されないこともあり、 ent で生成されるスキーマ ( DDL ) を手動で PlanetScale の新しいブランチに適用し Deploy request を作成し、本番に反映しています。

外部キー制約

PlanetScale の制約というよりは Vitess の技術的制約となっています。
Vitess では設計上の理由により外部キーを利用することが出来ません。詳細は以下の記事をご覧ください。
https://zenn.dev/tak_iwamoto/articles/b27151d22d9e6a#なぜ外部キー制約をサポートしていないのか

今回の対象のアプリケーションでも外部キーを利用していたため、テーブルから外部キーを削除する作業を移行前に実施しています。

TLS 接続対応

PlanetScale ではデータベースの接続に TLS オプションを利用する必要がありました。そのためアプリケーション側で TLS を利用して接続するように実装変更を行いました。

今回は以下のように mysql.Config に対して TLSConfig を設定することで TLS 接続を実現しました。


import (
	"github.com/go-sql-driver/mysql"
)

caCertPool := x509.NewCertPool()
pem, err := ioutil.ReadFile("/etc/ssl/cert.pem")
if err != nil {
	panic(err)
}
if ok := caCertPool.AppendCertsFromPEM(pem); !ok {
	panic(fmt.Errorf("Failed to append PEM."))
}

mysql.RegisterTLSConfig("custom", &tls.Config{
	RootCAs: caCertPool,
})

connection = mysql.Config{
	User:                 "user",
	Passwd:               "password",
	Net:                  "tcp",
	Addr:                 "database_host:3306",
	DBName:               "database",
	ParseTime:            true,
	AllowNativePasswords: true,
	TLSConfig:            "custom",
}

乗り換え方法

PlanetScale では 2022 年 12 月 31 日現在、 β 版ではありますが Aurora からの Import をサポートしています。これには Aurora のマスターパスワードなどが必要になりますが、今回は個人利用しているインスタンスであり認証やセキュリティも特に問題にならなかったためこの機能を用いて Import を行いました。
https://planetscale.com/docs/imports/database-imports

Aurora においていくつかオプションを変更する必要があったのですがこちらのドキュメント通りに行うことで問題なく Import を行うことが出来ました。
https://planetscale.com/docs/imports/aws-rds-migration-guide

乗り換え後の様子

レイテンシ

おまけの話ですが、移設後に明らかにアプリケーションのレイテンシが悪化していました。

しばらくは、まぁ無料ならそれくらい許容するか…と思っていたのですが、ふと PlanetScale のコンソールを眺めていると…

AWS us-east-1 (Northern Virginia)

はい、 API を実行している Cloud Run は asia-northeast1 で稼働しているのに PlanetScale のデータベースを何故か us-east-1 で起動させちゃってました。

そりゃ遅いよね。ってことで、年明けにでも再度、データベースの移設を行おうと思います…

Hobby プランではデータベースは 1 つしか作られないのでどのように移設するかを考えながらの年越しになりそうです。

脚注
  1. PlanetScale Pricing ↩︎

Discussion