Amazon ElastiCache for Valkeyのdurabilityの効果を実際にフェイルオーバーを起こして検証してみた
こんにちは。サービス開発室の武田です。
2026年6月2日、Amazon ElastiCache for Valkeyがdurability(永続性)をサポートしました。Multi-AZのトランザクションログにデータを永続化することで、キャッシュでありながら「データが消えない」という選択肢が増えたアップデートです。
機能の概要、sync/asyncの2つのオプション、制限事項、パフォーマンス特性については、すでに大栗がまとめています。全体像はこちらをご覧ください。
今回はその先、つまり「ACKされた書き込みは、フェイルオーバーが起きても本当に消えないのか」を確かめます。書き込み中のクラスターにフェイルオーバーを起こし、OK応答を受け取った書き込みを1件ずつ照合します。合わせて、アプリケーションから見た書き込み停止時間や、sync ⇔ asyncのオンライン切り替えの挙動も検証します。
検証の設計
durabilityの価値は「ACKされた書き込みは障害が起きても消えない」ことに尽きます。これを確認するため、次のように検証を設計しました。
- 連番付きキーを毎秒約100件のペースで書き込み続ける
- 書き込み中に
test-failoverAPIでフェイルオーバーを発生させる - クライアントが OK応答を受け取った(ACK済みの)書き込みだけ を記録しておく
- フェイルオーバー完了後、ACK済みの全キーをプライマリから読み取り、欠落がないか照合する
ポイントは3です。タイムアウトや接続エラーになった書き込みは「ACKされていない」ので照合対象から外します。durabilityが保証するのはあくまでACK済みの書き込みだからです。
なお、この検証で確認できるのは「test-failoverによる計画的フェイルオーバー条件下で欠落しないこと」です。AZ障害や複数同時障害まで含めた証明ではありません。とはいえ、従来のElastiCacheではこの条件でも直近の書き込みが消え得たので、違いを確かめる意味は十分あります。
検証環境
| 項目 | 内容 |
|---|---|
| クラスター | cache.m6g.large × 2(1シャード、プライマリ + レプリカ)、Valkey 9.0、durability sync |
| 配置 | プライマリ: ap-northeast-1a / レプリカ: ap-northeast-1c(東京リージョン) |
| クライアント | EC2 t4g.micro(Amazon Linux 2023)、valkey-cli 9.0.4、redis-py 7.0.1 |
ノードタイプは、durability対応ファミリー(R7g / R6g / M7g / M6g / C7gn)のうち最安のcache.m6g.largeを選びました。syncはノード料金に18%の追加料金がかかり、2ノードで約$0.36/時間(東京リージョン、2026年6月3日時点)です。
クラスター作成はCLIで
コンソールでの作成手順は大栗の記事にあるので、こちらはCLIで作成します。create-replication-groupに--durability syncを付けるだけです。
1点だけ前提があります。--durabilityパラメーターは発表と同時にリリースされた次のバージョン以降でないと使えません。
- AWS CLI v2: 2.34.59以降
- AWS CLI v1: 1.45.20以降
- botocore: 1.43.20以降
手元のCLIが古いとUnknown options: --durabilityになるので、先にアップデートしておきます。
aws elasticache create-replication-group \
--replication-group-id valkey-durability-test \
--replication-group-description "Valkey durability sync test" \
--engine valkey \
--engine-version 9.0 \
--cache-node-type cache.m6g.large \
--num-node-groups 1 \
--replicas-per-node-group 1 \
--cluster-mode enabled \
--multi-az-enabled \
--automatic-failover-enabled \
--transit-encryption-enabled \
--cache-subnet-group-name valkey-durability-test-subnet \
--security-group-ids sg-xxxxxxxxxxxxxxxxx \
--durability sync
レスポンスには要求値のDurabilityと実効値のEffectiveDurabilityが含まれます。作成完了まで約18分でした。
{
"ReplicationGroup": {
"ReplicationGroupId": "valkey-durability-test",
"Status": "creating",
"Engine": "valkey",
"Durability": "sync",
"EffectiveDurability": "sync"
}
}
ちなみに作成後、INFO persistenceを見るとaof_enabled:0でした。エンジン側のAOF(Append Only File)は使われていません。durabilityはValkeyエンジンの外側、ElastiCacheのインフラ側のMulti-AZトランザクションログで実現されていることが分かります。
検証1: フェイルオーバーでACK済みの書き込みは残るか
本題です。検証クライアント(redis-pyのクラスターモード + TLS)で連番キーを書き込み続けながら、フェイルオーバーを実行します。
aws elasticache test-failover \
--replication-group-id valkey-durability-test \
--node-group-id 0001
イベントログを見ると、フェイルオーバー自体は約19秒で完了しています。
04:04:22 UTC | Test Failover API called for node group 0001
04:04:41 UTC | Failover to replica node valkey-durability-test-0001-002 completed
フェイルオーバー完了後、ACK済みの全キーを新しいプライマリから読み取って照合した結果がこちらです。
| 項目 | 結果 |
|---|---|
| ACK済み書き込み | 9,342件 |
| フェイルオーバー後に欠落していたキー | 0件 |
| 値が壊れていたキー | 0件 |
ACK済みの書き込みは1件も失われませんでした。
この検証はクライアント実装を変えて2回実施しており、2回目はACK済み20,303件に対して欠落ゼロでした。合計すると、2回のフェイルオーバーでACK済み書き込み29,645件、欠落0件です。
検証2: フェイルオーバー中、アプリケーションの書き込みは何秒止まるか
データが消えないことは分かりました。次に気になるのは「フェイルオーバー中、アプリケーションはどれくらい書き込めなくなるのか」です。エラー時に再接続するロジックを入れたクライアントで計測しました。
結果のタイムラインです(フェイルオーバーAPI実行時刻を0秒とする)。
| 時刻 | イベント |
|---|---|
| -76秒 | 書き込み開始(正常に書き込み続ける) |
| +3.5秒 | 最初の接続エラー(旧プライマリがシャットダウンされ接続拒否) |
| +21.0秒 | 書き込み回復(新プライマリへの接続確立) |
| 項目 | 結果 |
|---|---|
| 書き込み試行 | 20,331件 |
| ACK成功 | 20,303件(99.86%) |
| エラー | 28件 |
| アプリケーションから見た書き込み停止時間 | 約17.5秒 |
書き込みが止まるのは約17.5秒で、イベントログ上のフェイルオーバー所要時間(約17秒)とほぼ一致します。この間のエラーはわずか28件で、再接続後は元どおり書き込みが続きました。
クライアント実装で復帰時間は大きく変わる
実は1回目の検証では、雑な再接続ロジックのクライアントを使っていたため、フェイルオーバー後に クライアントが復帰できない 状態になりました。クラスタートポロジーの変更にクライアントが追従できなかったためです。
| クライアント実装 | フェイルオーバー後の挙動 |
|---|---|
| リトライ無効 + 接続エラー時のみ再接続 | 復帰できず、エラーが出続けた |
| どのエラーでも再接続 | 17.5秒で自動復帰 |
もうひとつ注意点があります。test-failover完了イベントの後も、旧プライマリがレプリカとしてクラスターに再参加するまで時間がかかります(今回の検証では約7分)。この間、AWS APIのステータスはavailableに戻っていても、当該ノードはエンジンレベルでcluster_state:failを返します。そのため、全ノードの正常性を前提にするクライアント初期化(redis-pyのrequire_full_coverage=Trueなど)は失敗します。
サーバー側がdurabilityでデータを守ってくれても、アプリケーションが復帰できなければ意味がありません。クラスターモード対応クライアントの再接続・リトライ設定は必ず確認しておきましょう。
検証3: sync ⇔ asyncのオンライン切り替え
durabilityの有効/無効は作成後に変更できませんが、syncとasyncの切り替えは可能です。切り替え中に何が起きるのか確かめました。
aws elasticache modify-replication-group \
--replication-group-id valkey-durability-test \
--durability async \
--apply-immediately
切り替え中、30秒ごとにステータス確認と書き込みを行った結果です。
EffectiveDurabilityがsyncからasyncに変わるまで 約50秒- 切り替え中もクラスターのステータスは
availableのまま - 切り替え中も書き込みは成功し続けた(ダウンタイムなし)
modify直後のレスポンスではEffectiveDurability: syncのままで、少し遅れてasyncに切り替わります。要求値(Durability)と実効値(EffectiveDurability)が分かれているのはこのためです。
アプリケーションを停止せずにオンラインで切り替えられるので、「まずsyncで運用してみて、書き込みレイテンシー要件が厳しければasyncに落とす」という運用ができます。
参考までに、同一条件(同時接続10、value 100バイト、TLS)でのvalkey-benchmarkの結果も載せておきます。クライアントがt4g.microなので絶対値は参考程度に見てください。
| SET(書き込み) | sync | async |
|---|---|---|
| p50 | 3.29ms | 0.26ms |
| p99 | 4.40ms | 0.52ms |
| GET(読み取り) | sync | async |
|---|---|---|
| p50 | 0.22ms | 0.25ms |
| p99 | 0.42ms | 0.50ms |
書き込みはsyncで約12倍のレイテンシー(それでも1桁ミリ秒)、読み取りはsync/asyncで差なし、という公式の説明どおりの結果でした。
CloudWatchメトリクスの実値
durableクラスター向けに追加された2つのメトリクスも確認しました。
| メトリクス | 内容 | 検証中の値 |
|---|---|---|
| DurabilityLag | ACK済みだがまだ永続化されていない最古の書き込みの経過時間 | 0ms(syncは書き込み時点で永続化済みのため常に0) |
| DurabilityBufferExceededErrorCount | 10秒バッファ超過による書き込み拒否回数 | 0 |
asyncで運用する場合は、DurabilityLagが10,000ms(10秒)に近付いていないかを監視しておきましょう。10秒に達するとプライマリは新しい書き込みを拒否し始めます。また書き込みトラフィックがトランザクションログのスループットを超えると、TrafficManagementActiveメトリクスが1を出力します。
この機能で守れるもの・守れないもの
「障害でデータが消えない」ことは確認できました。ただし、durabilityはバックアップの代替ではありません。最後に整理しておきます。
守れるもの
- ノード障害・フェイルオーバー・再起動時のデータ
- syncならACK済みの書き込みすべて。asyncの場合、ACK済みでも未永続化(最大10秒分)の書き込みは失われ得る
守れないもの
- 誤ったDELETEやFLUSHALL(論理削除はそのまま実行される)
- TTL切れによる期限削除、maxmemory超過時のeviction(durabilityは障害時のデータ保護機能であり、これらは仕様どおりの削除として実行される)
- アプリケーションのバグによるデータ破壊
- リージョン障害(Multi-AZであってマルチリージョンではない)
「キーが絶対に消えない」機能ではなく、「障害でデータが失われない」機能です。「間違って消した」に備えるには、従来どおりスナップショット(バックアップ)の併用が必要です。
まとめ
検証結果をまとめます。
- ACK済み書き込みは、フェイルオーバーを起こしても1件も失われなかった(2回の検証で計29,645件、欠落ゼロ)
- フェイルオーバーは約17〜19秒で完了し、適切に実装されたクライアントなら約17.5秒で書き込みが復帰する
- 雑な再接続実装では、クライアントの復帰に失敗する場合がある。リトライ設定の確認は必須
- syncとasyncはオンラインで切り替え可能(約50秒、ダウンタイムなし)
「ACKされた書き込みは消えない」という公式の説明を、実際にフェイルオーバーを起こして確認できました。マイクロ秒の読み取りと永続性の両方が欲しいデータ、たとえばAIエージェントのメモリやセッションステートには、有力な選択肢になります。
どなたかの参考になりましたら幸いです。





