これは、なにをしたくて書いたもの?
Neonという、フルマネージドでサーバーレスなPostgreSQLというプロダクトがあります。
Neon — Serverless, Fault-Tolerant, Branchable Postgres
これはマネージドサービスとしても使えるのですが、ローカルで動かすことができるようなので1度試してみようかなということで。
やってみた結果としては、ローカルで動かすことはもうやらないと思いますが(笑)。
Neon
Neonは、フルマネージドでサーバーレスなPostgreSQL互換のプロダクトです。
Neon — Serverless, Fault-Tolerant, Branchable Postgres
ドキュメントはこちら。
Neon documentation - Neon Docs
Rustで実装されていて、ストレージとコンピューティングを分離したアーキテクチャーであり、サーバーレスでもあるとされています。
Neon is a fully managed serverless Postgres with a generous free tier. Neon separates storage and compute and offers modern developer features such as serverless, branching, bottomless storage, and more. Neon is open source and written in Rust.
PostgreSQLとの互換性はこちらにあるとおりで、PostgreSQL 14、15、16に対して互換性があり、Neonプロジェクトを作成する時に
どのPostgreSQLのバージョンを使うかを選択するようです。
Postgres compatibility - Neon Docs
利用は基本的にマネージドサービスとしての利用で、無料枠を含めて4つのプランがあります。
無料枠で試してみるのもよいですね。
一方で、Neon自体はOSSで自分でビルドして動かすこともできます。
README.md
の最初を見ると、AWS Aurora PostgreSQLのサーバーレスなOSS代替であると書かれていますね。イメージとしては
これで捉えるのがよさそうです。
Neon is a serverless open-source alternative to AWS Aurora Postgres. It separates storage and compute and substitutes the PostgreSQL storage layer by redistributing data across a cluster of nodes.
現在のバージョンはrelease-4917
で、ローカルで動かすためには自分でビルドする必要があります。
その手順は、こちらに記載があります。
Neon / Running local installation
また、開発者向けドキュメントはこちらですね。
https://github.com/neondatabase/neon/tree/release-4917/docs
今回は、このNeonをローカルでビルドして動かすところまでをREADME.md
に沿ってやってみます。
結果を言うと、動くには動いたのですがビルドにものすごく時間がかかるので、今後はちょっと扱えないかなと思います…。
クラスターを組むところとかまで、到達しそうにないですね…。
環境
今回の環境はこちら。Ubuntu Linux 22.04 LTSです。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.4 LTS Release: 22.04 Codename: jammy $ uname -srvmpio Linux 5.15.0-97-generic #107-Ubuntu SMP Wed Feb 7 13:26:48 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
Neonをビルドしてインストールする
では、こちらの手順に沿ってNeonをビルド、インストールしていきます。
Neon / Running local installation
依存ライブラリーのインストール。
$ sudo apt install build-essential libtool libreadline-dev zlib1g-dev flex bison libseccomp-dev \ libssl-dev clang pkg-config libpq-dev cmake postgresql-client protobuf-compiler \ libcurl4-openssl-dev openssl python3-poetry lsof libicu-dev
postgresql-client
が含まれていますが、これはNeonに接続するpsqlコマンドで使います。
Rustのインストール。
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh $ source "$HOME/.cargo/env"
インストールされたRustのバージョン。
$ rustc --version rustc 1.76.0 (07dca489a 2024-02-04) $ cargo --version cargo 1.76.0 (c84b36747 2024-01-18)
$ git clone --recursive https://github.com/neondatabase/neon.git
Neonだけでなく、サブモジュールとして登録されているPostgreSQL 14、15、16もcloneしてくるのでかなり時間がかかります。
Submodule 'vendor/postgres-v14' (https://github.com/neondatabase/postgres.git) registered for path 'vendor/postgres-v14' Submodule 'vendor/postgres-v15' (https://github.com/neondatabase/postgres.git) registered for path 'vendor/postgres-v15' Submodule 'vendor/postgres-v16' (https://github.com/neondatabase/postgres.git) registered for path 'vendor/postgres-v16'
cloneしたディレクトリ内に移動して、現時点のリリースバージョン(release-4917)にチェックアウト。
$ cd neon $ git checkout release-4917
ビルド。
$ make -j`nproc` -s
すると、PostgreSQL 14、15、16も含めてビルドを始めようとします。
Configuring Postgres v14 build Configuring Postgres v15 build Configuring Postgres v16 build Installing PostgreSQL v14 headers Installing PostgreSQL v15 headers Installing PostgreSQL v16 headers Compiling PostgreSQL v14 Compiling PostgreSQL v15 Compiling libpq v14 Compiling pg_prewarm v14 Compiling pg_buffercache v14 Compiling pageinspect v14 Compiling amcheck v14 Compiling PostgreSQL v16 Compiling libpq v15 Compiling pg_prewarm v15 Compiling pg_buffercache v15 Compiling pageinspect v15 Compiling amcheck v15 Compiling neon v14 Compiling neon_walredo v14 Compiling neon_rmgr v14 Compiling neon_test_utils v14 Compiling neon_utils v14 Compiling neon v15 Compiling neon_walredo v15 Compiling neon_rmgr v15 Compiling neon_test_utils v15 Compiling neon_utils v15 Compiling libpq v16 Compiling pg_prewarm v16 Compiling pg_buffercache v16 Compiling pageinspect v16 Compiling amcheck v16 Compiling neon v16 Compiling neon_walredo v16 Compiling neon_rmgr v16 Compiling neon_test_utils v16 Compiling neon_utils v16 Compiling walproposer-lib Compiling Neon info: syncing channel updates for '1.76.0-x86_64-unknown-linux-gnu' info: latest update on 2024-02-08, rust version 1.76.0 (07dca489a 2024-02-04) info: downloading component 'cargo' info: downloading component 'clippy' info: downloading component 'llvm-tools' info: downloading component 'rust-docs' info: downloading component 'rust-std' info: downloading component 'rustc' info: downloading component 'rustfmt' info: installing component 'cargo' info: installing component 'clippy' info: installing component 'llvm-tools' info: installing component 'rust-docs' info: installing component 'rust-std' info: installing component 'rustc' info: installing component 'rustfmt'
が、途中で失敗しました。
error: failed to run custom build command for `storage_broker v0.1.0 (/path/to/neon/storage_broker)` Caused by: process didn't exit successfully: `/path/to/neon/target/debug/build/storage_broker-a85363180b39c0b7/build-script-build` (exit status: 101) --- stdout cargo:rerun-if-changed=proto/broker.proto cargo:rerun-if-changed=proto --- stderr thread 'main' panicked at storage_broker/build.rs:9:29: failed to compile protos Custom { kind: Other, error: "protoc failed: broker.proto: This file contains proto3 optional fields, but --experimental_allow_proto3_optional was not set.\n" } note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace make: *** [Makefile:69: neon] エラー 101
このissueを見ると、protocは3.15以上を使う必要がありそうです。
aptでインストールしたprotocのバージョンを確認してみます。
$ protoc --version libprotoc 3.12.4
たしかに古いです…。
というわけで、protocの最新バージョンをインストールしましょう。
適当なディレクトリに移動して、protoc 25.3(現時点での最新バージョン)をダウンロードして/usr/local
にインストール。
$ curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-linux-x86_64.zip $ unzip protoc-25.3-linux-x86_64.zip $ sudo cp bin/protoc /usr/local/bin/ $ sudo cp -R include/google /usr/local/include/google
Release Protocol Buffers v25.3 · protocolbuffers/protobuf · GitHub
確認。
$ protoc --version libprotoc 25.3
再度ビルド。
$ make -j`nproc` -s
今度はうまくいきました。
Installing PostgreSQL v14 headers Installing PostgreSQL v15 headers Installing PostgreSQL v16 headers Compiling PostgreSQL v14 Compiling PostgreSQL v15 Compiling libpq v14 Compiling pg_prewarm v14 Compiling pg_buffercache v14 Compiling pageinspect v14 Compiling amcheck v14 Compiling PostgreSQL v16 Compiling libpq v15 Compiling pg_prewarm v15 Compiling pg_buffercache v15 Compiling pageinspect v15 Compiling amcheck v15 Compiling neon v14 Compiling neon_walredo v14 Compiling neon_rmgr v14 Compiling neon_test_utils v14 Compiling neon_utils v14 Compiling neon v15 Compiling neon_walredo v15 Compiling neon_rmgr v15 Compiling neon_test_utils v15 Compiling neon_utils v15 Compiling libpq v16 Compiling pg_prewarm v16 Compiling pg_buffercache v16 Compiling pageinspect v16 Compiling amcheck v16 Compiling neon v16 Compiling neon_walredo v16 Compiling neon_rmgr v16 Compiling neon_test_utils v16 Compiling neon_utils v16 Compiling walproposer-lib Compiling Neon
ここまでで、とても時間がかかります…。
あとは、ドキュメントに沿ってNeonの初期化からプロセスの起動までを行っていきます。
Neonの初期化。
$ cargo neon init
実行ログ。
Compiling rustc-hash v1.1.0 Compiling tempfile v3.5.0 Compiling bindgen v0.65.1 Compiling prost-build v0.11.9 Compiling tonic-build v0.9.2 Compiling storage_broker v0.1.0 (/path/to/neon/storage_broker) Compiling postgres_ffi v0.1.0 (/path/to/neon/libs/postgres_ffi) Compiling pageserver_api v0.1.0 (/path/to/neon/libs/pageserver_api) Compiling pageserver_client v0.1.0 (/path/to/neon/pageserver/client) Compiling control_plane v0.1.0 (/path/to/neon/control_plane) Finished dev [unoptimized + debuginfo] target(s) in 5m 03s Running `target/debug/neon_local init` Initializing pageserver node 1 at '127.0.0.1:64000' in ".neon/pageserver_1"
pageserver、safekeeper、内部通信のためのbrokerの起動。
$ cargo neon start
実行ログ。
Finished dev [unoptimized + debuginfo] target(s) in 19.43s Running `target/debug/neon_local start` Starting neon broker at 127.0.0.1:50051. storage_broker started and passed status check, pid: 71502 The files belonging to this database system will be owned by user "xxxxx". This user must also own the server process. The database cluster will be initialized with locale "ja_JP.UTF-8". The default database encoding has accordingly been set to "UTF8". initdb: could not find suitable text search configuration for locale "ja_JP.UTF-8" The default text search configuration will be set to "simple". Data page checksums are disabled. creating directory .neon/attachment_service_db ... ok creating subdirectories ... ok selecting dynamic shared memory implementation ... posix selecting default max_connections ... 100 selecting default shared_buffers ... 128MB selecting default time zone ... Asia/Tokyo creating configuration files ... ok running bootstrap script ... ok performing post-bootstrap initialization ... ok syncing data to disk ... ok initdb: warning: enabling "trust" authentication for local connections initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb. Success. You can now start the database server using: /path/to/neon/pg_install/v16/bin/pg_ctl -D .neon/attachment_service_db -l logfile start Starting attachment service database... localhost:1235 - no response .localhost:1235 - no response localhost:1235 - rejecting connections localhost:1235 - accepting connections attachment_service_db started and passed status check, pid: 71520 ... attachment_service started and passed status check, pid: 71539 Starting pageserver node 1 at '127.0.0.1:64000' in ".neon/pageserver_1".. pageserver started and passed status check, pid: 71550 Starting safekeeper at '127.0.0.1:5454' in '.neon/safekeepers/sk1'. safekeeper-1 started and passed status check, pid: 71560
初期テナントの作成とneon_localのデフォルトの呼び出し先を設定。
$ cargo neon tenant create --set-default
実行ログ。
Finished dev [unoptimized + debuginfo] target(s) in 1.85s Running `target/debug/neon_local tenant create --set-default` tenant 274099fcecc835dfb9191dc8f717b759 successfully created on the pageserver Created an initial timeline '57b0fb7782137034ccbce605eeb99412' for tenant: 274099fcecc835dfb9191dc8f717b759 Setting tenant 274099fcecc835dfb9191dc8f717b759 as a default one
PostgreSQLコンピュートノードの作成。
$ cargo neon endpoint create main
実行ログ。
Finished dev [unoptimized + debuginfo] target(s) in 1.92s Running `target/debug/neon_local endpoint create main`
PostgreSQLコンピュートノードの起動。
$ cargo neon endpoint start main
実行ログ。
Finished dev [unoptimized + debuginfo] target(s) in 1.73s Running `target/debug/neon_local endpoint start main` Starting existing endpoint main... Starting postgres node at 'postgresql://cloud_admin@127.0.0.1:55432/postgres'
実行中のPostgreSQLインスタンスの確認。
$ cargo neon endpoint list Finished dev [unoptimized + debuginfo] target(s) in 1.83s Running `target/debug/neon_local endpoint list` ENDPOINT ADDRESS TIMELINE BRANCH NAME LSN STATUS main 127.0.0.1:55432 57b0fb7782137034ccbce605eeb99412 main 0/149F8D8 running
無事、インストールと起動が完了しました。
psqlでNeonに接続する
それでは、Neonに接続してみましょう。こちらもドキュメントに沿ってそのまま行います。
Neon / Running local installation
aptでインストールしたPostgreSQL Client(psql)がちょっと古いですが、今回はこのままいくことにしましょう。
$ psql --version psql (PostgreSQL) 14.10 (Ubuntu 14.10-0ubuntu0.22.04.1)
Neonへ接続。
$ psql -p 55432 -h 127.0.0.1 -U cloud_admin postgres psql (14.10 (Ubuntu 14.10-0ubuntu0.22.04.1), server 15.6) WARNING: psql major version 14, server major version 15. Some psql features might not work. Type "help" for help. postgres=#
cargo neon start
の時のログにも出ていましたが、ローカル接続だとtrust
扱いになっているのでパスワードを聞かれません。
initdb: warning: enabling "trust" authentication for local connections initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
テーブルの作成からデータ登録、確認まで。
postgres=# CREATE TABLE t(key int primary key, value text); CREATE TABLE postgres=# insert into t values(1,1); INSERT 0 1 postgres=# select * from t; key | value -----+------- 1 | 1 (1 row)
1度、psqlを終了します。
postgres=# \q
次はブランチです。Neonは、データに対するブランチを作成できるようです。
「migration_check」という名前のブランチを作成。
$ cargo neon timeline branch --branch-name migration_check Finished dev [unoptimized + debuginfo] target(s) in 1.87s Running `target/debug/neon_local timeline branch --branch-name migration_check` Created timeline '99182b9ad53c4b534c1d6f9b948e3ba3' at Lsn 0/14D5450 for tenant: 274099fcecc835dfb9191dc8f717b759. Ancestor timeline: 'main'
ブランチを確認。
$ cargo neon timeline list Finished dev [unoptimized + debuginfo] target(s) in 1.84s Running `target/debug/neon_local timeline list` main [57b0fb7782137034ccbce605eeb99412] ┗━ @0/14D5450: migration_check [99182b9ad53c4b534c1d6f9b948e3ba3]
mainから分岐した、migration_checkというブランチができていることがわかります。
ブランチに対するPostgreSQLコンピュートノードの作成。
$ cargo neon endpoint create migration_check --branch-name migration_check Finished dev [unoptimized + debuginfo] target(s) in 1.86s Running `target/debug/neon_local endpoint create migration_check --branch-name migration_check`
ブランチに対するPostgreSQLコンピュートノードの起動。
$ cargo neon endpoint start migration_check Finished dev [unoptimized + debuginfo] target(s) in 1.76s Running `target/debug/neon_local endpoint start migration_check` Starting existing endpoint migration_check... Starting postgres node at 'postgresql://cloud_admin@127.0.0.1:55434/postgres'
先ほどとは違うポートで起動しているようですね。
動作しているPostgreSQLインスタンスの一覧を見てみます。
$ cargo neon endpoint list Finished dev [unoptimized + debuginfo] target(s) in 1.93s Running `target/debug/neon_local endpoint list` ENDPOINT ADDRESS TIMELINE BRANCH NAME LSN STATUS main 127.0.0.1:55432 57b0fb7782137034ccbce605eeb99412 main 0/14D5450 running migration_check 127.0.0.1:55434 99182b9ad53c4b534c1d6f9b948e3ba3 migration_check 0/14D54C0 running
よく見ると、この中にブランチ名も含まれていますね。
migration_checkブランチの方のコンピュートノードへ接続。
$ psql -p 55434 -h 127.0.0.1 -U cloud_admin postgres psql (14.10 (Ubuntu 14.10-0ubuntu0.22.04.1), server 15.6) WARNING: psql major version 14, server major version 15. Some psql features might not work. Type "help" for help. postgres=#
データを確認すると、mainブランチで登録したデータが入っています。
postgres=# select * from t; key | value -----+------- 1 | 1 (1 row)
データを追加。
postgres=# insert into t values(2,2); INSERT 0 1
現在は2件のデータがあります。
postgres=# select * from t; key | value -----+------- 1 | 1 2 | 2 (2 rows)
psqlを終了。
postgres=# \q
mainブランチのコンピュートノードへ接続。
$ psql -p 55432 -h 127.0.0.1 -U cloud_admin postgres psql (14.10 (Ubuntu 14.10-0ubuntu0.22.04.1), server 15.6) WARNING: psql major version 14, server major version 15. Some psql features might not work. Type "help" for help. postgres=#
こちらでは、migration_checkブランチで追加したデータが見えないことが確認できます。
postgres=# select * from t; key | value -----+------- 1 | 1 (1 row)
オマケ:neon_local
Neonの初期化の際に、neon_localのデフォルトの呼び出し先を設定というステップがありましたが、neon_local自体には触れていません
でした。
neon_localは、Neonをビルドするとtarget/debug
ディレクトリ内に作成されます。
$ target/debug/neon_local --version Neon CLI git:96a4e8de660be469fb00efd7d268120890ca06fd-modified
そもそも、今までcargo neon [コマンド]
といった形でコマンドを実行していましたが、実行ログをよく見ると実体としてはneon_localを
呼び出していることが示されていました。
$ cargo neon endpoint list Finished dev [unoptimized + debuginfo] target(s) in 1.88s Running `target/debug/neon_local endpoint list` ENDPOINT ADDRESS TIMELINE BRANCH NAME LSN STATUS main 127.0.0.1:55432 57b0fb7782137034ccbce605eeb99412 main 0/14D5450 running migration_check 127.0.0.1:55434 99182b9ad53c4b534c1d6f9b948e3ba3 migration_check 0/14D5828 running
「Running」の部分ですね。
ということは、cargo neon
をneon_local
に置き換えても実行できるはずです。
$ target/debug/neon_local endpoint list ENDPOINT ADDRESS TIMELINE BRANCH NAME LSN STATUS main 127.0.0.1:55432 57b0fb7782137034ccbce605eeb99412 main 0/14D5450 running migration_check 127.0.0.1:55434 99182b9ad53c4b534c1d6f9b948e3ba3 migration_check 0/14D5828 running
やっぱりそうでした。
ではこれがNeon標準のCLIツールかというとそれはちょっと違うようで、Neon CLIは別に存在します。
おわりに
OSSのサーバーレスPostgreSQL、Neonを自分でビルドして動かしてみました。
おもしろいな、と思うのですが、ビルドに時間がかかりすぎるのとリソース的にもちょっとヘビー気味なので、自分の手持ちの環境で
遊ぶのは難しそうかな…と思います。
もともと興味はあって、1度動かしてみたいなと思っていたくらいなので、ここまでにしておきましょう。