ElastiCache Redis Service Update をApply Service Updateにおまかせしないで俺が対処する方法

俺です。

このクソ記事に3~5minのダウンタイムあるって書いてたけど間違っていたので訂正してます.実際のダウンタイムはもっと短くprimary failoverにかかるじかんです。


くっそ昔に書いていま役に立つとは思ってなかった記事です。
elasticache-20210615-002(ServiceUpdateSeverity critical)適用時の、実ダウンタイムを短くするためのrougaiテクニックです。
老害テックがんばるぞ。

[ElastiCache Redis Self Service Update](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/Self-Service-Updates.html)通知を受けて興奮がさめやらない俺たちのためにメモを残します。

↓のこいつをポチらずElastiCache RedisのUpdateを行う方法です。
2019/10/11 2:17JST時点ではElastiCache Redis Multi-AZモードを俺俺Service Updateした内容を書いてます。Clusterは別日に書く力があれば多分書きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42755/4085a62b-3bfe-7f62-eb98-6287fedd3c9a.png)

Apply Service Updateを使うとローリングで適用されていきます。途中で停止することもできます。
が、Eventを眺めていないとどのノードにService Updateが適用されているのかわからずprimary failoverタイミングが読めません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42755/ba74cbea-ee38-5bb5-50db-19a8ba394df3.png)

failoverタイミングを制御する方法を検証した結果のメモを残しておきます。

# Multi-AZモードのRedisを俺俺Service Updateしてわかったこと

- Service UpdateはNode単位に適用される
- Service Update通知を受けたクラスタへ、新規ノードを追加するとup to dateなノードとして起動する


# ServiceUpdate をManual applyしたときに発生するダウンタイム

- 適用にかかる時間: 非ClusterモードのRedis cache.m4.largeで15分ぐらい。
- 完全なダウンタイム: primary failoverタイミング ~~3分ちょっと-(テストコマンド悪かったかもしれないので実際はただのfailoverと変わらず短いかも)~~


AWS ServiceUpdateに任せて、Update内に発生するfailoverタイミングを人が管理する必要ないなら、メンテいれて一斉applyでよいとおもいます。

ServiceUpdate中の確認方法

```
while :; do timeout 2 redis-cli -h redisnodename  info; date; sleep 1; done
```

### 記録

開始: 11:25:39
cluster ダウン発生 : 2021年  6月 22日 火曜日 11:40:31 JST Could not connect to 6379: Connection refused
復帰:2021年  6月 22日 火曜日 11:43:17 JST


メンテいれむずい、とかFalioverタイミングを任意のタイミングにしたいServiceUpdateの適用単位がノード単位であることに着目して以下の手順でいっちゃいましょう。

### やりかた

- 新規ノードを追加する(ServiceUpdate elasticache-20210615-002が適用されて起動します)
- Redisを新規ノードへPromote(failover)する
- 古いノードを消す


# CUI編

## ElastiCache Redis(non clustered mode)

- ElastiCache RedisClusterではない、Multi-AZ Redisのメンテ方法です。


```
$ aws elasticache describe-update-actions --service-update-name elasticache-20210615-002 --replication-group-ids hogehoge
{
    "UpdateActions": [
        {
            "ReplicationGroupId": "hogehoge",
            "ServiceUpdateName": "elasticache-20210615-002",
            "ServiceUpdateReleaseDate": "2021-06-21T17:00:00+00:00",
            "ServiceUpdateSeverity": "critical",
            "ServiceUpdateStatus": "available",
            "ServiceUpdateRecommendedApplyByDate": "2021-06-28T16:59:59+00:00",
            "ServiceUpdateType": "security-update",
            "UpdateActionAvailableDate": "2021-06-21T17:40:59.189000+00:00",
            "UpdateActionStatus": "not-applied",
            "NodesUpdated": "0/1",
            "UpdateActionStatusModifiedDate": "2021-06-21T17:40:59.191000+00:00",
            "SlaMet": "no",
            "EstimatedUpdateTime": "30 minutes per node",
            "Engine": "redis"
        }
    ]
}
```


### nodeの追加

- 3node化する

```
$ aws elasticache increase-replica-count  --replication-group-id hogehoge --new-replica-count 2 --apply-immediately
{
    "ReplicationGroups": [
        {
            "ReplicationGroupId": "hogehoge",
            "Description": "hogehoge",
            "GlobalReplicationGroupInfo": {},
            "Status": "available",
            "PendingModifiedValues": {},
            "MemberClusters": [
                "hogehoge-001",
                "hogehoge-002",
                "hogehoge-003"
            ],
```

- 新規replica nodeが稼働するとNodesUpdatedが更新される(この情報が表示されるのは時間かかる)

```
❯ aws elasticache describe-update-actions --service-update-name elasticache-20210615-002 --replication-group-ids hogehoge
{
    "UpdateActions": [
        {
            "ReplicationGroupId": "hogehoge",
            "ServiceUpdateName": "elasticache-20210615-002",
            "ServiceUpdateReleaseDate": "2021-06-21T17:00:00+00:00",
            "ServiceUpdateSeverity": "critical",
            "ServiceUpdateStatus": "available",
            "ServiceUpdateRecommendedApplyByDate": "2021-06-28T16:59:59+00:00",
            "ServiceUpdateType": "security-update",
            "UpdateActionAvailableDate": "2021-06-21T17:40:59.189000+00:00",
            "UpdateActionStatus": "not-applied",
★★★★            "NodesUpdated": "2/3",
            "UpdateActionStatusModifiedDate": "2021-06-21T17:40:59.191000+00:00",
            "SlaMet": "no",
            "EstimatedUpdateTime": "30 minutes per node",
            "Engine": "redis"
        }
    ]
}
```

### nodeのMulti-AZを有効化する

```
$ aws elasticache modify-replication-group --replication-group-id hogehoge --multi-az-enabled --automatic-failover-enabled
```

```
$ aws elasticache describe-replication-groups  --replication-group-id hogehoge
{ 
...省略
            "AutomaticFailover": "disabled",
            "MultiAZ": "enabled",
...省略
```

### elasticache-20210615-002未適用ノードを削除する

- 事前に別ノードをfailoverしてprimary化したい人は elasticache modify-replication-groupを叩けばOK
- このときのfailoverにかかる時間が実際のダウンタイムになります。


```
$ aws elasticache decrease-replica-count --replication-group-id hogehoge --replicas-to-remove hogehoge-001 --apply-immediately
```

### elasticache-20210615-002適用済みノードの確認をする

- クラスタ内のレプリケーションノードUpdatedがn/nならokです。


```
❯ aws elasticache describe-update-actions --service-update-name elasticache-20210615-002 --replication-group-ids hogehoge
{
    "UpdateActions": [
        {
            "ReplicationGroupId": "hogehoge",
            "ServiceUpdateName": "elasticache-20210615-002",
            "ServiceUpdateReleaseDate": "2021-06-21T17:00:00+00:00",
            "ServiceUpdateSeverity": "critical",
            "ServiceUpdateStatus": "available",
            "ServiceUpdateRecommendedApplyByDate": "2021-06-28T16:59:59+00:00",
            "ServiceUpdateType": "security-update",
            "UpdateActionAvailableDate": "2021-06-21T17:40:59.189000+00:00",
            "UpdateActionStatus": "complete",
            "NodesUpdated": "2/2",
            "UpdateActionStatusModifiedDate": "2021-06-22T03:55:34.041000+00:00",
            "SlaMet": "yes",
            "Engine": "redis"
        }
    ]
}
```

お疲れさまでした

# GUI編

## 検証に使ったElastiCache Redis

- ElastiCache Redis(Multi-AZ)
- Instance Type cache.t2.micro
- Engine Version Compatibility: v5.0.0

## 検証内容

1. Redisクラスタ内にReplica Nodeを追加する(旧ノード数分のReplica Nodeを追加する)
2. 古いReplica Nodeを消す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42755/4cd2a525-d201-ed7d-7545-ffa9369ab418.png)

3. failover primaryして[1]で追加したReplicaノードのいずれかをPrimaryにする
4. [3]でfailoverしてReplicaになったNodeを消す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42755/ff6ac794-cdd2-9720-68c3-f4108018886c.png)

5. Update Action Statusが `update available` から `up to date` になる

- 旧ノード削除前もしくは削除中
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42755/e3e314fc-1c7d-a5e7-bf1e-ee4041d19a93.png)


- 旧ノード削除後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42755/cdf903e6-0efc-ec32-5b92-bc3a7b0ad946.png)
6. 最高

良いフルマネージドサービスの俺ージドライフを!