Redisのクラスタリング

忘れそうなのでメモ。

## バージョン

```
redis_version:3.0.4
```


## 制限(引っかかった箇所)

* マスター3つ以上必要  
2つまでだとエラーでクラスタ作成できない。
* ノード削除はスロットを持たない場合でないとできない。  
`cluster reshard` で別マスタへ移動しておく必要がある。 ← テスト系でめんどい場合は `cluster reset` で。
* `cluster reset` はデータがあるとできない。  
あらかじめ `flushall` などで中身を飛ばしておく。
* エンドポイント指定はクライアントから見える必要がある。  
例えば開発環境で `127.0.0.1:7001` などと指定して別マシンからアクセスすると `MOVED` のエラーが出る。  
外部から認識されるIPとポートで指定する必要がある。


## 設定

必要なものだけ抜粋

```bash
appendonly          yes        # アペンドログ必須

cluster-enabled     yes
cluster-config-file nodes.conf # クラスタ状況を保存するファイル、開発など1台で複数立てる場合は個別にファイル作成
```


## init.d

https://gist.github.com/paulrosania/257849 ベース。
1サーバーで複数立てる場合は `rh_status_q` が邪魔するので、startとか書き換える必要がある。



## コマンド

redisをソースダウンロードした時の `src/redis-trib.rb` を使用する。
めんどいので↑だけどこかのbinにリンクを貼る。(移動して動くか未確認)
※開発環境しか組んでないので途中で追加とか削除とかしていません。

```bash
# ポート7001～7003のredisでクラスタ作成
# スロットは既定で16384個を適宜分散してくれる。
# あらかじめ3つ立てておくこと。
$ redis-trib.rb create --replicas 0 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003
>>> Creating cluster
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
>>> Performing hash slots allocation on 3 nodes...
Using 3 masters:
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
M: d510983e678bdba33a7039dd4d22ac8b90d32647 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 61910e138c5c2d793f7159a69b3a5b1f4baaa7f5 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: 32ec8ce4865fe0430b557e921e3870aab3bcc836 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes  # ← ここでyesを入力
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join.
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: d510983e678bdba33a7039dd4d22ac8b90d32647 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 61910e138c5c2d793f7159a69b3a5b1f4baaa7f5 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: 32ec8ce4865fe0430b557e921e3870aab3bcc836 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
```

```bash
# ポート7002～7006のredisでクラスタ+スレーブ作成
# --replicas はスレーブ数を指定、初期台数見て適宜マスター/スレーブを振るプランを提示してくる。
$ redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 ...途中略... 127.0.0.1:7006
>>> Creating cluster
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7006: OK
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
Adding replica 127.0.0.1:7006 to 127.0.0.1:7003
M: d510983e678bdba33a7039dd4d22ac8b90d32647 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 61910e138c5c2d793f7159a69b3a5b1f4baaa7f5 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: 32ec8ce4865fe0430b557e921e3870aab3bcc836 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
S: 8c010c600b53c39de85eeb3eaf96729cfbf8c5e3 127.0.0.1:7004
   replicates d510983e678bdba33a7039dd4d22ac8b90d32647
S: acec75627418db78c45b55ac0adee74e34afc91e 127.0.0.1:7005
   replicates 61910e138c5c2d793f7159a69b3a5b1f4baaa7f5
S: 83d54ce8ad560d9b4ff674b13daa4ce7e40178fd 127.0.0.1:7006
   replicates 32ec8ce4865fe0430b557e921e3870aab3bcc836
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join...
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: d510983e678bdba33a7039dd4d22ac8b90d32647 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 61910e138c5c2d793f7159a69b3a5b1f4baaa7f5 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: 32ec8ce4865fe0430b557e921e3870aab3bcc836 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
M: 8c010c600b53c39de85eeb3eaf96729cfbf8c5e3 127.0.0.1:7004
   slots: (0 slots) master
   replicates d510983e678bdba33a7039dd4d22ac8b90d32647
M: acec75627418db78c45b55ac0adee74e34afc91e 127.0.0.1:7005
   slots: (0 slots) master
   replicates 61910e138c5c2d793f7159a69b3a5b1f4baaa7f5
M: 83d54ce8ad560d9b4ff674b13daa4ce7e40178fd 127.0.0.1:7006
   slots: (0 slots) master
   replicates 32ec8ce4865fe0430b557e921e3870aab3bcc836
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
```

`add-node` とか `del-node` は今度書くかも。

## CLI

```bash
redis-cli -p 7001 -c
```

`-h` とか `-p` でクラスタのうちの1台を指定する、スレーブを宛先にしても問題ない。
`-c` はクラスタオプション、これを付ける付けないで他サーバーへの設定挙動が違う。

```bash
# -c付
$ redis-cli -p 7001 -c set testkey1 10
-> Redirected to slot [13567] located at 127.0.0.1:7004
OK

# -c無
$ redis-cli -p 7001 set testkey1 10
(error) MOVED 13567 127.0.0.1:7004
```