どうも永田です。
弊社サービスの「リレーション」では、セッション管理やジョブキュー、一時的なデータ置き場として Redis を使っています。 最近、EC2 上に自前で構築していた Redis から AWS Elasticache に移行しました。
動機
自前で構築していた Redis は Sentinel を使ってクラスタを構築していました。特に問題はなかったのですが、やはり管理対象を減らしてマネージドサービスに移行していきたいという思いがあり、移行することにしました。
データの移行
実は自前 Redis は3系のバージョンを使っていました。AWS Elasticache では現時点で最新の5.0.4を使っています。気になるのはデータ(rdbファイル)を移行する際の互換性。
こちらには
Redis dump file is 100% backwards compatible. An older dump file format will always work with a newer version of Redis.
とあり、バージョンによる互換性は大丈夫だと言えそうです。
ただし、AWS Elasticache はクラスタを起動するタイミングでしか rdb ファイルをインポートできないため、移行は多少ややこしくなります(後述)
Cluster Mode はどちらにすべきか?
AWS Elasticache はそもそもがクラスタなのですが、作成する際に Cluster Mode のチェックボックスがあります。当然オンでしょ?と思ったらハマりました。弊社サービスでは非同期ジョブに Sidekiq を使っており、ジョブキューには Redis を使っているのですが、その Sidekiq が Redis Cluster には対応していないようなのです。
ここに、Cluster is NOT appropriate for Sidekiq と太字で書かれています。
実際のエラーメッセージは
ERR CROSSSLOT Keys in request don't hash to the same slot.
というもので、https://github.com/mperham/sidekiq/blob/3d622887c81b28cf0ffc5c8c1f7dd626c463f6a1/lib/sidekiq/api.rb#L205-L206 ここに TODO で誰かクラスターサポートしてよとコメントに書いていますね。
では実際の移行手順はどうなるのか?
上述のとおり、rdb ファイルは、Elasticache のクラスタ作成時でないと指定できません。 そのため、多少時間はかかるのですが、以下の手順を取ることにしました。
- AWS で Elasticache のクラスタ作成の入力項目を全部埋めておく(rdb の s3 のロケーションも)
- アプリケーションをメンテナンスモードをオンにする
- バッチや常駐プログラムの起動を停止し、自前 Redis へのコネクションがないことを確認する(コマンドは後述)
- 旧 Redis の rdb ファイルを 1 で指定した s3 のロケーションにアップロードする
- アップロードしたファイルのS3上でのパーミッションを変更する(詳細は後述)
- クラスタ作成の実施する(大体7分から8分くらいか)
- ステータスが
creating
からmodifying
に変わり、primary endpoint が確定したら、アプリケーションが参照するRedisのホストをその primary endpoint に変更し、設定内容を反映させる - メンテナンスモードをオフにする
- セッションが引き継げているかなど動作確認をする
といった流れとなりました。
Redis のコネクションの確認は
$ redis-cli -h <host> CLIENT LIST
で確認可能です。
また s3 にアップロードした rdb ファイルのパーミッションは
にあるとおり、 [Add Account] に 540804c33a284a299d2547575ce1010f2312ef3da9b3a053c8bc45bf233e4353
を入力し、読み取り権限を与える必要があります。
移行後
残念ながら、AWS Elasticache にしたことによってパフォーマンスがよくなったとかそういった感触はありません。 メモリ空間は今までより増えたので、さらに活用していこうかと思います。
では!
エンジニアは引き続き募集中だよ!