LoginSignup
32
22

More than 3 years have passed since last update.

CockroachDBのチュートリアルをやってみる

Posted at

はじめに

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つのノードが稼働していることが確認できます。

image.png

[METRICS]では、SQLクエリの実行状況のグラフなど、さまざまなダッシュボードを表示することができます。

image.png

ノードをダウンさせてみる

ノードに対してcockroach quitコマンドを実行して、ノードダウンをシミュレートします。

# cockroach quit --insecure --host=localhost:26259
ok

1ノードがダウンしていても、Admin UIを見るとSQLトラフィックが継続していることが確認できます。

image.png

[OVERVIEW]では1ノードがダウンしているので、LIVE NODESは"2"になっています。

image.png

最後に先ほどダウンさせたノードを起動させておきます。

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"に戻ります。

image.png

クラスターをスケール

現在クラスターは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"になっていることが確認できます。

image.png

最初はノード4と5のレプリカ数が少なっていますが、すぐに均等になりデータが自動的にリバランスされることがわかります。

image.png

クラスターを停止

クラスターを停止させるため、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

参考

32
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
22