Redisのmaxmemory-policy

オンメモリ KVS の Redis では、使用メモリに上限を設定し、閾値を超えた場合のポリシー(maxmemory-policy)を複数の中から設定できるようになっている。
パラメータとポリシーを整理したのが以下

使用メモリの上限値

redis.conf の次のパラメータで設定する。

maxmemory

maxmemory-policy
メモリ使用量が閾値を超えている状況でキー追加する場合の振る舞いは、以下の 6 つの maxmemory-policy から選択できる。

  1. volatile-lru : remove the key with an expire set using an LRU algorithm
  2. allkeys-lru : remove any key accordingly to the LRU algorithm
  3. volatile-random : remove a random key with an expire set
  4. allkeys-random : remove a random key, any key
  5. volatile-ttl : remove the key with the nearest expire time (minor TTL)
  6. noeviction : don’t expire at all, just return an error on write operations

2.4 でのデフォルトは volatile-lru。Redis が LRU キャッシュで使われることを一番に想定しているということか。

最後の noeviction では、Out Of Memory 状態で新しいキーを追加しようとすると、次のようなエラーメッセージを常に返す。

redis 127.0.0.1:6379> set foo bar
(error) ERR command not allowed when used memory > 'maxmemory'

残りの5つは、OOM Killer のように新しいキーを追加するのに必要な空きメモリを確保できるまで確率的に既存のキーを削除する。
ポリシーによって削除対象のキーの選び方が異なる。

all keys or volatile
全てのキーを対象とするのか expire が設定されたキーを対象にするのか。

TTL or LRU or random choice
TTL または LRU の場合、 maxmemory-samples(デフォルトは3) で指定した個数のキーをランダムに選び(=ランダム・サンプリング)、その中から最もふさわしいキー、たとえば volatile-ttl であれば TTL  が一番短いキーを evict 対象に選ぶ。当然ながら maxmemory-samples を 1 に設定すれば lru/ttl と random choice は同じ挙動になる。

なお Redis 作者の @antirez によると maxmemory-samples のデフォルトが 3 なのは “reasonable approximation of LRU in the long run” だそうだが、根拠は不明。サンプルサイズを増やせば CPU タイムが増える。

LRUの計算

LRU は least recently used の略。
Redis では各キーを 10-second resolution  の 22ビットタイムスタンプで管理しており(redis.h::redisObject->lru. (1 << 22 ) * 10 = 41943040 seconds = 485.5 days ≒ 1.5 year)、 キー追加、キー探索のたびにタイムスタンプが更新される。

  • キー追加 : object.c::createObject
  • キー探索 : db.c::lookupKey

サーバのタイムスタンプ(redis.h::redisServer->lruclock)とキーのタイムスタンプの差が短いほど recently used と判断し、長いほど evict 候補になる(object.c::estimateObjectIdleTime)。

TTL の計算

各キーの TTL(time to live)はハッシュテーブル(redis.h::redisDb->expires) で管理されている。TTL が短いほど evict 候補になる

expire date の設定例
TTL は expire や expireat や setex(set & expire のショートカット)コマンドで設定する。ttl コマンドで期限を確認できる。

redis 127.0.0.1:6379> set foo bar
OK
redis 127.0.0.1:6379> expire foo 100
(integer) 1
redis 127.0.0.1:6379> ttl foo
(integer) 98

32 bit 環境での例外ポリシー
例外的に、32bit環境で  maxmemory を設定していない場合、maxmemory を 3.5GB にし、noeviction で起動される。(redis.c::initServer)

[30400] 18 Mar 12:52:47 # Warning: 32 bit instance detected but no memory limit set. Setting 3.5 GB maxmemory limit with 'noeviction' policy now.

References

Advertisements
Tagged with: , ,
Posted in database

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 6 months ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 6 months ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 6 months ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 1 year ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 1 year ago
%d bloggers like this: