CockroachDBをDocker環境上で動かし、クラスター内のサービス数を増やし、データをレプリカしてみる

# はじめに
![](https://www.cockroachlabs.com/docs/images/CL_Logo_Horizontal.png)

[CockroachDBをDocker Swarm環境上で動かし、高可用性と拡張性を試してみた](http://qiita.com/cyack2002/items/8ebefd18127d1ed3c51c)の続きです。
今回、CockroachDBクラスター内のサービス数を増やし、CockroachDBの機能にて、データが自動でレプリカされるかを確認します。

# 環境
- Windows7
- Vagrant V1.8.6
- VirtualBox V4.3.10
- Coreos-alpha V1465.0.0
- CockroachDB V1.05

# 1.CockroachDBクラスターの起動(1クラスター/1サービス)
- 1.1. CoreOSのダウンロード
-
```
C:\Users\IBM_ADMIN>mkdir vagrant_test
C:\Users\IBM_ADMIN>cd vagrant_test
C:\Users\IBM_ADMIN\vagrant_test>git clone https://github.com/coreos/coreos-vagrant/
```

- 1.2. CoreOSの起動
-
Vagrantfileにて、インスタンス数が1個であることを確認します。

```
$num_instances = 1
```

CoreOSのインスタンスを1つ起動します。vagrant global-statusコマンドを実行し、stateがrunningであることを確認します。

```
C:\Users\IBM_ADMIN\vagrant_test>cd coreos-vagrant
C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant>vagrant up
Bringing machine 'core-01' up with 'virtualbox' provider...
(省略)
PS C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant> vagrant global-status
id       name        provider   state    directory
--------------------------------------------------------------------------------------
81ef246  core-01     virtualbox running  C:/Users/IBM_ADMIN/vagrant_test/coreos-vagrant
```

- 1.3. Teraterm plugin導入と起動
-
```
C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant>vagrant plugin install vagrant-teraterm
C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant>vagrant teraterm core-01
```

- 1.4. CockroachDBのDockerイメージのダウンロード
-
起動させたTeratermから下記コマンドを実行します。CockroachDBは、執筆時点での最新版V1.0.5を使用します。

```
core@core-01 ~ $ sudo -s
core-01 core # docker pull cockroachdb/cockroach:v1.0.5
v1.0.5: Pulling from cockroachdb/cockroach
cd0a524342ef: Pull complete
6cf552a06a24: Pull complete
0d5d5f6dea12: Pull complete
Digest: sha256:9db5df93d2e453ec8c6b78a944a647ade3d63a96f840cb570a0158ea11a5a883
Status: Downloaded newer image for cockroachdb/cockroach:v1.0.5
core-01 core # docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
cockroachdb/cockroach   v1.0.5              810ca9af6e1b        12 days ago         163MB
```

- 1.5. ブリッジネットワークの作成
- 
1つのCoreOSインスタンス上に複数のDockerコンテナーを起動し、1つのDockerコンテナー上に1つのCockroachDBを稼働させます。
最初に、複数のDockerコンテナー間で通信するために、roachnetという名前のブリッジネットワークを作成します。

```
core-01 core #  docker network create -d bridge roachnet
dfbe9d0ca6e76fdd8738d945ea34f4d4d9726294b428b80bf14fd1e618741b37
core-01 core # docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
725d01be8b96        bridge              bridge              local
da1a8876cfd5        host                host                local
94a03f6842f0        none                null                local
dfbe9d0ca6e7        roachnet            bridge              local
```

- 1.6. CockroachDBクラスターの起動
-
Dockerコンテナーノード上に、CockroachDBクラスターを起動します。
pullしたCockroachのDockerイメージを指定し、Dockerコンテナーを起動します。
コンテナー名はroach1、コンテナーホスト名はroach1とします。
他と通信するために26257ポート(=CockroachDB用)と8080ポート(=Admin UI用)をフォワードします。
コンテナー上の/cockroach/cockroach-dataを、ホストOS上の${PWD}/cockroach-data/roach1にマウントします。
動かしてみるのが目的ですので、InsecureモードでCockroachDBを起動します。

```
core-01 core # docker run -d \
--name=roach1 \
--hostname=roach1 \
--net=roachnet \
-p 26257:26257 -p 8080:8080  \
-v "${PWD}/cockroach-data/roach1:/cockroach/cockroach-data"  \
cockroachdb/cockroach:v1.0.5 start --insecure \
--store=repdemo-node1
```

# 2. データの書き込みと確認
- 2.1. サンプルデータベースの作成
-
コンテナー名:roach1から、cockroach gemコマンドとcockroach sqlコマンドを実行し、製品で用意されているサンプルのデータベースを作成します。

```
core-01 core # docker exec -it roach1 bash
root@roach1:/cockroach# ./cockroach gen example-data intro | ./cockroach sql --insecure
CREATE DATABASE
SET
DROP TABLE
CREATE TABLE
INSERT 1
INSERT 1
(省略)
root@roach1:/cockroach# exit
```

- 2.2.  Cockroachサンプルデータベースの確認
-
コンテナー名:roach1から、サンプルのデータベースの中身を確認します。

```
core-01 core # docker exec -it roach1 ./cockroach sql --insecure
# Welcome to the cockroach SQL interface.
# All statements must be terminated by a semicolon.
# To exit: CTRL + D.
root@:26257/> SHOW DATABASES;
+--------------------+
|      Database      |
+--------------------+
| crdb_internal      |
| information_schema |
| intro              |
| pg_catalog         |
| system             |
+--------------------+
(5 rows)
root@:26257/> SHOW TABLES FROM intro;
+---------+
|  Table  |
+---------+
| mytable |
+---------+
(1 row)
root@:26257/> 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)
root@:26257/> \q
```

- 2.3. データのレプリカ確認
- 
データのレプリカ状況を確認します。Webブラウザから、ホストオンリーアダプターのIPアドレスを指定し、http://(IPアドレス):8080/にアクセスします。[View nodes list]を選択し、roach1が登録されていることを確認します。
![17.jpg](https://qiita-image-store.s3.amazonaws.com/0/199531/e3f3486e-8b31-b6f7-baaa-bb0b405cf2eb.jpeg)

ここまで、下図のようになっています。
![16.jpg](https://qiita-image-store.s3.amazonaws.com/0/199531/6621e7ea-466b-50a1-7d6e-4f0b96be52f9.jpeg)

# 3. CockroachDBクラスターの起動(1クラスター/3サービス)

- 3.1. CockroachDBクラスターの起動(1クラスター/3サービス)
- 
1で作成したCockroachDBクラスターに、別のDockerコンテナーノード上(=roach2)のCockroachDBを追加します。
pullしたCockroachのDockerイメージを指定し、Dockerコンテナーを起動します。
コンテナー名はroach2、コンテナーホスト名はroach2とします。
コンテナー上の/cockroach/cockroach-dataを、ホストOS上の${PWD}/cockroach-data/roach2にマウントします。
動かしてみるのが目的ですので、InsecureモードでCockroachDBを起動し、コンテナー名:roach1上のCockroachDBにジョインします。

```
core-01 core # docker run -d \
--name=roach2 \
--hostname=roach2 \
--net=roachnet \
-v "${PWD}/cockroach-data/roach2:/cockroach/cockroach-data" \
cockroachdb/cockroach:v1.0.5 start --insecure \
--store=repdemo-node2 \
--port=26258 \
--http-port=8081 \
--join=roach1

core-01 core # docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                              NAMES
ad90eb659699        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   15 seconds ago      Up 15 seconds        8080/tcp, 26257/tcp                                roach2
0b003551961c        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   About an hour ago   Up About an hour    0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   roach1
```

1で作成したCockroachDBクラスターに、別のDockerコンテナーノード上(=roach3)のCockroachDBを追加します。
pullしたCockroachのDockerイメージを指定し、Dockerコンテナーを起動します。
コンテナー名はroach3、コンテナーホスト名はroach3とします。
コンテナー上の/cockroach/cockroach-dataを、ホストOS上の${PWD}/cockroach-data/roach3にマウントします。
動かしてみるのが目的ですので、InsecureモードでCockroachDBを起動し、コンテナー名:roach1上のCockroachDBにジョインします。

```
core-01 core # docker run -d \
--name=roach3 \
--hostname=roach3 \
--net=roachnet \
-v "${PWD}/cockroach-data/roach3:/cockroach/cockroach-data" \
cockroachdb/cockroach:v1.0.5 start --insecure \
--store=repdemo-node3 \
--port=26259 \
--http-port=8082 \
--join=roach1

core-01 core # docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                              NAMES
3b5949a85c96        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   16 seconds ago      Up 16 seconds       8080/tcp, 26257/tcp                                roach3
ad90eb659699        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   3 minutes ago       Up 3 minutes        8080/tcp, 26257/tcp                                roach2
0b003551961c        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   About an hour ago   Up About an hour    0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   roach1
```

- 3.2. データのレプリカ確認(レプリカ数=3)
- 
データのレプリカ状況を確認します。Webブラウザから、ホストオンリーアダプターのIPアドレスを指定し、http://(IPアドレス):8080/にアクセスします。[View nodes list]を選択し、roach2とroach3が登録され、データがレプリカされていることを確認します。
![18.jpg](https://qiita-image-store.s3.amazonaws.com/0/199531/76c71b00-94f7-dc41-d3d0-95b1ba668908.jpeg)

CockroachDBは、デフォルトでデータのレプリカ数が3(=num_replicas: 3)に設定されています。

```
core-01 core # docker exec -it roach1 ./cockroach zone get .default --insecure
.default
range_min_bytes: 1048576
range_max_bytes: 67108864
gc:
  ttlseconds: 86400
num_replicas: 3
constraints: []
```

従いまして、下図のように、均等にroach2とroach3にデータがレプリカされます。
![19.jpg](https://qiita-image-store.s3.amazonaws.com/0/199531/1bbbd9a8-fb3d-5d76-bce2-fa6545d32fbf.jpeg)




# 4. CockroachDBクラスターの起動(1クラスター/3サービス/3レプリカ)

- 4.1. CockroachDBクラスターの起動(1クラスター/5サービス/)
- 
1で作成したCockroachDBクラスターに、別のDockerコンテナーノード上(=roach4、roach5)のCockroachDBを追加します。

```
core-01 core # docker run -d \
--name=roach4 \
--hostname=roach4 \
--net=roachnet \
-v "${PWD}/cockroach-data/roach4:/cockroach/cockroach-data" \
cockroachdb/cockroach:v1.0.5 start --insecure \
--store=repdemo-node4 \
--port=26260 \
--http-port=8083 \
--join=roach1

core-01 core # docker run -d \
--name=roach5 \
--hostname=roach5 \
--net=roachnet \
-v "${PWD}/cockroach-data/roach5:/cockroach/cockroach-data" \
cockroachdb/cockroach:v1.0.5 start --insecure \
--store=repdemo-node5 \
--port=26261 \
--http-port=8084 \
--join=roach1
```

- 4.2. データのレプリカ確認(レプリカ数=3)
- 
データのレプリカ状況を確認します。Webブラウザから、ホストオンリーアダプターのIPアドレスを指定し、http://(IPアドレス):8080/にアクセスします。[View nodes list]を選択し、roach4とroach5が登録され、データがレプリカされていることを確認します。
![20.jpg](https://qiita-image-store.s3.amazonaws.com/0/199531/0afe12a9-6153-8408-b99e-6ceded3858a0.jpeg)

現在、データのレプリカ数が3(=num_replicas: 3)に設定されていますので、下図のように、roach4とroach5にもデータがレプリカされます。
最初のデータ量を10とすると、3つレプリカされて合計のデータ量が30になります。この30を5つのCockroachサービスで保持しています。
![21.jpg](https://qiita-image-store.s3.amazonaws.com/0/199531/b78128e8-f6a4-41c9-a116-bb26c6b7b48c.jpeg)

- 4.3. データのレプリカ数の変更
-
データのレプリカ数を3から5(=num_replicas: 5)に増やします。

```
core-01 core # docker exec -it roach1 bash
root@roach1:/cockroach# echo 'num_replicas: 5' | ./cockroach zone set .default --insecure -f -
range_min_bytes: 1048576
range_max_bytes: 67108864
gc:
  ttlseconds: 86400
num_replicas: 5
constraints: []
```

- 4.4. データのレプリカ確認(レプリカ数=5)
- 
データのレプリカ状況を確認します。Webブラウザから、ホストオンリーアダプターのIPアドレスを指定し、http://(IPアドレス):8080/にアクセスします。[View nodes list]を選択し、データがレプリカされていることを確認します。
![22.jpg](https://qiita-image-store.s3.amazonaws.com/0/199531/71f25258-558f-8926-29fa-7b1babb7bddb.jpeg)

現在は、サービス数=5、レプリカ数=5ですので、下図のように均等にデータがレプリカされています。
![23.jpg](https://qiita-image-store.s3.amazonaws.com/0/199531/cbb3471a-cc8c-2675-13d2-eb5654cf3d59.jpeg)


# 5. CockroachDBクラスターの停止

最後に、コンテナ名を指定し、Dockerコンテナーを停止します。

```
core-01 core # docker stop roach1 roach2 roach3 roach4 roach5
```


# まとめ
CockroachDBのデータレプリカを確認してみました。CockroachDBクラスターのサービス数もレプリカ数も、自由自在に増減できそうです。
データベースであっても、Active-Activeの構成を選択できそうです。そして、それらの管理は製品機能で実施してくれるので、運用を気にしないで済む(=軽減される)。(安易で申し訳ないのですが)マイクロサービスのアーキテクチャーを(ACID特性が求められる)データベースでも実現できる世界は近いかも知れません。

# 参考
[Data Replication](https://www.cockroachlabs.com/docs/stable/demo-data-replication.html)
[Qiita:Cockroach関連記事 1.CockroachDBをDocker環境上で動かしてみる](http://qiita.com/cyack2002/items/18d6ad3bdc95eee8fec7)
[Qiita:Cockroach関連記事 2.CockroachDBをDocker環境上で動かし、サンプルデータベースをselectして、ぎょっとする](http://qiita.com/cyack2002/items/3d6500e0b8ace85cadf0)
[Qiita:Cockroach関連記事 3.CockroachDBをDocker Swarm環境上で動かし、高可用性と拡張性を試してみた](http://qiita.com/cyack2002/items/8ebefd18127d1ed3c51c)