Sidekiq を 6 → 7 にメジャーアップデートした
こんにちは。st-1985 です。
先日プロジェクトで使用している、sidekiq gem(ジョブをバックグラウンドで実行する為のライブラリ)のメジャーアップデートを行ったので、その際に行った対応や注意点、関連する gem のアップデートについてお話しできればと思います。
sidekiq gem 7 には Redis 6.2 以上が必要
前提条件として新しい sidekiq は Redis 6.2 以上を必要とするので事前に Redis のバージョンを上げておく必要があります。
sidekiq gem の 7.0 がリリースされてから1年以上経過していますが、アップデートまでに期間を要したのはここが大きかったです。
sidekiq の config を変更する必要がある
sidekiq のAPIマイグレーションガイドにあるように、 initializer で sidekiq の設定をしている場合に対応が必要です。
弊プロジェクトでは logger のフォーマットを指定していたのでそちらを変更する程度でした。
# before
Sidekiq.configure_server do |cfg|
cfg.log_formatter = ...
end
# after
Sidekiq.configure_server do |cfg|
cfg.logger.formatter = ...
end
上記以外にも
- logger 自体を指定している
- コネクションプールを使用している
- 独自の属性を持たせている
等に該当している場合は対応が必要なようです。
redis gem がアップデート可能になる
ここからは sidekiq gem ではなく redis gem 関連のお話しです。
sidekiq gem は 7.0 から Redis へのアクセスに redis-client gem を使用します。
これにより redis gem への依存がなくなる為、 sidekiq gem によって 5 にならないように抑えられていた redis gem もアップデートされます。
※Gemfile.lock のアップデート差分
弊プロジェクトでは sidekiq gem とは関係なく redis gem を利用している箇所もあるのでこちらもアップデートしましたが redis gem は一旦そのままにして別々にアップデートしても良かったかもしれません。
(この記事を書いていて気づきました)
redis gem のデフォルトタイムアウト値が5秒 → 1秒に
redis gem が 5.0 にアップデートした際にデフォルトのタイムアウト値が5秒から1秒に短縮されています。
負荷が大きくなった際等にタイムアウトが発生しやすくなってしまうので利用状況に応じて調整が必要かもしれません。
Redis のハッシュ型の値としてハッシュを渡すとエラーになる
redis gem を使用してハッシュ型のデータを保存している場合には微妙な挙動の変化がありました。
# before
Redis.new.hmset('myhash', 'key', { key: 'value' })
Redis.new.hgetall("myhash") # => {"key"=>"{:key=>\"value\"}"}
このような書き方をしても今まではハッシュが文字列にされて保存されていましたが、 redis gem をアップデートした事で以下のようにエラーが起きます。
# after
Redis.new.hmset('myhash', 'key', { key: 'value' }) # => Redis::CommandError: ERR wrong number of arguments for 'hmset' command
これはアップデート前までは redis gem 自身で Redis に接続していたのを redis-client 任せるようになったことによる影響のようです。
redis-client gem の README には与えられたハッシュを展開して別々の引数にする旨 が書かれています。
ただ、バージョンアップ以前でも保存する値が文字列になってしまうので、このような利用はあまりされていないと思われます。
弊プロジェクトで影響したのは Redis のデータを削除した事を確認するテストくらいでした。
(削除の確認なので、中のデータの形式を気にしていなかった)
redis gem のメソッド(sadd,srem) が boolean を返さなくなった
以下のようにメソッドの戻り値が変わっています。
# before
Redis.new.sadd("myset", "member") # => true
# after
Redis.new.sadd("myset", "member") # => 1
バージョンアップ前では sadd,srem の戻り値が integer になる旨の警告が出るようになっていましたが、そちらが実際に適用されたようです。
# バージョンアップ前の警告
# Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead.(called from: (pry):3:in `__pry__')
弊プロジェクトでは該当箇所はありませんでしたが、戻り値を使用して処理をしているところがあれば修正が必要かもしれません。
もし、 boolean が必要であれば sadd? や srem? を使用することで boolean での戻り値を得ることができます。
Redis.new.sadd?("myset", "member") # => true
まとめ
今回は、プロジェクトで使用している Sidekiq gem をバージョン 7 にアップデートした際の対応や関連 gem の注意点について紹介しました。
各項目の概要を以下にまとめます。
- 前提条件の確認: sidekiq gem 7 には Redis 6.2 以上が必要。事前に Redis のバージョンを確認し、必要に応じてアップデートする。
- 設定変更の必要性: sidekiq gem の設定(initializer)の変更が必要になる場合がある。
- redis gem のアップデート: Sidekiq の依存関係の変更により、redis gem が 5 以上にアップデート可能となった。
- redis gem のタイムアウト設定: redis gem 5.0 ではデフォルトのタイムアウト値が5秒から1秒に短縮された。利用状況に応じて設定を変更する。
- redis gem で特定データでのエラー: redis gem でのハッシュ追加時に値をハッシュにするとエラーが発生する。
- redis gem の一部メソッドの戻り値の変更: redis gem の sadd や srem の戻り値が boolean から integer に変更された。戻り値を使用している箇所は修正が必要。
公式のアップデートガイドや詳細情報については、以下を参照してください。
- Sidekiq 7.0 Upgrade Guide
- Sidekiq 7.0 API Migration Guide
- Redis 5.0 Changelog
- redis-client gem README
今回の内容がアップデートの際に参考になればと思います。
Discussion