DockerでサクッとRethinkDBのクラスタを試す

# はじめに

Document型DBといえばMongoDBが定番ですが、ReplicationやShardingの構築かなり複雑です。一方RethinkDBはこれらがとても簡単にでき、私も徐々にMongoDBからRethinkDBにシフトしています。今回はDockerを使用してRethinkDBのクラスタ機能を構築して試してみます。

# 環境の準備

Dockerの環境を各自構築してください。私は普段はUbuntuを使用しているのでそのままインストールしました。

- OS: Ubuntu 14.04
- Docker: 1.9.1
- Dokcer Compose: 1.5.1 

WindowsやMac等を使用している方はVirtualBox(+Vagrant)等でCoreOSを立ちあげればすぐにDockerの環境が整います。もちろんUbuntu 14.04やCentos 7などのVMを作って自分でDockerを入れてもOKです。あとは[公式の手順](https://docs.docker.com/compose/install/)などを参考にDocker Composeをインストールしてください。

# クラスタの起動

## 構成

次のように`docker-compose.yml`を準備します。

```yaml:docker-compose.yml
seed:
    image: rethinkdb:2
    ports:
        - 8081:8080
    command: rethinkdb -n rethink_seed --bind all

worker:
    image: rethinkdb:2
    links:
        - seed:seed
    command: rethinkdb --bind all -j seed:29015

proxy:
    image: rethinkdb:2
    ports:
        - 8080:8080
    links:
        - worker:worker
    command: rethinkdb proxy --bind all -j worker:29015
```

`seed`は種となるノードでこれに`worker`ノードがつながってRethinkDBのクラスタを形成します。`-j`オプションで接続する他のRethinkDBのアドレスとポートを指定します。ここではDockerのlink機能を使用して`seed:29015`のように指定しています。`worker`はDocker Composeの`scale`を使用すれば複数のコンテナをすぐに起動できます。`proxy`というのは自身はデータを保存せず、クエリの転送や処理のみを行うノードです。こちらは`worker`に接続します。あとでブラウザから操作するので`seed`と`proxy`はそれぞれhttpのポートをホストにマッピングしています。

## 起動

以下のコマンドで`seed`のRethinkDBコンテナが立ち上がります。

```bash
$ docker-compose up -d seed
```

ブラウザで<http://host:8081>にアクセスしてください。hostはDockerのホストのIPアドレスです。直接Ubuntuなどにインストールしている場合は127.0.0.1になり、VirtualBoxを使用している場合はゲストVMのIPアドレスです。

管理画面が表示されました。

![Screenshot from 2015-12-02 00:38:08.png](https://qiita-image-store.s3.amazonaws.com/0/65444/7ba50edf-e3d6-96be-78b7-615edb3ec9a2.png)


Serversを見ると`rethink_seed`の1ノードだけいます。
![Screenshot from 2015-12-02 00:38:15.png](https://qiita-image-store.s3.amazonaws.com/0/65444/37623dd8-f187-e1f3-4b2a-579eabac59ae.png)


次に`worker`も立ち上げます。

```bash
$ docker-compose up -d worker
```

すぐにノードが１つ増えます。今度はserver nameを指定していないのでランダムに名前がついています。
![Screenshot from 2015-12-02 00:38:30.png](https://qiita-image-store.s3.amazonaws.com/0/65444/f49fc347-7f48-52ef-1643-20a87fb16ea0.png)


`worker`を4つに増やしてみましょう。

```bash
$ docker-compose scale worker=4
```

一瞬で5ノードのクラスタが出来ました。
![Screenshot from 2015-12-02 00:41:17.png](https://qiita-image-store.s3.amazonaws.com/0/65444/177f8f0e-3854-9f43-5828-cf193a32ad5a.png)

最後に`proxy`を立ち上げ、ブラウザで8080ポートにアクセスします。

```bash
$ docker-compose up -d proxy
```

`proxy`は4つの`worker`のうちのどれかにつながっておりますが、`proxy`からも5ノードが見えているのがわかります。ただし`proxy`自身はデータを持たないノードなのでノードは6つには増えません。
![Screenshot from 2015-12-02 00:44:40.png](https://qiita-image-store.s3.amazonaws.com/0/65444/37d6244b-7516-8abd-eeaa-a22e83c15321.png)

# DB,テーブル、データ

## DBとテーブルの作成

`proxy`の管理画面をブラウザで開き、Tablesのタブを開いてください。はじめはtestというDBのみが存在しています。
![Screenshot from 2015-12-02 00:49:52.png](https://qiita-image-store.s3.amazonaws.com/0/65444/1554a4df-9407-6fd8-299c-baf9f38f1292.png)


RethinkDBはブラウザからDBやテーブルを作成することができ、冗長化の設定もできます。*+Add Database*と書いてあるボタンを押し、`marvel`というDBを作成します。つぎにmarvelの*+Add Table*をクリックして`heroes`というテーブルを作ります。作成が完了するとheroesをクリックしてテーブルの管理画面に進めます。

![Screenshot from 2015-12-02 00:58:07.png](https://qiita-image-store.s3.amazonaws.com/0/65444/3b343e99-0d61-7937-428e-a272844f44a9.png)

最初は`rethink_seed`のみにデータが保存されるので*Sharding and replication*にある*Reconfigure*のボタンをクリックし、replicaとshardの数を設定します。例えばreplica=3, shard=2という設定にします。

![Screenshot from 2015-12-02 01:01:23.png](https://qiita-image-store.s3.amazonaws.com/0/65444/80273b2b-6480-0f84-851e-b61c60016ea9.png)

これでDBとテーブルの準備が完了しました。

## データ投入

Data Explorerタブをクリックし、テキストエリアに次のコマンドを入力してRUNボタンを押します。

```
r.db("marvel").table("heroes").insert([
  {
    "name": "Steve Rogers",
    "alias": "Captain America",
    "species": "Human",
    "affiliations": ["Avengers", "S.H.I.E.L.D"]
  },
  { 
    "name": "Tony Stark",
    "alias": "Iron Man",
    "species": "Human",
    "affiliations": ["Avengers", "Stark Industries", "Illuminati"]
  },
  { "name": "Matthew Murdock",
    "alias": "Daredevil",
    "species": "Human",
    "affiliations": ["Defenders", "Heroes for Hire"]
  },
  { "name": "Thor Ordinson",
    "species": "Asgardian",
    "affiliations": ["Avengers"]
  }
])
```

![Screenshot from 2015-12-02 01:19:08.png](https://qiita-image-store.s3.amazonaws.com/0/65444/986f7755-3e4a-ac46-c6ec-e24e4ca86824.png)

結果のJSONで**"inserted":4**となっていれば成功です。

最後に`seed`のノードからデータが入ったことと冗長性を確認します。以下のコマンドで4つ目のworkerを壊します。

```bash
$ docker-compose scale worker=3
```

Tableの状態を見るとshard1のreplicaが1つdisconnectedになってしまいました。

![Screenshot from 2015-12-02 01:35:31.png](https://qiita-image-store.s3.amazonaws.com/0/65444/34d3a02b-5d27-a36e-4be3-0bff1c989838.png)


この状態でData Explorerのテキストエリアに以下のクエリを入力し、RUNを押します。

```
r.db("marvel").table("heroes")
```

![Screenshot from 2015-12-02 01:35:54.png](https://qiita-image-store.s3.amazonaws.com/0/65444/d206a612-dd44-71e9-194b-f49598d4c294.png)

１つノードが欠損しても先ほど挿入した4つのデータが入っていることが確認できました。

# まとめ

RethinkDBを使えば非常に簡単にクラスタを組むことができます。MongoDBのクラスタを組むのに疲れてしまった人はぜひお試しください。