Redis Cluster検証

# はじめに
他のRedis構築に関するページは以下をご参考ください。
[Redis構築のまとめ](https://qiita.com/ono-soic/items/d63ac849ebccee68b5bc)

# 環境
CentOS 6.8
Redis 3.2.5(当時の安定バージョン)

# 構成

| サーバ | IPアドレス | 役割 | ポート番号 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | master or slave | 6379
| redis02 | 192.168.56.112 | master or slave | 6379
| redis03 | 192.168.56.113 | master or slave | 6379
| redis04 | 192.168.56.114 | master or slave(redis01に紐づく) | 6379 
| redis05 | 192.168.56.115 | master or slave(redis02に紐づく) | 6379 
| redis06 | 192.168.56.116 | master or slave(redis03に紐づく) | 6379

# 現状わかったこと

| No | わかったこと | コメント |
|:--|:--|:--|
| 1 | 6台構成の場合、マスターが3台動いている状態でないといけない |   |
| 2 | あるマスターが落ちた時に昇格するスレーブは紐づけられていて、他のスレーブが昇格することはない | 2台落ちただけでもクラスタ構成が落ちる可能性がある |
| 3 | 昇格したスレーブが落ちるとクラスタ自体がダウンする。他にスレーブが残っていても昇格することはない<br><br>※昇格したスレーブ(例えばredis04)に紐づくサーバ(redis01)が復活していた場合は、それが再びマスターに昇格する | 同上 |
| 4 | ダウンしたサーバが復活すると再びクラスタ構成に組み込まれる<br>その際に下記のルールがある模様<br><br>1) 落ちる前の紐付け状態は保たれ続ける<br><br>2) 紐づけられているサーバが2台とも落ちている状態でスレーブが復活しても、マスターに昇格しない(クラスタはダウンしたまま)<br>→ダウンする前にマスターだったサーバが復活しない限り、クラスタ構成は戻らない<br><br>3) 紐づけられているサーバが2台とも落ちた時に両方がマスターに昇格していた場合、先に復活した方がマスターになり、後に復活した方がスレーブになる<br><br>4.1) マスター(例えばredis03)が落ちる→スレーブ(redis06)が昇格する→昇格したスレーブに紐づくマスター(03)が復活する→そのマスター(03)はスレーブとして扱われる<br><br>4.2) 上記にある通り全台落ちた後、紐づけられていて両方がマスターに昇格している2台と他のマスター1台が復活したとしても、紐づけられた片方がスレーブになってしまうのでクラスタ構成は戻らない | 構成を変えた場合の検証が必要 |
| 5.1 | setである値を設定したサーバが落ちると、<br>他のサーバでその値をgetすることができない(接続エラーになる)| 検証段階ではサーバが落ちるとそのサーバのデータが参照できなかった |
| 5.2 | マスターサーバが落ちて、スレーブに降格したサーバとして復活すると、スレーブでsetしていたデータがマスターに移る | マスターが落ちた場合、代わりに昇格したマスターが落ちたマスターのデータを保持していないといけないのでは？ |
| 6 | setでリダイレクトが発生する場合は必ずマスターへリダイレクトする。<br>スレーブでsetを行った場合、マスターにリダイレクトしてからsetの処理を行う | 理由はマスターにしかスロットが振られていないから |
| 7 | スレーブが落ちてもクラスタ構成に特に問題はない<br>ただしスレーブが落ちた状態で、スレーブに紐づけられたマスターが落ちるとクラスタが落ちる |
| 8 | 最低2台(紐づくマスター・スレーブ)・最高4台(スレーブ3台＋マスター1台)の同時停止でクラスタ全体が機能不全に陥る可能性がある |   |

# 検証項目
## 1. マスターが1台(redis01)を落ちた場合
落とした後 redis02に接続

```
192.168.56.112:6379> get num1
-> Redirected to slot [4980] located at 192.168.56.111:6379
Could not connect to Redis at 192.168.56.111:6379: Connection refused
not connected> get num1
```
接続が切れた

一旦exitして再度接続 

```
192.168.56.112:6379> set number 1
-> Redirected to slot [12299] located at 192.168.56.113:6379
OK
192.168.56.113:6379> get number
"1"
```
クラスタ構成を維持したまま動作した 

○ノード情報(ノード文字列は割愛)

```
192.168.56.112:6379>cluster nodes
192.168.56.115:6379 slave connected
192.168.56.111:6379 master,fail disconnected
192.168.56.112:6379 master 5461-10922
192.168.56.116:6379 slave connected
192.168.56.113:6379 master 10923-16383
192.168.56.114:6379 myself,master connected 0-5460
```
※master/slave,failになっていると落ちている

| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | マスター | マスター(停止)
| redis02 | 192.168.56.112 | マスター | マスター
| redis03 | 192.168.56.113 | マスター | マスター
| redis04 | 192.168.56.114 | スレーブ | マスター
| redis05 | 192.168.56.115 | スレーブ | スレーブ 
| redis06 | 192.168.56.116 | スレーブ | スレーブ

### 結果
redis01が落ちて、redis04がマスターに昇格。CLUSTERの動作は問題なし

## 2. マスターが2台(redis01-2)が落ちた場合
2台落とした後 redis03に接続

```
192.168.56.113:6379> set num10 10
(error) CLUSTERDOWN The cluster is down
192.168.56.113:6379> set num11 11
-> Redirected to slot [8616] located at 192.168.56.115:6379
OK
```
一回CLUSTERDOWNのメッセージが出たが、再度setを行うとクラスタ構成を維持したまま動作した(フェールオーバに時間がかったため？)

○ノード情報(最初のノード文字列は割愛)

```
192.168.56.112:6379 master,fail disconnected
192.168.56.113:6379 master 10923-16383
192.168.56.115:6379 myself,master connected 5461-10922
192.168.56.116:6379 slave connected
192.168.56.114:6379 master connected 0-5460
192.168.56.111:6379 master,fail disconnected
```

| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | マスター(停止) | マスター(停止)
| redis02 | 192.168.56.112 | マスター | マスター(停止)
| redis03 | 192.168.56.113 | マスター | マスター
| redis04 | 192.168.56.114 | スレーブ | マスター
| redis05 | 192.168.56.115 | スレーブ | マスター 
| redis06 | 192.168.56.116 | スレーブ | スレーブ

### 結果
redis01とredis02が落ちて、redis04とredis05がマスターに昇格
CLUSTERの動作は一瞬ダウンしたが、その後問題なし

# マスターが3台(redis01-3)が落ちた場合
落とした後 redis04に接続

```
192.168.56.114:6379> set num14 14
-> Redirected to slot [12557] located at 192.168.56.116:6379
OK
```
クラスタ構成を維持したまま動作した

○ノード情報(最初のノード文字列は割愛)

```
192.168.56.112:6379 master,fail disconnected
192.168.56.113:6379 master,fail disconnected
192.168.56.116:6379 myself,master connected 10923-16383
192.168.56.115:6379 master  connected 5461-10922
192.168.56.114:6379 master connected 0-5460
192.168.56.111:6379 master,fail disconnected
```

| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | マスター | マスター(停止)
| redis02 | 192.168.56.112 | マスター | マスター(停止)
| redis03 | 192.168.56.113 | マスター | マスター(停止)
| redis04 | 192.168.56.114 | スレーブ | マスター
| redis05 | 192.168.56.115 | スレーブ | マスター 
| redis06 | 192.168.56.116 | スレーブ | マスター

### 結果
redis01とredis02とredis03が落ちて、redis04とredis05とredis06がマスターに昇格
クラスタ構成は問題なし

# 4. マスターが1台落ちて、スレーブから昇格したマスターが落ちた場合

```
192.168.56.112:6379> cluster nodes #ノード文字列は割愛
192.168.56.116:6379 master connected 10923-16383
192.168.56.113:6379 slave  connected
192.168.56.114:6379 slave connected
192.168.56.115:6379 master 5461-10922
192.168.56.112:6379 myself,slave connected
192.168.56.111:6379 master disconnected 0-5460
192.168.56.112:6379> get num100
-> Redirected to slot [109] located at 192.168.56.114:6379
"100"
192.168.56.114:6379> get num100
"100" //ここで192.168.56.111をシャットダウン
192.168.56.114:6379> cluster nodes
192.168.56.116:6379 master connected 10923-16383
192.168.56.115:6379 master connected 5461-10922
192.168.56.114:6379 myself,master connected 0-5460
192.168.56.111:6379 master,fail disconnected
192.168.56.113:6379 slave connected
192.168.56.112:6379 slave connected
 
192.168.56.114:6379> shutdown
not connected> exit
[root@soic-redis02 ~]# redis-cli -h 192.168.56.112 -c
192.168.56.112:6379> get num100
-> Redirected to slot [109] located at 192.168.56.114:6379
Could not connect to Redis at 192.168.56.114:6379: Connection refused
not connected> exit
[root@soic-redis02 ~]# redis-cli -h 192.168.56.112 -c
192.168.56.112:6379> cluster nodes
192.168.56.116:6379 master 10923-16383
192.168.56.113:6379 slave connected
192.168.56.114:6379 master,fail disconnected 0-5460
192.168.56.115:6379 master connected 5461-10922
192.168.56.112:6379 myself,slave connected
192.168.56.111:6379 master,fail disconnected
192.168.56.112:6379> set num101 101
(error) CLUSTERDOWN The cluster is down
```
| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | マスター(停止) | マスター(停止)
| redis02 | 192.168.56.112 | スレーブ | スレーブ
| redis03 | 192.168.56.113 | スレーブ | スレーブ
| redis04 | 192.168.56.114 | マスター | マスター(停止)
| redis05 | 192.168.56.115 | マスター | マスター 
| redis06 | 192.168.56.116 | マスター | マスター

#### 結果
スレーブからマスターに昇格したサーバが落ちても、他のスレーブは昇格しない
そのためマスターが2台しか存在せず落ちる

# 5. スレーブが1台(redis01)落ちた場合
◯ノード情報

```
192.168.56.116:6379 myself,master connected 10923-16383
192.168.56.111:6379 slave,fail disconnected
192.168.56.112:6379 slave connected
192.168.56.115:6379 master connected 5461-10922
192.168.56.114:6379 master connected 0-5460
192.168.56.113:6379 slave connected
```

| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | スレーブ | スレーブ(停止)
| redis02 | 192.168.56.112 | スレーブ | スレーブ
| redis03 | 192.168.56.113 | スレーブ | スレーブ
| redis04 | 192.168.56.114 | マスター | マスター
| redis05 | 192.168.56.115 | マスター | マスター 
| redis06 | 192.168.56.116 | マスター | マスター

#### 結果
問題なく動作した

# 6. スレーブが2台(redis01, redis02)落ちた場合
◯ノード情報

```
192.168.56.111:6379 slave,fail disconnected
192.168.56.114:6379 master connected 0-5460
192.168.56.115:6379 myself,master 5461-10922
192.168.56.116:6379 master connected 10923-16383
192.168.56.112:6379 slave,fail disconnected
192.168.56.113:6379 slave connected
```

| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | スレーブ(停止) | スレーブ(停止)
| redis02 | 192.168.56.112 | スレーブ | スレーブ(停止)
| redis03 | 192.168.56.113 | スレーブ | スレーブ
| redis04 | 192.168.56.114 | マスター | マスター
| redis05 | 192.168.56.115 | マスター | マスター 
| redis06 | 192.168.56.116 | マスター | マスター

#### 結果
問題なく動作した

# 7. スレーブが3台落ちた場合

```
192.168.56.111:6379 slave,fail disconnected
192.168.56.113:6379 slave,fail disconnected
192.168.56.112:6379 slave,fail disconnected
192.168.56.116:6379 master connected 10923-16383
192.168.56.114:6379 myself,master 0-5460
192.168.56.115:6379 master connected 5461-10922
```

| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | スレーブ(停止) | スレーブ(停止)
| redis02 | 192.168.56.112 | スレーブ(停止) | スレーブ(停止)
| redis03 | 192.168.56.113 | スレーブ | スレーブ(停止)
| redis04 | 192.168.56.114 | マスター | マスター
| redis05 | 192.168.56.115 | マスター | マスター 
| redis06 | 192.168.56.116 | マスター | マスター

#### 結果
問題なく動作した

# 8. スレーブが1台(redis01)落ちて、それに紐付くマスターが1台(redis04)落ちた場合
#### 結果
控えのスレーブが落ちていると、それに紐づくマスターが落ちた際に他のスレーブは昇格しない

# 9. マスターが3台(redis01-3)落ちて、スレーブから昇格したマスターが1台(redis04)が落ちた場合 
そのためマスターが2台しか存在せず、落ちる(検証結果4と同じ)

落とした後、redis05から接続

```
192.168.56.115:6379> set num15 15
(error) CLUSTERDOWN The cluster is down
```
クラスタが完全にダウンした模様

○ノード情報

```
192.168.56.112:6379 master,fail disconnected
192.168.56.113:6379 master,fail disconnected
192.168.56.115:6379 myself,master connected 5461-10922
192.168.56.116:6379 master connected 10923-16383
192.168.56.114:6379 master,fail disconnected 0-5460
```

| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | マスター(停止) | マスター(停止)
| redis02 | 192.168.56.112 | マスター(停止) | マスター(停止)
| redis03 | 192.168.56.113 | マスター(停止) | マスター(停止)
| redis04 | 192.168.56.114 | マスター | マスター(停止)
| redis05 | 192.168.56.115 | マスター | マスター 
| redis06 | 192.168.56.116 | マスター | マスター

#### 結果
redis01-4がfail状態に、クラスタはダウンして機能しなくなる

# 10. マスターが3台(redis01-3)落ちて、スレーブから昇格したマスターが2台(redis04-5)落ちた場合
◯ノード情報

```
192.168.56.112:6379 master,fail disconnected
192.168.56.113:6379 master,fail disconnected
192.168.56.116:6379 myself,master connected 10923-16383
192.168.56.115:6379 master,fail? disconnected 5461-10922
192.168.56.114:6379 master,fail disconnected 0-5460
192.168.56.111:6379 master,fail disconnected
```

| サーバ | IPアドレス | 検証前 | 検証後 |
|:--|:--|:--|:--|
| redis01 | 192.168.56.111 | マスター(停止) | マスター(停止)
| redis02 | 192.168.56.112 | マスター(停止) | マスター(停止)
| redis03 | 192.168.56.113 | マスター(停止) | マスター(停止)
| redis04 | 192.168.56.114 | マスター | マスター(停止)
| redis05 | 192.168.56.115 | マスター | マスター(停止?) 
| redis06 | 192.168.56.116 | マスター | マスター

redis01-5がfail状態に、クラスタはダウンして機能しなくなる
(05はfail?となっている。クラスタが落ちるとfailかどうか判断できなくなる模様)

# 11. マスターが3台(redis01-3)が落ちて、スレーブから昇格したマスターが3台(redis04-6)が落ちた場合
#### 結果
全サーバからredisに接続できなくなる

# 12. 落としたサーバでsetした値をgetしようとする

```
192.168.56.111:6379> set num100 100
OK
192.168.56.111:6379> get num100
"100"
192.168.56.111:6379> shutdown
not connected> exit
[root@soic-redis05 ~]# redis-cli -h 192.168.56.115 -c
192.168.56.115:6379> get num100
-> Redirected to slot [109] located at 192.168.56.111:6379
Could not connect to Redis at 192.168.56.111:6379: Connection refused
not connected> exit
```
○Redirectedが起きた場合

```
192.168.56.114:6379> set num43 43
-> Redirected to slot [15903] located at 192.168.56.113:6379
OK
```
リダイレクトが起きた場合は「num43」が設定されているサーバはリダイレクト先の「192.168.56.113(redis03)」になる

#### 結果
redis01でnum100をsetしたが、redis01が落ちてしまうと別のサーバからgetすることはできない

# 13. redis03(192.168.56.113)でset num43を行った後、redis03を落とした場合	

```
192.168.56.111:6379> get num43
-> Redirected to slot [15903] located at 192.168.56.113:6379
Could not connect to Redis at 192.168.56.113:6379: Connection refused
not connected>
```
getすることはできなくなる

上で落ちたサーバーを再度復活させると

```
192.168.56.116:6379 myself,master connected 10923-16383
192.168.56.113:6379 slave connected
192.168.56.113がスレーブに降格して、192.168.56.116がマスターに昇格している
```
この後に再度113を落として上記で設定したnum43をgetしてみる

```
192.168.56.114:6379> get num43
-> Redirected to slot [15903] located at 192.168.56.116:6379
"43"
```
116にリダイレクトしてgetできるようになっている
→落ちてスレーブに降格したサーバが復活すると、スレーブのデータがマスターに移る

※この後再び116を落として「get num43」を実行したが接続エラーになったため、同期されているというより移動しているのではないかと考える