本記事では、Herokuで提供されているHeroku Data for RedisというRedisアドオンのバージョンアップの方法を記載します。
RailsアプリでのRedis6.2から7.2へのバージョンアップを例として使用しますが、他のフレームワークやバージョンでもやり方はほぼ一緒なはずです。また、6.2から7.0, 7.0から7.2のように間に7.0へのアップグレードを挟まなくても、直接6.2から7.2へのアップグレードが可能です。
なお、Redisがオープンソースではなくなったことが原因で、Herokuではバージョン7.2からはRedisではなくRedisをフォークしたオープンソースのValkeyを使って同様の機能を提供しています。本番環境でのアップグレード手順は変わりませんが、ローカル環境ではそれに伴ってvalkeyを使ってテストするようにします。
ローカル環境での事前確認
Heroku環境でRedisのアップグレードを行なう前に、ローカル環境でアップグレードしてみて、アプリケーションが正常に動作するかを確認します。
Docker Composeを使ってRedisを管理している場合、dokcer-compose.ymlファイルでバージョンを変更します。また、7.2以降にアップグレードする場合は、redisではなくvalkeyに変更します。
version: '2.1'
services:
- redis:
- image: "redis:latest"
+ valkey:
+ image: "valkey/valkey:7.2"
ports:
- "6379:6379"
Valkeyに変更してもAPIの互換性があるので、redis-rb gemは以前のまま使えます。例えば、Railsアプリケーションで$redis.setや$redis.delなどredisグローバルオブジェクトを使っていたとしてもそのまま使えます。
ローカル環境でテストすべき項目は以下の通りです。
- $redisオブジェクトを使っている箇所。
- ActiveJob関連機能(メール通知など)。
ローカル環境で無事にアプリケーションが動作するかどうかを、手動・自動テスト両方で確認できたらOKです。
本番環境でのアップグレード
本番環境でのアップグレード手順は、Heroku Data for Redisの契約プランがMiniプランかそうでないかによって若干異なります。
Miniプランの場合
Miniプランの場合はRedisのメンテナンスを予約することができなくすぐにアップグレードが始まります。そのため、アップグレード中にアクセスされないよう、先にアプリケーションをメンテナンスモードにしておきます。
heroku maintenance:on
その後、webとworkerがredisにアクセスしないように、両方のdyno数を0にしますが、元のdyno数がわからなくならないように確認してメモしておきます。
# webとworkerのdyno数の確認
heroku ps
# dyno数を0にスケールダウン
heroku ps:scale web=0 worker=0
Redisアドオンの名前とバージョンを指定し、アップグレードします。
heroku redis:upgrade redisアドオン名 --version 7.2
以下のコマンドでアップグレードの進捗を確認できます。
heroku redis
以下のようなRedisの情報がコンソールに出力され、Status欄で進捗を確認できます。Versionはアップグレード前のバージョンが表示されます。
Plan: Mini
Status: preparing (creating maintenance event for version upgrade)
Created: 2023-06-05 06:32
Version: 7.0.15
Timeout: 300
Maxmemory: noeviction
Maintenance: not required
Maintenance window: Wednesdays 18:00 to 22:00 UTC
Persistence: None
HA Status: Unavailable
Requires TLS: Yes
Keyspace Notifications: Disabled
このコマンドでStatusがavailableになり、Versionが7.2に変わったらバージョンアップ完了です。
dyno数を元に戻します。
heroku ps:scale web=1 worker=1
アプリケーションのメンテナンスモードを解除します。
heroku maintenance:off
メール送信などRedisを使う機能を試し、問題がなければアップグレード完了です。
Miniプラン以外の場合
Miniプラン以外の場合は以下の手順になります。
- Redisのデータメンテナンスを作成(新バージョンの用意)。
- アプリケーションをメンテナンスモードにする。
- Redisのデータメンテナンス実行。
- アプリケーションのメンテナンスモード解除。
1のRedisメンテナンスの作成には15〜30分ほど時間がかかりますが、その間はアプリケーションをメンテナンスモードにする必要はありません。また、3のRedisメンテナンスの実行は数秒で終わりますので、Miniプランに比べるとダウンタイムを最小限に抑えられるというメリットがあります。
もしData MaintenanceのCLIプラグインがインストールされていない場合は以下のコマンドで事前にインストールしておきます。
heroku plugins:install @heroku-cli/plugin-data-maintenance
Redisのアドオン名とバージョンを指定してアップグレードコマンドを実行します。
heroku redis:upgrade redisアドオン名 --version 7.2
すると、自動的にRedisのデータメンテナンスが作成され、以下のような情報が表示されます。
Requesting upgrade of redis-アドオン名 to 7.2… Your Redis version is being upgraded to 7.2.The system is preparing a maintenance.
Once the maintenance is ready you can run it with heroku data:maintenances:run.
See: https://devcenter.heroku.com/articles/data-maintenance-cli-commands#heroku-data-maintenances-run.
アップグレードの進捗は以下のコマンドで確認できます。
heroku data:maintenances:info redisアドオン名
もし過去のメンテナンス情報が表示されたらまだメンテナンス作成中です。その場合、status項目はcompletedかつstarted_at項目は過去の日時が表示されます。
addon_attachments: REDIS_URL
addon_description: premium HA
addon_kind: heroku-redis
addon_name: Redisアドオン名
addon_plan: premium-0
addon_window: Fridays 20:00 to Saturdays 00:00 UTC
app_name: アプリケーション名
completed_at: 2024-07-19T20:05:31.029+00:00
duration_approximate: ~ 4 minutes
duration_seconds: 268
method: failover
reason: routine_maintenance
required_by: 2024-08-12T17:51:48.684+00:00
scheduled_for: 2024-07-19T20:00:00.000+00:00
server_created_at: 2024-05-06T21:53:16.126+00:00
started_at: 2024-07-19T20:01:02.128+00:00
status: completed
window: Fridays 20:00 to Saturdays 00:00 UTC
メンテナンス作成が終わると、過去のメンテナンスではなく作成された将来のメンテナンス情報に表示が変わります。scheduled_for項目が将来の日付になり、status項目もreadyになります。
addon_attachments: REDIS_URL
addon_description: premium HA
addon_kind: heroku-redis
addon_name: Redisアドオン名
addon_plan: premium-0
addon_window: Fridays 20:00 to Saturdays 00:00 UTC
app_name: アプリケーション名
method: failover
reason: customer_request
required_by: 2024-09-27T09:32:54.969+00:00
scheduled_for: 2024-09-06T20:00:00.000+00:00
server_created_at: 2024-07-15T17:33:47.573+00:00
status: ready
window: Fridays 20:00 to Saturdays 00:00 UTC
また、heroku data:maintenances:infoコマンドに加え、heroku redisコマンドでも進捗が確認できます。
heroku redis
メンテナンス作成中の場合、Statusがpreparingと表示されます。
Plan: Premium 0
Status: preparing (creating maintenance event for version upgrade)
Created: 2019-12-13 05:29
Version: 6.2.14
Timeout: 300
Maxmemory: noeviction
Maintenance: not required
Maintenance window: Fridays 20:00 to Saturdays 00:00 UTC
Persistence: AOF
HA Status: Available
Requires TLS: Yes
Keyspace Notifications: Disabled
メンテナンス作成後はStatusがawaiting version upgradeに変わります。
Plan: Premium 0
Status: awaiting version upgrade (maintenance pending)
Created: 2019-12-13 05:29
Version: 6.2.14
Timeout: 300
Maxmemory: noeviction
Maintenance: scheduled for 2024-09-06 20:00:00 +0000, required by 2024-09-27 09:32:54 +0000
Maintenance window: Fridays 20:00 to Saturdays 00:00 UTC
Persistence: AOF
HA Status: Available
Requires TLS: Yes
Keyspace Notifications: Disabled
作成されたメンテナンスを実行します。メンテナンス実行は数秒で終わります。
heroku data:maintenances:run redisアドオン名
data:maintenances:infoコマンドで実行完了かを確認します。
heroku data:maintenances:info redisアドオン名
Fetching maintenance… done
addon_attachments: REDIS_URL
addon_description: premium HA
addon_kind: heroku-redis
addon_name: Redisアドオン名
addon_plan: premium-0
addon_window: Fridays 20:00 to Saturdays 00:00 UTC
app_name: アプリケーション名
completed_at: 2024-08-30T09:45:43.035+00:00
duration_approximate: ~ less than a minute
duration_seconds: 10
method: failover
reason: customer_request
required_by: 2024-09-27T09:32:54.969+00:00
scheduled_for: 2024-08-30T09:45:30.621+00:00
server_created_at: 2024-07-15T17:33:47.573+00:00
started_at: 2024-08-30T09:45:32.664+00:00
status: completed
window: Fridays 20:00 to Saturdays 00:00 UTC
statusがcompletedになっていたら完了です。
Dynos数を元に戻します。
heroku ps:scale web=1 worker=1
アプリケーションメンテナンスを解除します。
heroku maintenance:off
メール送信などRedisを使う機能を試し、問題がなければアップグレード完了です。
まとめ
herokuでのredisのバージョンアップは、契約プランがMiniプランかそれ以外かで方法が若干異なりますので、ご自身のプランを確認して適切な方法を使うようにしましょう。
