Redis-ClusterをGCPのインスタンスグループで構成する

GCP上でインスタンスグループを用いてRedis-Clusterを構成しようとしたところ、いろいろ詰まったので手順をメモしておく。

## VMインスタンスを作成する

### VM作成→コンソールを開くまで

テンプレート作成用のマシンを作成する。

GCPコンソールから「VMインスタンス」を開き、そこから「インスタンスの作成」を選択する。

ブートディスク設定から、OSとしてUbuntu 18.04 LTSを設定。ゾーンは東京に設定しておく。
ファイアウォール設定はこの時点では特になし、インスタンスタイプは適当に設定して作成する。

作成したインスタンスに対してSSH接続を行う。

### 最新版Redis(2022/07/05現在7.0.2)の導入

以下のコマンドで公式レポジトリから導入を行う。
```
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg 
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list 
sudo apt-get update
```
```
sudo apt-get install -y redis
```

ここまで行い、バージョンを確認する。

```
redis-server -v
```
これで現在の最新バージョン(2022/07/05現在7.0.2)を導入できていればOK。

参考

https://self-development.info/ubuntu-22-04-lts%E3%81%B8%E3%81%AE%E6%9C%80%E6%96%B0%E7%89%88redis%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/

### Redis.confの設定を行う

```
sudo vi /etc/redis/redis.conf
```
でコンフィグファイルを開く。

この内容からそれぞれ以下の点について書き換える。
#### バインド設定
redisがlistenするアドレスを設定する。ここでは0.0.0.0で設定するが、必要に応じてちゃんと設定すること。
```conf:redis.conf
bind 0.0.0.0
```

#### protected-mode
他のサーバーからのアクセスに関する設定。クラスター化にはnoを設定する必要がある。
```conf:redis.conf
protected-mode no
```
#### cluster-enabled
クラスター化に関する設定。yesに設定しておく。

```conf:redis.conf
cluster-enabled yes
```


#### オプション：Debugコマンド

redis-cliからdebugコマンドを使うための設定。必要がなければつけなくてよい。

```conf:redis.conf
enable-debug-command yes
```

### 設定したファイルを反映させる

```
sudo systemctl enable redis-server
sudo systemctl restart redis
```
これで設定ファイルが反映される...のだが、一つ罠がある。```var/lib/redis/nodes.conf```ファイルを見てみよう。
```
sudo cat /var/lib/redis/nodes.conf
```
以下のようなクラスターノード設定ファイルが作られている。
```conf:nodes.conf
185d8f59dbb200c00453c1f4e71b71c9f6cfbdc4 :0@0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0
```
これをテンプレートとして複数台のredisノードを作成したとき、この内容まで全てコピーされるため「全部が同じID」となってしまう。クラスター作成を行った時途中で動かなくなって```"Waiting for the cluster to join....."```というメッセージから進まないならこれが原因の可能性がある。


このため、一度このファイルを消した状態にしておく。
```
sudo systemctl stop redis
sudo rm -i /var/lib/redis/nodes.conf

rm: remove regular file '/var/lib/redis/nodes.conf'? yes
```

起動時にrestartされるので、その時にクラスターノード設定ファイルが自動で新しく作られる。


この点についての参考：

https://linux.m2osw.com/redis-infamous-waiting-cluster-join-message

## イメージ→テンプレートを作成する
### イメージの作成
ここまで設定したら、先ほど起動したVMを停止させる。

GCPコンソールからイメージ→イメージを作成を選択。ソースディスクから先ほどのVMを選択してイメージを作成する。

### インスタンステンプレートの作成

GCPコンソールからインスタンステンプレート→インスタンステンプレートの作成を選ぶ。
* Redisはメモリーの消費が多いのでN2-standardを選んでおく。ここは必要に応じて調整。
* ブートディスクとして、先ほど作成したイメージを選択しておく。
* ファイアウォールの「ネットワーキング」の部分に任意のタグを設定しておく。ここではredis-policyとしておく。

ここまで設定したら作成を押す。

### ファイアウォール設定

ポート開放を行う。先ほど設定したネットワークタグ(redis-policy)が機能するように設定を行う。

GCPコンソールの検索欄に「ファイアウォール」と入力。「ファイアウォール」を開き、「ファイアウォールルールを作成」を選ぶ。

* 任意の名前を設定する(ここは先ほどのタグ名とは別)。
* トラフィックの方向は「上り」
* ターゲットを「指定されたターゲットタグ」に設定し、ターゲットタグとして先ほど設定したタグの名前(redis-policy)を設定する。
* ソースフィルタとして「ソースタグ」を設定し、「ソースタグ」の欄に先ほどと設定したタグの名前(redis-policy)を設定する。
* プロトコルとポートはTCPの6379, 16379(デフォルト設定のredis-clusterに使用されるポート)の二つを設定する。

![rapture_20220705094522.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/708893eb-f6c6-1c08-dcf2-beccfaccc5b6.jpeg)

ここまで設定したら「作成」を押す。これでこの設定が(redis-policyタグをつけたマシンに)反映される。

## インスタンスグループを作成する

GCPコンソールから「インスタンスグループ」→「インスタンスグループを作成」を選択する。
* 先ほど設定したインスタンステンプレートを設定する
* ロケーションを「シングルゾーン」「東京」に設定しておく。
* 自動スケーリングを「オフ」にする。

この状態で作成を押す。

作成したインスタンスグループのページを開き、「edit」を押す。インスタンス数を適当に「4」と設定しておく。3台はクラスター作成用、1台はそれを操作するためのものとして扱ってみる。

## Redisクラスターを作成する

それぞれのマシンの内部IPアドレスをここで確認しておく。

![rapture_20220705095951.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/e881bc25-8a9f-5ec0-2476-db48e8287f8b.jpeg)



まずは適当な1台のVMにssh接続し、コンソールを開く。

### まずは繋がっていることを確認してみる

この一台から別のVM一台のredis-cliに接続してみる。以下のコマンドを打ってみる。

```
redis-cli -h <接続したいマシンの内部IP>
```

このコマンドでredisに接続できれば確認はOK。

### redis-clusterを作成する

以下のコマンドで3台のmasterからなるRedis-clusterを作成する。

```
redis-cli --cluster create <接続したいマシン1の内部IP>:6379 <接続したいマシン2の内部IP>:6379 <接続したいマシン3の内部IP>:6379
```
```
>>> Performing hash slots allocation on 3 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
M: f1c6e5de895d0beefd054e5f6b9da28e229cd478
   slots:[0-5460] (5461 slots) master
M: 2719dec111f249a1dfceab43bc4ee3bb2be4b252
   slots:[5461-10922] (5462 slots) master
M: d59e936be02c90af5b01f54ac3770e622c34b9a5
   slots:[10923-16383] (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): 
```
これでyesと入力して作成。これでRedis-Clusterの作成が完了した。

もしここで「Waiting for the cluster to join...」から進まなくなったらredisのidが3つすべて同一になってないか確認すること。(対処法は[先述](https://qiita.com/NNNiNiNNN/items/3c1b1597ff1f7642f06f#%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%9F%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%8F%8D%E6%98%A0%E3%81%95%E3%81%9B%E3%82%8B)。これでだいぶ詰まった)