🐈
Sidekiq利用時のRedisのmaxmemory-policyの設定
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