先週 AWS ElastiCache for Redis を cache.m3.medium から
cache.m4.large にスケールアップしました。今後のためにメモを残して
おきます。

背景

cache.m3.medium を Multi-AZ + Replica 1 台構成で運用していた。主な
用途は Rails4 の Session Store サーバとして。

BytesUsedForCache が cache.m3.medium のメモリ 2.78 GiB を超え、
Evictions が発生し始めたため、cache.m4.large にスケールアップした。

タイムライン

メンテナンスウィンドウをセットした AM 3:00 になるとすぐに、当該ク
ラスターの Status が modifying になった。

AM 3:07 に Rails から接続できなくなり、Primary の CPUUtilization
が 60% 〜 90% で推移。Replica は普段通り。

AM 4:16 にようやく復帰。Multi-AZ 構成で冗長性が担保されているため、
データは消失しない。

感想

よくある質問 - Amazon ElastiCache|AWS

Q: 大きいノードタイプにスケールアップするにはどうすればよいですか?

(省略)スケールアッププロセスは、既存のデータをベストエフォートで
保持するように設計されており、Redis レプリケーションに成功する必要
があります。詳細については、こちら をご覧ください。

以前テストした時は、BytesUsedForCache が少ないインスタンスで試した
ため、ダウンタイムは数分であった。

長くても 30 分あれば終わると思っていたが、1 時間 9 分と想定以上か
かった。

また、Multi-AZ に期待しすぎていた節もあった。ElastiCache for Redis
の Multi-AZ は「冗長化」と「スケールアップや再起動をしてもデータが
全消失しない」程度に考えたほうが良さそう。

前述の「こちら」からの引用。

Redis スナップショットを作成するための十分なメモリがあることの確認

バージョン 2.8.22 以降の Redis のスナップショットと同期

Redis 2.8.22 で分岐なしの保存プロセスが導入されました。これにより、
同期および保存中にスワップを使用することなく、アプリケーションによ
り多くのメモリを割り当てて使用することができます。

今回のエンジンバージョンは 2.8.19。2.8.22 以上にしていれば、復帰時
間を早められたかもしれない。ただ、2.8.22 以上にする場合もダウンタ
イムは発生してしまう。

監視

CPUUtilization、BytesUsedForCache、Evictions あたりを監視すれば良
いことは分かっていたが、BytesUsedForCache は 2.78 GiB のうち、どこ
まで使えるか分からなかった。

今回の件で『使用できるキャッシュノードの種類 』に書かれたメモリサイ
ズを Redis にほぼそのまま使えることが分かった。残り 300 MiB とかに
なったら Warning 飛ばすとかで良さそう。

Evictions は通常 0 なので、0 より大きくなったら Warning で良い。
CPUUtilization は 98% 以上で Critical とかにした。

※ 今回の ElastiCache for Redis の用途はほぼ Session Store サーバな
ので、監視は緩め。

おまけ1

ElastiCache for Redis は Primary と Replica で Multi-AZ を構成する。
RDS は Primary 単体で Multi-AZ を構成できるので、知らないと勘違いする。

よって、料金は Primary + Replica x N しかかからない。Primary と
Replica は別々の Availability Zone にした方が良い。

参考: よくある質問 - Amazon ElastiCache|AWS

おまけ2

ElastiCache for Redis を使う以上、ダウンタイムを避けるのは難しそう。

DynamoDB を使うのはどうだろう?(以前この記事を見て試したことがある)

Rails4 でセッションストアに DynamoDB を使う | Developers.IO

DynamoDB ではインスタンスを立ち上げるわけではないので、メンテナン
スウィンドウからは逃れられる。スケールも考えなくて良い。

ただ、Session Store として使う場合、有効期限切れのレコードを消すの
が大変そう。ずっと持っていてもコストの無駄だし。

DynamoDBで有効期限切れのレコードを削除する - Qiita

DynamoDB は Session Store に使うにはオーバースペックかも。