[アップデート] ElastiCache Serverless for Valkey がオンライン移行に対応したので EC2 の Redis OSS から移してみた
いわさです。
先日のアップデートで、ElastiCache Serverless for Valkey に移行機能が追加され、セルフマネージドな Valkey / Redis OSS からダウンタイムなしのオンライン移行ができるようになりました。
最近 ElastiCache for Redis OSS のアップデートの関係で Valkey への移行方法の案内通知が出ていたので、これ良さそうだなと思ったのですが、今回のアップデート移行元の対象はセルフマネージドが前提みたいです。
ただ、そのケースも一定ありそうだなと思ったので試してみることにしました。
対応している移行元は Redis OSS 4.0 〜 7.2、または Valkey 7.2 〜 8.1 のクラスターモード(どちらもセルフマネージド)で、そこから直接 Valkey 9.0 へ移行できるみたいです。
今回こちらを確認してみたので紹介します。
やってみる
今回はソース(移行元)に EC2 上の Redis OSS 7.2(クラスターモード、3 プライマリ + 3 レプリカ、全スロットカバー)、ターゲット(移行先)に空の ElastiCache Serverless for Valkey(エンジンバージョン 9.0、IPv4、パブリックエンドポイントなし)を用意しました。
ソースとターゲットは同じ VPC・同じセキュリティグループを使い、ソースの Redis ポートに ElastiCache 側から到達できるようにしています。
コンソールのウィザードで操作しましょう。東京リージョンでやりました。
ElastiCache コンソールのナビゲーションペインに「移行」があります。
開いて右上の「移行を作成」を押しました。

移行先は「サーバーレスに移行」と「ノードベースに移行」の 2 つから選べました。
移行先がサーバーレスキャッシュかノードベースのクラスターかで選ぶ形で、ドキュメントもそれぞれ別ページに分かれています。
These topics cover migration to an ElastiCache Serverless cache. To migrate to a node-based cluster instead, see Online migration to ElastiCache node-based clusters.
検証なのでどっちでも良いのですが、今回は「サーバーレスに移行」を選びました。

移行の作成画面はこんな感じで、ソースの詳細とターゲットの詳細を入力します。

ソースの詳細のサーバーアドレスには、移行元 EC2 を選択します。
カーソルあわせたら候補選択出来ましたが、多分 IP 直接入力が想定されていそうです。オンプレとかかな。

ターゲットの詳細では、移行先の Valkey サーバーレスキャッシュとして、今回作った空の ecmig-valkey-target(Available・valkey 9.0)を指定しました。

今回は次のような感じでソースとターゲットを指定しています。

今回は認証なし・TLS なしのソースなので、認証方法は「なし」、TLS 暗号化も「なし」を選びました。
認証ありのソースなら Secrets Manager にシークレットを置き、TLS ありなら「CA を検証」で CA 証明書(チェーン)を指定するっぽいです。
「作成」を押すと移行の詳細ページに移り、現在の状態が「移行の準備中」になりました。

準備は数分で終わると書かれていますが、今回の環境では「移行の準備中」から「同期準備完了」になるまで 9 分ほどかかりました。
ちなみに AWS CLI でステータスを確認してみると同期準備完了になるまでの間にpreparing から ready-to-sync に変わります。
ここでいう「同期」は、ソースの Redis OSS にあるデータを移行先のサーバーレスキャッシュへ複製する処理のことです。
Start the data sync. ElastiCache begins replicating data from your source cache to the target cache. It keeps replicating as your application writes.
なお、初回にターゲットを 2 サブネット(2 AZ)で作っていたら、移行の準備中に失敗しました。
ドキュメントを見ると、ターゲットキャッシュは ElastiCache Serverless が使う各 AZ にサブネットを持っている必要があるとのことで、3 AZ 分のサブネットを指定してターゲットを作り直したらいけました。
Your target cache must have a subnet in each Availability Zone that ElastiCache Serverless uses in your AWS Region. If it does not, the prepare step fails.
また、準備が終わる前にデータ同期を開始しようとしたところ、次のようなエラーとなり、ステータスが「同期準備完了」になってから開始するまで実行できませんでした。
An error occurred (InvalidServerlessCacheStateFault) when calling the
StartMigration operation: Serverless cache is not in a valid migration
state to perform this operation.
「同期準備完了」になると、移行の詳細ページに移行エンドポイントが表示され、「移行エンドポイントをコピー」ボタンでコピーできるようになりました。
コンソールの様子からすると、どうやらここでアプリ側は移行エンドポイントの使用に更新する必要があるようです。

ドキュメントでも、データ同期を始める前にアプリを移行エンドポイントに向けるよう案内されていました。
Point your application at the migration endpoint and confirm that it is serving traffic through the endpoint. The console reminds you to do this before you start the data sync, because ElastiCache cannot detect whether your application has moved.
今回は EC2 上のアプリケーションから移行エンドポイントを接続先にして、読み書きをし続けておきます。
なお、この移行エンドポイントはサーバーレスキャッシュの通常のエンドポイントなので、サーバーレスの接続要件(TLS必須など)があります。
セキュリティグループにも、クライアントから 6379 へ到達できるようインバウンドを追加しています。
redis-cli-tls --tls \
-h ecmig-valkey-target-xxxxxx.serverless.apne1.cache.amazonaws.com \
-p 6379 ping
PONG
アプリケーションのエンドポイントを切り替えたので「移行を開始」ボタンを押してみましょう。
「移行を開始」を押すと、カットオーバーモードを選ぶダイアログが出ました。

コンソールによると、手動カットオーバーは自分でカットオーバーのタイミングを制御するモードで、カットオーバーを手動で開始するまでトラフィックはソースに流れる。
自動カットオーバーは、完全に同期された次のウィンドウでカットオーバーが自動的に実行されるとのこと。
公式ドキュメントでも次のように記載されていました。
The Cutover mode control, with the values Manual cutover and Auto-cutover. With manual cutover, you call
CompleteMigrationwhen you are ready. With automatic cutover, ElastiCache completes the cutover for you at the next fully synced window.
今回は手動カットオーバーで進めました。
「移行を開始」を押すとデータ同期が始まり、バナーが「ステップ 2/3: データ同期を開始しています」に変わりました。

現在の状態は「同期の初期化中」(initiating-sync)になり、そこから「データ同期中」(syncing)へ進みました。
同期が追いついたところで「移行を完了」を押して、カットオーバーを確定しました。
バナーが「ステップ 3/3: カットオーバーが進行中です」に変わり、現在の状態が「カットオーバーが進行中」(cutting-over)になりました。

cutting-over は少し長めに続きました。
ドキュメントには、この時点でトラフィックはすでに移行先に移っていて、「まだ移行先が応答していない」という意味ではない、と明記されています。
The
cutting-overstate persists while ElastiCache tears down the migration infrastructure. By this point, your traffic has already moved to your target cache. Do not read this state as a sign that your target is not yet serving.
最初に試したときは、AWS CLI から自動カットオーバーを指定してデータ同期を開始しました。
--auto-cutover を外すと手動カットオーバーになります。
aws elasticache start-migration \
--serverless-cache-name ecmig-valkey-target \
--auto-cutover \
--clear-target-cache-data
自動カットオーバーで試したときは、まだ同期が追いつく前に complete-migration(force なし)を呼んでも受け付けられず、InvalidServerlessCacheStateFault になってしまいました。
同期が追いついたら ElastiCache 側が自動で切り替えるので、自動のときは完了操作が要りません。
手動のときは、同期が追いついた後に自分で「移行を完了」を押して確定します。
どちらの場合も、カットオーバーが終わると Migration オブジェクトが消えて、キャッシュのステータスが Available に戻りました。
移行中にクライアント側にエラーが発生していないかを確認してみました。
EC2 上で移行エンドポイントに対して連続で SET と GET を繰り返すスクリプトを起動しておきました。
それぞれの処理実行時のエラー回数をカウントしていたのですが、カットオーバーをまたいで最後まで実行した結果は次のようになりました。
FINAL i=30781 ok=30781 err=0
30781 回の書き込みと読み戻しが全部成功し、アナウンスにあるようにエラーは 0 回でした。
同期の初期化からカットオーバーが進行中になるまで、接続先を一度も変えずに読み書きが途切れませんでしたね。
カットオーバー中にアプリ側で何が起きるかもドキュメントに書かれています。
ワークロードによっては 2〜10 秒ほど、テールレイテンシ(p99 などの応答時間)が上がるとのことです。
今回のスクリプトは応答時間まで記録してなかったな・・・。
Reads and writes keep flowing, and tail latency rises briefly. Traffic flows continuously throughout cutover. Tail latency rises for roughly 2 to 10 seconds, depending on your workload.
移行先のデータも確認しました。
移行前にソースへ入れておいたキーはそのまま移行先にあり、移行中にスクリプトが書いた mlive:* のキーも移行先に反映されていました。
redis-cli-tls --tls -h <migration-endpoint> -p 6379 GET key:1000
value-1000
redis-cli-tls --tls -h <migration-endpoint> -p 6379 GET mlive:100
v100
カットオーバーの前後でデータの欠損もなかったです。
料金がかかる
今回のこの移行機能の利用は、アカウントごとに最初に移行を準備した日から 180 日間は無料とのこと。
その後は、データ複製のために ElastiCache が動かす移行ノードに対して、移行が動いているあいだ node-hour という料金が発生するようです。
移行の料金を止めるには移行を完了する必要があります(コンソールの「移行を完了」、CLI の complete-migration)。
データ同期を停止(stop-migration)しても移行インフラは残ったままなので、移行を途中でやめるつもりで停止しただけだと、移行の料金はかかり続けるので注意してください。
Billing does not stop when you stop the data sync.
StopMigrationleaves the migration infrastructure provisioned.CompleteMigrationis the call that ends the migration and its charges. Your target ElastiCache Serverless cache continues to bill until you delete it.
なお、移行中にエラーが出て停止した場合は、原因を直してもデータ同期を再開できず、強制完了でしか移行を終えられないようです。
If the migration has reported an error, StopMigration still succeeds and reports that the data sync stopped, but a later StartMigration is rejected. This applies even to a problem you have since fixed, such as a network path that dropped or a credential that changed. The only way to end the migration is then to complete it with force.
サーバーレスキャッシュの料金そのものは ElastiCache の料金ページ を確認してください。
さいごに
本日は ElastiCache Serverless for Valkey のオンライン移行を、EC2 上の Redis OSS 7.2 クラスターをソースにして、準備からカットオーバーまで実施してみました。
アプリケーション側のエラー数や、移行前後のデータ欠損なかったのでこのオンラインマイグレーションはかなり良さそうですね。
ドキュメント記載の2~10秒の間のレイテンシー低下だけ許容できそうであれば。
セルフマネージドな Redis などを使っている方はぜひこれを機に ElastiCache Server for Valkey への移行も検討してみてください。








