The behaviour of key expiration in Redis

Redisのkeyのexpirationを理解する為に、以下のページの「Appendix: Redis expires」を和訳してみました。

EXPIRE - Redis

間違い等あればtwitter(@masayuki)に連絡をください。

Keys with an expire

通常、Redisのkeyは生存期間を持たない。ユーザがDELコマンドを使って明示的に削除しない限り、keyは存在し続ける。 EXPIRE等のコマンドは、本来のkeyのメモリ消費量に少し上乗せする形で、keyに有効期限をつけることができる。keyに有効期限が設定されると、Redisは一定時間経過したkeyを削除するようになる。 keyの生存期間はEXPIREやPERSISTコマンドによって更新または削除される。

Expire accuracy

Redis2.4における有効期限は少し正確性に欠け、また有効期限は秒単位の指定となっていた。 Redis2.6より、有効期限の精度はミリ秒単位となっている。

Expires and persistence

keyの有効期限は、絶対時刻(Unixタイムスタンプ)として保存される。これはRedisのインスタンスがアクティブではない場合でも時間が経過することを意味する。 有効期限をうまく機能させる為にコンピュータの時間を安定に保たなければならない。時刻同期の取れていない2つのコンピュータの間でRDBファイルを移動すると、(ロード時にすべてのKeyが有効期限切れになってしまうような)おかしな現象が起こるだろう。 稼働中のインスタンスは常にコンピュータ時間をチェックするので、あるkeyの生存期間を1000秒に設定し、コンピュータ時間を2000秒進めると、そのkeyは即座に有効期限切れになってしまうだろう。

How Redis expires keys

Redisのkeyが有効期限切れと見なされるには2つの方式: passive wayとactive wayがある。 クライアントがkeyにアクセスした際に有効期限を過ぎていれば、その時に有効期限切れとされる(active way)。 もちろん、再びアクセスされることない有効期限を過ぎたkeyがあるので、これは十分ではない。これらのkeyは有効期限切れとされるべきなので、Redisは定期的にランダムにいくつかのkeyをテストし、有効期限切れとする。有効期限切れのkeyは全てkeyspaceから削除される(passive way)。

具体的に言うと、Redisは毎秒10回、以下のことを行っている。

  1. 有効期限が設定されているkeyからランダムに100個のkeyをテストする
  2. 有効期限切れのkeyが見つかったらすべて削除する
  3. 25個以上のkeyが期限切れとなった場合、再びステップ1から開始する

これはちょっとした確率論のアルゴリズムで、基本的な仮定は私たちのサンプルはkeyspace全体を表しており、有効期限切れとなるkeyが全体の25%未満になるまでこの操作を継続して実行する。 これは、メモリを消費している期限切れのkeyの最大量は、いかなる瞬間においても、1秒あたりの書き込み操作の最大数を4で割った値に等しいことを意味する。

一貫性を損なわず正しい操作を行うために、keyが期限切れとなった場合、DEL(keyを削除する操作)はAOFファイルと接続されている全てのスレーブに対し一括で行われる。keyを期限切れにする処理はマスターのインスタンスで行われ、一貫性を損なうことはない。 しかしながら、マスターに接続しているスレーブが個々にkeyを期限切れにしないので(マスターからのDELを待つことを除く)、スレーブではデータセットにkeyが期限切れのままで存在している状態となる。そしてスレーブがマスターに昇格すると、マスターとしてkeyを期限切れにすることができる。