はじめに
Neonという Serverless な Postgres を提供しているサービスのリージョンを変更することがあったので、その手順を備忘録として残しておきます。
移行自体は macOS で進めていきます。
一応、以下のドキュメントにもリージョンの変更手順は書かれているのですが、無料プランではプロジェクトを同時に1つしか持てないため、危ない橋を渡る必要があります。
また、経緯として個人開発の技術構成とその制約に基づいた元のリージョン構成を見て、さらに新しいリージョン構成とのラウンドトリップタイム(RTT)の概算を出し、簡単な比較を行っています。
こちらだけ見たい方は、 ↓ おまけ: リージョン変更の経緯をご覧ください。
おおまかな移行手順
以下の手順で進めていきます。
- 各種ツールのインストール
- 現在のデータをすべて export
- (optional) ローカルで確認
- プロジェクト削除・作成
- export したデータを import & 確認
1. 各種ツールのインストール
import/export (および確認)のために以下のツールを Mac にインストールしていきます。
$ brew install libpq
$ brew install postgresql@16 # (optional)
$ echo 'export PATH="/usr/local/opt/libpq/bin:$PATH"' >> ~/.zshrc
$ souce ~/.zshrc
psql
コマンドが動くことを確認します。
$ psql -V
psql (PostgreSQL) 16.2
2. 現在のデータをすべて export
Neon コンソール画面にて Project Dashboard の Connection Details 内にあるテキストエリア上のプルダウンから psql
を選択しその値をコピーしておきます。
- 例:
postgresql://user:pass@example.ap-southeast-1.aws.neon.tech/example?sslmode=require
そちらをターミナルに貼り付けて接続できることを確認します。
$ psql 'postgresql://user:pass@example.ap-southeast-1.aws.neon.tech/example?sslmode=require'
psql (16.2)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
example=>
接続が確認できたら、 pg_dump
コマンドで実際に export をしていきます。
$ pg_dump 'postgresql://user:pass@example.ap-southeast-1.aws.neon.tech/example?sslmode=require' > export.sql
export できたら中身を cat
コマンドやお使いのエディタなどで一応確認します。
--
-- PostgreSQL database dump
--
-- Dumped from database version 16.2
-- Dumped by pg_dump version 16.2
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
...
3. (optional) ローカルで確認
こちらは念の為にローカルで動くかを確認したいひと向けです。
はじめにローカルで postgres を立ち上げます。
docker などを使用してもよいですが、今回は簡便化のため brew
コマンドで立ち上げて中に入ります。
$ brew services start postgresql@16
$ psql
中に入れたら、DBとユーザーの作成をします。
-- 任意のデータベース名を指定
create database "example";
-- 任意のユーザー名・パスワードを指定
create user user with encrypted password 'pass';
exit
作成できたら、以下のコマンドで作成した DB にデータを入れ込みます。
$ psql example < export.sql
この時点で開発中のアプリの DB 向き先をローカルに向けて動作確認します。
4. プロジェクト削除・作成
データの export (とローカルでの動作確認)が取れたら、プロジェクトを削除していきます。
プロジェクトの削除自体は Neon コンソールの Project settings -> Delete から「Delete project」ボタンクリックでできます。
削除できたら、 Neon の UI の指示にしたがって再度プロジェクトを作成します。
このときに、変更先のリージョンを選んでください。
5. export したデータを import & 確認
作成できたら、ステップ 2 と同じ手順で psql
を選択して表示される値をコピーします。
コピーした値をそのままターミナルに貼り付けて以下のようなコマンドで export.sql
をリダイレクトで流し込んであげます。
$ psql 'postgresql://user:pass@example.ap-southeast-1.aws.neon.tech/example?sslmode=require' < export.sql
流し込めたら、開発中のアプリのDB向き先を新しい Neon の DB に向けてあげて確認すれば完了です。
おまけ: リージョン変更の経緯
現在筆者が作っている個人開発プロダクトでは以下の技術構成を取っています。
- フロントエンド: Next.js (Vercel)
- バックエンド: NestJS (Railway)
- データベース: Postgres (Neon)
しかし、 Vercel は東京(ap-northeast-1)、 Railway はオレゴン(us-west-2)、 Neon はシンガポール(ap-southeast-1)となっており、 RTT が非常に長くなってしまっていました。
そもそもなんでこんなリージョンバラバラなんだよ!
- ローカル開発
- 「まずは DB は Neon にデプロイするか〜」
- 「東京リージョンはないから一番近いシンガポールリージョンにしとこ...」
- フロント・バックエンドのデプロイ
- 「フロントエンドは手っ取り早く Vercel に乗せるとして、東京リージョンがあるな、、、よし!」
- 「バックエンドは...前に使ったことある Railway が良さそうだからコレにしよう!」
- 「あれ、、、リージョンはオレゴン固定か、、、まあいいか」
- 実際に自分で使ってみる
- 「めちゃくちゃ重い...」
というわけで、行き当たりばったりにリージョンを決めていったらこの結果になりました。
じゃあどうする?
個人開発サービスは日本からのアクセスしか想定していないので、できれば東京リージョンに全部まとめたいなあ、と思っていました。
しかし、 Neon は上述のとおり東京リージョンがなく、さらに Railway はそもそも Pro プランでしかリージョンを選ぶことができず、デフォルトでオレゴン固定になってしまいます。
というわけで一旦すべてのサービスをオレゴンに集結させることになりました。
結果どうなった?
体感でいうと1秒ぐらい速くなった気がします。(ちゃんとデータとして取っていないのでなんとも言えないですが...)
せっかくなので、以下の記事を参考にリージョンを概算してみます。
東京(ap-northeast-1) | オレゴン(us-west-2) | シンガポール(ap-southeast-1) | |
---|---|---|---|
東京(ap-northeast-1) | 1.76ms | 108.51ms | 73.38ms |
オレゴン(us-west-2) | 98.61ms | 4.69ms | 216.69ms |
シンガポール(ap-southeast-1) | 72.44ms | 159.89ms | 1.84ms |
ということで大体のリージョン間のレイテンシがわかったので、次にサービスのリクエストの流れを見てみます。
これに元のリージョンでのレイテンシを当てはめて見てみます。
ココでは東京を apne1 、 オレゴンを usw2 、 シンガポールを apse1 とします。
次にすべてを集結させたリージョンに当てはめてみます。
というわけで、これを合計して比較してみると...
- 元リージョン構成: 約 587.22 ms
- 新リージョン構成: 約 225.88 ms
倍近くRTTを削減できていることがわかります。
元の RTT 値自体が各リージョンの Lambda -> 各リージョンの DynamoDB ping endpoint の RTT を取得しているらしいです。
今回の筆者のサービスでいうと各サービス間のレイテンシはもっと遅いはずです。
したがって、単純計算はできませんがおよそ体感の「1秒ぐらい速くなった」のは妥当な気もします。
まとめ
複数のサービスを組み合わせるときは、よりいっそうリージョンを意識しよう!!!(自戒)