はじめに
CockroachDBはACIDトランザクションをサポートする分散型のSQLデータベースです。
ちなみにCockroachはゴキブリという意味です。
以下の"Get Started"を参考に、実際にCockroachDBをローカル(3ノード~5ノード)で動かしてみます。
なお、"Get Started"では以下の操作を実施することになります。
- CockroachDBのインストール
- ローカルクラスターを起動
- SQLの実行
- サンプルワークロードの実行
- Admin UIへのアクセス
- ノードをダウンさせてみる
- クラスターをスケール
- クラスターを停止
- CockroachDBのSQLを学ぶ
- テーブル一覧を表示
- テーブルを作成
- レコードを挿入
- インデックスを作成
- テーブルのインデックスを表示
- テーブルを検索
- レコードを更新
- レコードを削除
- テーブルを削除
環境
使用する環境は以下になります。
- CentOS 7.4
- CockroachDB v19.2.4
CockroachDBのインストール
Linux用のCockroachDBバイナリをダウンロードし展開します。
# wget -qO- https://binaries.cockroachdb.com/cockroach-v19.2.4.linux-amd64.tgz | tar xvz
cockroachコマンドをPATH(/usr/local/bin/)が通ったディレクトリにコピーします。
# cp -i cockroach-v19.2.4.linux-amd64/cockroach /usr/local/bin/
ローカルクラスターを起動
cockroach startコマンドを使用してローカルクラスターを開始します。
# cockroach start --insecure --store=node1 --listen-addr=localhost:26257 --http-addr=localhost:8080 --join=localhost:26257,localhost:26258,localhost:26259 --background
*
* WARNING: RUNNING IN INSECURE MODE!
*
* - Your cluster is open for any client that can access localhost.
* - Any user, even root, can log in without providing a password.
* - Any user, connecting as root, can read or write any data in your cluster.
* - There is no network encryption nor authentication, and thus no confidentiality.
*
* Check out how to secure your cluster: https://www.cockroachlabs.com/docs/v19.2/secure-a-cluster.html
*
*
* INFO: initial startup completed.
* Node will now attempt to join a running cluster, or wait for `cockroach init`.
* Client connections will be accepted after this completes successfully.
* Check the log file(s) for progress.
*
先ほどはnode1のノードを起動しました。続いてnode2, node3のノードを起動して、3台構成のクラスターを構成します。
# cockroach start --insecure --store=node2 --listen-addr=localhost:26258 --http-addr=localhost:8081 --join=localhost:26257,localhost:26258,localhost:26259 --background
# cockroach start --insecure --store=node3 --listen-addr=localhost:26259 --http-addr=localhost:8082 --join=localhost:26257,localhost:26258,localhost:26259 --background
次にcockroach initコマンドでクラスターの初期化を実行します。
コマンドはクラスター内の1台のノードに対して実行します。
# cockroach init --insecure --host=localhost:26257
Cluster successfully initialized
なお、各ノードの起動情報はログで出力されており、以下のように確認できます。
# grep 'node starting' node1/logs/cockroach.log -A 11
CockroachDB node starting at 2020-02-29 23:02:48.899689215 +0000 UTC (took 116.5s)
build: CCL v19.2.4 @ 2020/02/06 21:55:19 (go1.12.12)
webui: http://localhost:8080
sql: postgresql://root@localhost:26257?sslmode=disable
RPC client flags: cockroach <client cmd> --host=localhost:26257 --insecure
logs: /root/node1/logs
temp dir: /root/node1/cockroach-temp058344301
external I/O path: /root/node1/extern
store[0]: path=/root/node1
status: initialized new cluster
clusterID: 0bd03d0c-e836-4a84-9a18-85b540caa3e3
nodeID: 1
SQLの実行
CockroachDBの組み込みSQLクライアントを使用してクラスタに接続してみます。
# cockroach sql --insecure --host=localhost:26257
続いて、データベース作成、テーブル作成、レコード挿入、検索までを実行してみます。
root@localhost:26257/defaultdb> CREATE DATABASE bank;
CREATE DATABASE
Time: 13.496349ms
root@localhost:26257/defaultdb> CREATE TABLE bank.accounts (id INT PRIMARY KEY, balance DECIMAL);
CREATE TABLE
Time: 17.062985ms
root@localhost:26257/defaultdb> INSERT INTO bank.accounts VALUES (1, 1000.50);
INSERT 1
Time: 18.117957ms
root@localhost:26257/defaultdb> SELECT * FROM bank.accounts;
id | balance
+----+---------+
1 | 1000.50
(1 row)
Time: 1.435583ms
"\q"でクライアントを終了します。
root@localhost:26257/defaultdb> \q
次にnode2に接続して、同様にテーブルを検索してみます。
node1に接続したときと同じ結果が得られました。
cockroach sql --insecure --host=localhost:26258
root@localhost:26258/defaultdb> SELECT * FROM bank.accounts;
id | balance
+----+---------+
1 | 1000.50
(1 row)
Time: 12.707771ms
サンプルワークロードの実行
CockroachDBには、クライアントトラフィックをシミュレートするための多数のワークロードも組み込まれています。
まず、CockroachDBのワークロードmovrのデータセットをロードします。
# cockroach workload init movr 'postgresql://root@localhost:26257?sslmode=disable'
I200229 23:10:02.671365 1 workload/workloadsql/dataload.go:135 imported users (0s, 50 rows)
I200229 23:10:06.086413 1 workload/workloadsql/dataload.go:135 imported vehicles (3s, 15 rows)
I200229 23:10:06.179277 1 workload/workloadsql/dataload.go:135 imported rides (0s, 500 rows)
I200229 23:10:06.275984 1 workload/workloadsql/dataload.go:135 imported vehicle_location_histories (0s, 1000 rows)
I200229 23:10:06.375615 1 workload/workloadsql/dataload.go:135 imported promo_codes (0s, 1000 rows)
5分間ワークロードを実行します。
# cockroach workload run movr --duration=5m 'postgresql://root@localhost:26257?sslmode=disable'
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__total
300.0s 0 1389 4.6 4.1 3.4 6.0 31.5 46.1 addUser
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__total
300.0s 0 463 1.5 7.3 5.8 11.5 39.8 192.9 addVehicle
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__total
300.0s 0 443 1.5 10.1 8.9 17.8 39.8 62.9 applyPromoCode
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__total
300.0s 0 136 0.5 4.6 3.8 6.3 32.5 44.0 createPromoCode
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__total
300.0s 0 323 1.1 4.3 3.8 6.0 28.3 32.5 endRide
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__total
300.0s 0 87044 290.1 0.9 0.9 1.4 2.5 46.1 readVehicles
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__total
300.0s 0 1763 5.9 8.5 7.3 13.1 37.7 352.3 startRide
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__total
300.0s 0 4518 15.1 41.9 35.7 75.5 151.0 2818.6 updateActiveRides
_elapsed___errors_____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p95(ms)__p99(ms)_pMax(ms)__result
300.0s 0 96079 320.3 3.1 0.9 11.5 39.8 2818.6
Admin UIへのアクセス
CockroachDBのAdmin UIを使用すると、クラスターに関する各種情報を表示することができます。
Admin UIのURLは「http://localhost:8080」です。
[OVERVIEW]で、3つのノードが稼働していることが確認できます。
[METRICS]では、SQLクエリの実行状況のグラフなど、さまざまなダッシュボードを表示することができます。
ノードをダウンさせてみる
ノードに対してcockroach quitコマンドを実行して、ノードダウンをシミュレートします。
# cockroach quit --insecure --host=localhost:26259
ok
1ノードがダウンしていても、Admin UIを見るとSQLトラフィックが継続していることが確認できます。
[OVERVIEW]では1ノードがダウンしているので、LIVE NODESは"2"になっています。
最後に先ほどダウンさせたノードを起動させておきます。
cockroach start --insecure --store=node3 --listen-addr=localhost:26259 --http-addr=localhost:8082 --join=localhost:26257,localhost:26258,localhost:26259 --background
[OVERVIEW]ではLIVE NODESは"3"に戻ります。
クラスターをスケール
現在クラスターは3台のノードで構成されています。
このクラスターに2台のノードを追加します。
cockroach start --insecure --store=node4 --listen-addr=localhost:26260 --http-addr=localhost:8083 --join=localhost:26257,localhost:26258,localhost:26259 --background
cockroach start --insecure --store=node5 --listen-addr=localhost:26261 --http-addr=localhost:8084 --join=localhost:26257,localhost:26258,localhost:26259 --background
[OVERVIEW]ではLIVE NODESは"3"から"5"になっていることが確認できます。
最初はノード4と5のレプリカ数が少なっていますが、すぐに均等になりデータが自動的にリバランスされることがわかります。
クラスターを停止
クラスターを停止させるため、5台全てのノードをcockroach quitコマンドを実行します。
まず、最初にクラスターを構成させていた3台のノードを停止させてみます。
これらはすぐにコマンドが完了しノードが停止します。
cockroach quit --insecure --host=localhost:26257
cockroach quit --insecure --host=localhost:26258
cockroach quit --insecure --host=localhost:26259
最後の2台のノードでは、シャットダウンに時間がかかり、最終的にノードが強制的に停止します。
これは5台のノードのうち2ノードしか残っていないため、クラスターが動作しなくなるためです。
# cockroach quit --insecure --host=localhost:26260
W200229 23:57:53.934909 1 cli/start.go:1405 timed out; proceeding with hard shutdown
ok
# cockroach quit --insecure --host=localhost:26261
W200229 23:58:58.104645 1 cli/start.go:1405 timed out; proceeding with hard shutdown
ok
後でクラスターを再起動するには、ノードのデータストアを含むディレクトリからcockroach startコマンドを実行します。
クラスターを利用しない場合は、各ノードのディレクトリ(データストア)を削除します。
rm -rf node1 node2 node3 node4 node5
CockroachDBのSQLを学ぶ
参考URLとは違う操作になりますが、ワークロード作成時に使用したmovrデータベースを利用して試してみます。
また、操作が多かったので一部省略しています。
cockroach sql --insecure --host=localhost:26257 --database=movr
テーブル一覧を表示
root@localhost:26257/movr> SHOW TABLES;
table_name
+----------------------------+
promo_codes
rides
user_promo_codes
users
vehicle_location_histories
vehicles
(6 rows)
Time: 1.664515ms
テーブルを作成
root@localhost:26257/movr> CREATE TABLE drivers (
id UUID NOT NULL,
city STRING NOT NULL,
name STRING,
dl STRING UNIQUE,
address STRING,
CONSTRAINT "primary" PRIMARY KEY (city ASC, id ASC)
);
CREATE TABLE
Time: 16.162934ms
root@localhost:26257/movr> SHOW COLUMNS FROM drivers;
column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden
+-------------+-----------+-------------+----------------+-----------------------+--------------------------+-----------+
id | UUID | false | NULL | | {primary,drivers_dl_key} | false
city | STRING | false | NULL | | {primary,drivers_dl_key} | false
name | STRING | true | NULL | | {} | false
dl | STRING | true | NULL | | {drivers_dl_key} | false
address | STRING | true | NULL | | {} | false
(5 rows)
Time: 10.02457ms
レコードを挿入
root@localhost:26257/movr> INSERT INTO drivers VALUES
('c28f5c28-f5c2-4000-8000-000000000026', 'new york', 'Petee', 'ABC-1234', '101 5th Ave');
INSERT 1
Time: 21.626055ms
root@localhost:26257/movr> INSERT INTO drivers (name, city, dl, address, id) VALUES
('Adam Driver', 'chicago', 'DEF-5678', '201 E Randolph St', '1eb851eb-851e-4800-8000-000000000006');
INSERT 1
Time: 5.400835ms
root@localhost:26257/movr> INSERT INTO drivers VALUES
('8a3d70a3-d70a-4000-8000-00000000001b', 'seattle', 'Eric', 'GHI-9123', '400 Broad St'),
('9eb851eb-851e-4800-8000-00000000001f', 'new york', 'Harry Potter', 'JKL-456', '214 W 43rd St');
INSERT 2
Time: 6.377982ms
インデックスを作成
root@localhost:26257/movr> CREATE INDEX name_idx ON users (name DESC);
CREATE INDEX
Time: 393.752574ms
root@localhost:26257/movr> CREATE TABLE IF NOT EXISTS drivers (
id UUID NOT NULL,
city STRING NOT NULL,
name STRING,
dl STRING,
address STRING,
INDEX name_idx (name),
CONSTRAINT "primary" PRIMARY KEY (city ASC, id ASC)
);
CREATE TABLE
Time: 553.356µs
テーブルのインデックスを表示
root@localhost:26257/movr> SHOW INDEX FROM users;
table_name | index_name | non_unique | seq_in_index | column_name | direction | storing | implicit
+------------+------------+------------+--------------+-------------+-----------+---------+----------+
users | primary | false | 1 | city | ASC | false | false
users | primary | false | 2 | id | ASC | false | false
users | name_idx | true | 1 | name | DESC | false | false
users | name_idx | true | 2 | city | ASC | false | true
users | name_idx | true | 3 | id | ASC | false | true
(5 rows)
Time: 2.334076ms
テーブルを検索
root@localhost:26257/movr> SELECT name FROM users LIMIT 10;
name
+-------------------+
William Wood
Victoria Jennings
Tyler Dalton
Tony Ortiz
Tina Miller
Taylor Cunningham
Susan Morse
Steven Lara
Stephen Diaz
Sarah Wang DDS
(10 rows)
Time: 1.49566ms
レコードを更新
root@localhost:26257/movr> UPDATE promo_codes SET (description, rules) = ('EXPIRED', '{"type": "percent_discount", "value": "0%"}') WHERE expiration_time < '2019-01-22 03:04:05+00:00';
UPDATE 669
Time: 3m43.8256279s
レコードを削除
root@localhost:26257/movr> DELETE FROM promo_codes WHERE description = 'EXPIRED';
DELETE 669
Time: 42.330774ms
テーブルを削除
root@localhost:26257/movr> DROP TABLE drivers;
DROP TABLE
Time: 98.414047ms
参考