🐛

[WIP] CockroachDB触ってみる

2024/06/12に公開

耐障害姓がとても高いというCockroachDBを、公式チュートリアルに沿って触ってみる。
下記のスライドでどんだけ耐障害性がすごいのか、説明されています。

こちらのスライドでは「とてもしぶとい」理由がデータを分散させて持っているからと言うのがわかるかと思います。しかし、それでMySQLやPosgreSQLなどのよく使われるRDBと使用感が違い過ぎたらパッとは使えなさそうだなぁと思い、どんなもんじゃいというところで触ってみようと思います。

大まかには下記に沿ってやっていきます

実行環境は下記の通り

  • WSL2 (Ubuntu 22.04)
  • cockroach v24.1.0

結論

CockroachDB in Comparison というページが有り、こちらで説明されていますが最初の心配事だった

MySQLやPosgreSQLなどのよく使われるRDBと使用感が違い過ぎたらパッとは使えなさそうだなぁ

という懸念は

Yes - wire compatible with PostgreSQL

と説明されているのでPostgreSQLに慣れている人であればおそらく何も心配いらないようです。安心。
ただし僕はPostgreSQLに触ったことがないので、その……

インストール

まずはインストール。Dockerを使って……と思ったのですが、 cockroach コマンドを使いプロジェクトの作成などを行う必要があるようで、公式的にはDockerに習熟してないならまずは普通にバイナリをインストールしてね、ということが書いてありました。
僕はDockerに習熟しているとはとても言えないのでWSL上にインストールしていきます。たぶん調べればDockerを使った方法を解説している方もいるのかなと思うので、Dockerを使いたい方はググってみてください。

# tgzファイル取得
# バージョンは記事作成時のバージョンのため注意
$ wget https://binaries.cockroachdb.com/cockroach-v24.1.0.linux-amd64.tgz
$ tar -xf cockroach-v24.1.0.linux-amd64.tgz
$ cd cockroach-v24.1.0.linux-amd64
# バイナリを /usr/local/bin にコピー。各人の環境で変更してください
$ sudo cp cockroach /usr/local/bin
$ mkdir -p /usr/local/lib/cockroach
$ sudo cp -i lib/libgeos.so /usr/local/lib/cockroach/
$ sudo cp -i lib/libgeos_c.so /usr/local/lib/cockroach/
# 確認
$ cockroach --version
cockroach version details:
Build Tag:        v24.1.0
Build Time:       2024/05/15 21:28:29
Distribution:     CCL
Platform:         linux amd64 (x86_64-pc-linux-gnu)
Go Version:       go1.22.2 X:nocoverageredesign
C Compiler:       gcc 6.5.0
Build Commit ID:  5e4ca9e26f1a25681de9c944298cfa139c344466
Build Type:       release
Enabled Assertions: false
(use 'cockroach version --build-tag' to display only the build tag)

# demo コマンドで確認
$ cockroach demo
# :
> SELECT ST_IsValid(ST_MakePoint(1,2));
  st_isvalid
--------------
      t
(1 row)

Time: 1ms total (execution 0ms / network 0ms)

ここまでできていればOK。

TypeScriptサンプルアプリを動かす

下記のURLに沿ってやっていきます。

$ cockroach start-single-node --advertise-addr 'localhost' --insecure
# :
build:               CCL v24.1.0 @ 2024/05/15 21:28:29 (go1.22.2 X:nocoverageredesign)
webui:               http://localhost:8080
sql:                 postgresql://root@localhost:26257/defaultdb?sslmode=disable
# :

「シングルノードで、localhostとして、非productionモードで起動」って感じですかね。上記で書いた3行が重要っぽい。
ただこのまま実行するとフォアグラウンドで起動してしまうので、気になる方はtmuxとかを使うと良いかもです。

$ git clone https://github.com/cockroachlabs/example-app-typescript-typeorm
$ cd example-app-typescript-typeorm
$ npm i
$ vim src/datasource.ts
# ssl, extra をコメントアウトし、 `ssl: { rejectUnauthorized: false }` をアンコメント
$ export DATABASE_URL="postgresql://root@localhost:26257/defaultdb?sslmode=disable"

$ npm start

で、走り出す……はずがエラー

> hello-world-typescript-typeorm@0.0.1 start
> ts-node src/index.ts

Error: The server does not support SSL connections

仕方ないので一旦 ssl: false にしてみる

$ vim src/datasource.ts
# ssl: false に修正

# 再実行
$ npm start
> hello-world-typescript-typeorm@0.0.1 start
> ts-node src/index.ts

Inserting a new account into the database...
#:

うまく行ったっぽい。

マルチノードにしてみる

シングルノードで動かして大丈夫だったので次はマルチノードにしてみます。

上記の内容では最初3ノードで始めて、その後2ノードを追加する手順を示しているようです。

$ mkdir cockroachdb && cd cockroachdb # この行は実行しなくてもOK
$ cockroach cert create-ca --certs-dir=certs --ca-key=my-safe-directory/ca.key
$ cockroach cert create-node localhost $(hostname) --certs-dir=certs --ca-key=my-safe-directory/ca.key
$ cockroach cert create-client root --certs-dir=certs --ca-key=my-safe-directory/ca.key

ここでなんとなく certs を確認してみる。

$ ls certs
ca.crt  client.root.crt  client.root.key  node.crt  node.key

当たり前だけどnode用の証明書とクライアントのroot用証明書が作られている。
ドキュメントの記述から本来はノードごとに証明書を作成する必要があるんだろうけど、そのへんはクラウド環境ではいい感じにやってくれるのかな?
進めます。

ノードを3つスタート。ただしそれぞれのコマンドは新しいターミナルで実行する必要がある模様。tmuxの新規ウィンドウで対応。

$ cockroach start --certs-dir=certs --store=rep-node1 --listen-addr=localhost:26257 --http-addr=localhost:8080 --join=localhost:26257,localhost:26258,localhost:26259
$ cockroach start --certs-dir=certs --store=rep-node2 --listen-addr=localhost:26258 --http-addr=localhost:8081 --join=localhost:26257,localhost:26258,localhost:26259
$ cockroach start --certs-dir=certs --store=rep-node3 --listen-addr=localhost:26259 --http-addr=localhost:8082 --join=localhost:26257,localhost:26258,localhost:26259

最後に init コマンドを実行すれば良いとのこと。実行先が1つでも --join で指定したノード全てに init してくれるとのこと。

$ cockroach init --certs-dir=certs --host=localhost:26257
Cluster successfully initialized

この時点でそれぞれのノードのターミナルに接続作情報などが表示される模様。build, webui, sql の3つですね。

そうしたら進みます。

# SQLユーザー作成. パスワードはそれぞれの環境で変えてください
$ cockroach sql --certs-dir=certs --host=localhost:26257
> CREATE USER maxroach WITH PASSWORD 'awesomepassword';
CREATE ROLE

> GRANT admin TO maxroach;
GRANT

> \q

# データ書き込み. ここではサンプルデータをロードしている模様
$ cockroach workload init intro 'postgres://maxroach:awesomepassword@localhost:26257?sslmode=verify-full&sslrootcert=certs/ca.crt'
I240611 16:05:27.449100 1 ccl/workloadccl/fixture.go:315  [-] 1  starting import of 1 tables
I240611 16:05:27.734344 14 ccl/workloadccl/fixture.go:492  [-] 2  imported 2.8 KiB in mytable table (42 rows, 0 index entries, took 258.376507ms, 0.01 MiB/s)
I240611 16:05:27.734444 1 ccl/workloadccl/fixture.go:323  [-] 3  imported 2.8 KiB bytes in 1 tables (took 285.13974ms, 0.01 MiB/s)

# データ確認
$ cockroach sql --user=maxroach --certs-dir=certs --host=localhost:26257 # パスワード応答
# intro ができていることを確認
> SHOW DATABASES;
  database_name |  owner   | primary_region | secondary_region | regions | survival_goal
----------------+----------+----------------+------------------+---------+----------------
  defaultdb     | root     | NULL           | NULL             | {}      | NULL
  intro         | maxroach | NULL           | NULL             | {}      | NULL
  postgres      | root     | NULL           | NULL             | {}      | NULL
  system        | node     | NULL           | NULL             | {}      | NULL
(4 rows)

> SHOW TABLES FROM intro;
  schema_name | table_name | type  |  owner   | estimated_row_count | locality
--------------+------------+-------+----------+---------------------+-----------
  public      | mytable    | table | maxroach |                  42 | NULL
(1 row)

> select * from intro.mytable where (l % 2) = 0;
  l  |                          v
-----+-------------------------------------------------------
   0 | !__aaawwmqmqmwwwaas,,_        .__aaawwwmqmqmwwaaa,,
   2 | !"VT?!"""^~~^"""??T$Wmqaa,_auqmWBT?!"""^~~^^""??YV^
   4 | !                    "?##mW##?"-
   6 | !  C O N G R A T S  _am#Z??A#ma,           Y
   8 | !                 _ummY"    "9#ma,       A
  10 | !                vm#Z(        )Xmms    Y
  12 | !              .j####mmm#####mm#m##6.
  14 | !   W O W !    jmm###mm######m#mmm##6
  16 | !             ]#me*Xm#m#mm##m#m##SX##c
  18 | !             dm#||+*$##m#mm#m#Svvn##m
  20 | !            :mmE=|+||S##m##m#1nvnnX##;     A
  22 | !            :m#h+|+++=Xmm#m#1nvnnvdmm;     M
  24 | ! Y           $#m>+|+|||##m#1nvnnnnmm#      A
  26 | !  O          ]##z+|+|+|3#mEnnnnvnd##f      Z
  28 | !   U  D       4##c|+|+|]m#kvnvnno##P       E
  30 | !       I       4#ma+|++]mmhvnnvq##P`       !
  32 | !        D I     ?$#q%+|dmmmvnnm##!                                                                                                                                                                         34 | !           T     -4##wu#mm#pw##7'
  36 | !                   -?$##m####Y'
  38 | !             !!       "Y##Y"-
  40 | !
(21 rows)

> \q

次はwebuiを使うようです。

https://localhost:8080 にアクセス。おそらく証明書が自己証明書なので警告が出ますが、そのままアクセス。
下記画面から maxroach ユーザーでログイン。
ログイン画面

ログイン後に表示される Overview の下記の赤枠のところに注目すると各レプリカに56のrangeデータが存在しているということっぽいです(ただしほぼシステムデータとのこと)。
Overview画面に表示されるReplicaの列がハイライトされている

現状はデフォルト値の3でレプリケーションされていますが、nodeの数が増えてReplicaの値も増やせばそれだけ耐障害性が増えるってわけですね~。
というわけで引き続き2つのノードを追加します。

$ cockroach start --certs-dir=certs --store=rep-node4 --listen-addr=localhost:26260 --http-addr=localhost:8083 --join=localhost:26257,localhost:26258,localhost:26259
$ cockroach start --certs-dir=certs --store=rep-node5 --listen-addr=localhost:26261 --http-addr=localhost:8084 --join=localhost:26257,localhost:26258,localhost:26259

なるほど、 --join の値が変わってないけれどちゃんと追加されているみたいなのでいいんですね。
webuiの方に戻ると直ちにノードの追加が反映され、リバランスが働いているみたいです。
Overview画面が表示され、各ノードのReplicaの値が変わっている

大体2-3分でReplicaの値は落ち着きました。
リバランス後のOverview画面

// TODO: データを追加して、ノードを落としてみる

Discussion