🐈

Sidekiq利用時のRedisのmaxmemory-policyの設定

2024/04/15に公開

Sidekiq起動時に、以下のようなwarningが表示される場合があります。

WARNING: Your Redis instance will evict Sidekiq data under heavy load.
The 'noeviction' maxmemory policy is recommended (current policy: 'allkeys-lru').
See: https://github.com/sidekiq/sidekiq/wiki/Using-Redis#memory

Redisのmaxmemory-policyには、noevictionという値を設定することを推奨するという内容ですが、maxmemory-policyについて詳しくなかったので調べてみました。

Redisのmaxmemory_policyとは

maxmemory-policyとは、Redisのメモリが100%になるかmaxmemoryの設定値を超えた時の振る舞いを定義するものです。

noevictionの場合は、メモリが制限に達した場合は、新しい値を保存しないようになります。他の設定だとキーを削除する挙動もあるので、sidekiqでの利用時にはnoevictionが推奨されています。

maxmemory-policyの違いによる挙動の違い

サンプルとして、50,000件をキューに入れるコマンドを用意します。

class EnqueJob
  def self.run
    50000.times do |i|
      NormalJob.perform_async(i + 1)
    end
  end
end

redis-cliを利用して、メモリを5MBに設定します。

$ redis-cli
127.0.0.1:6379> CONFIG SET maxmemory 5mb
OK
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "5242880"

maxmemory-policyに、noevictionを設定します。

127.0.0.1:6379> CONFIG SET maxmemory-policy noeviction
OK
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"

エンキューコマンドを実行すると、エラーとなります。

% rails c
irb(main):001:0> EnqueJob.run
/home/hoge/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/redis-client-0.21.0/lib/redis_client/connection_mixin.rb:71:in `call_pipelined': OOM command not allowed when used memory > 'maxmemory'. (redis://localhost:6379) (RedisClient::OutOfMemoryError)

次に、allkeys-lruを設定してみます。これは、メモリが制限を超えた場合にもっとも最近使われていない(LRU)キーから削除するよう試みるという挙動になります。

127.0.0.1:6379> CONFIG SET maxmemory-policy allkeys-lru
OK
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"

エンキューコマンドを何度実行しても、エラーにはなりません。その代わりに、古いキーは消えてしまっています。

irb(main):001:0> EnqueJob.run
=> 10000
irb(main):002:0> EnqueJob.run
=> 10000
irb(main):003:0> EnqueJob.run
=> 10000
irb(main):004:0> EnqueJob.run
=> 10000
irb(main):005:0> EnqueJob.run
=> 10000

Discussion