Redisのメモリを使い切った時に「OOM command not allowed when used memory > ‘maxmemory’.」というエラーが発生することがあります。
「maxmemory言われてるし…」とメモリ周りを確認することになるので、ちらっと調べたことのメモ書き。
現時点でのメモリ使用量を調べる
Redisのinfo
コマンドでRedisの情報を確認。
「メモリ情報だけ確認したい!」という時はinfo memory
で確認できます。
> redis-cli -h xxx xxx:6379> info memory # Memory used_memory:1346349472 used_memory_human:1.25G used_memory_rss:1322913792 used_memory_peak:1347333880 used_memory_peak_human:1.25G used_memory_lua:36864 mem_fragmentation_ratio:0.98 mem_allocator:jemalloc-3.6.0
used_memory
が使用量(_human
で単位付き)なので、上記の例だと1.25Gのメモリを使用していることになります。
参考:
INFO – Redis
maxmemory-policyの確認
ざっくり言うと、「メモリいっぱいになったらどうする?」の設定。
- noeviction
メモリ制限に達しているのに、さらにメモリを使用するようなコマンド(ほぼ書き込み。DELやいくつか例外あり)を実行しようとしているときにエラーを返す。 - allkeys-lru
新しいデータの領域を確保するため、あまり使われていないキー(LRU)を先に削除しようとする。 - volatile-lru
新しいデータの領域を確保するため、あまり使われていないキー(LRU)を先に削除しようとする。有効期限が設定されているキーのみ対象。 - allkeys-random
新しいデータの領域を確保するため、キーをランダムに削除する。 - volatile-random
新しいデータの領域を確保するため、キーをランダムに削除する。有効期限が設定されているキーのみ対象。 - volatile-ttl
新しいデータの領域を確保するため、有効期限が設定されたキーの中で、より短い有効期間(TTL)のキーを削除する。
volatile-lru
、volatile-random
、volatile-ttl
を設定していても、有効期限を設定しているものが無い場合はnoeviction
と同じ挙動になるので、メモリを使い切った時には例の「maxmemory」エラーが出てしまうようです。
参考:
Using Redis as an LRU cache – Redis
対策
有効期限を設定できるのであればそれが無難なような感じもしますが、時と場合によっては期限を設定したく無い時も。
そうなるとメモリの増量が有力候補に踊り出るかと思います。
AWSのElastiCacheの場合はノードタイプを変更することでメモリを増やすこともできますが、一時的に読み・書きができなくなるので、「アクセスできなくなったらまずいんだよなぁ…」な場合は、気持ち慎重に対応する必要があります。
参考;
単一ノード Redis のクラスターのスケールアップ - Amazon ElastiCache
Redis 本番障害から学んだコードレビューの勘所 - Qiita
Redisのメモリ使用量がmaxを超えた場合の挙動 - Gaishimo