こんにちは!Redisのメモリ管理、そしていよいよ「メモリがパンクした時にどうするか」という核心に迫る時間がやってきました。
Redisは、すべてのデータをメモリ(RAM)の上に載せることで、あの爆速なパフォーマンスを実現しています。しかし、無限にメモリがあるわけではありません。物理的な限界は必ず訪れます。
「じゃあ、メモリがいっぱいになったらどうなるの?」
「古いデータを自動で消してくれるって聞いたけど、どうやって選ばれるの?」
今回は、そんな疑問を完全に氷解させる「Evictionポリシー(メモリ逐次削除アルゴリズム)」の全貌を解説します。
ここをクリアすれば、Redisのメモリ管理の仕組みはバッチリマスターできますよ。難しい数式や専門用語は置いておいて、まずは日常の例えから楽しく紐解いていきましょう!
—
1. 例え話:あなたの「デスクの引き出し」で考えてみよう
想像してください。あなたの目の前に、大切な小物をしまう「小さな引き出し(Redisのメモリ)」があります。この引き出しに入る量は「最大で10個まで」と決まっています(これが `maxmemory` の設定です)。
最初は余裕ですが、毎日仕事をしているうちに、次々と新しいガジェットやメモ帳(データ)が送られてきて、ついに引き出しがパンパンになってしまいました。
「新しいメモ帳を入れたいのに、もうスペースがない……!」
さあ、あなたならどうしますか?
1. 「これ以上は絶対に入らない!」と、新しいメモ帳の受け取りを拒否する?
2. 「最近全然使ってない文房具」を捨てる?
3. 「なんとなく目についたもの」を適当に放り出す?
Redisがメモリ上限に達したときに行う行動も、まさにこれと同じです。この「何を基準に、どれを捨てる(または拒否する)か」を決めるルールが、Evictionポリシーなのです。
—
2. ポリシーの全体像を把握しよう
Redisでは、設定ファイル(`redis.conf`)の `maxmemory-policy` という項目で、この「お片付けのルール」を8種類の中から選ぶことができます。
名前を見ると難しそうですが、分解すると非常にシンプルです。ルールは、大きく分けて次の3つの軸の組み合わせでできています。
1. 対象範囲:すべてのデータ(allkeys)を見るのか、それとも「有効期限(TTL)が設定されているデータ」だけ(volatile)を見るのか。
2. 選び方:LRU(最近使ってないもの)、LFU(最近アクセス頻度が低いもの)、Random(ランダム)、TTL(寿命が短いもの)、あるいは何もしない(noeviction)。
これを踏まえて、8つのアルゴリズムを一つずつ、優しく見ていきましょう。
—
3. 全8アルゴリズムの徹底解説
① noeviction (お断りポリシー)
- 対象:なし
- 動作:何も削除せず、エラーを返す
メモリが限界に達しても、「データは1つも捨てない!」という頑固なポリシーです。
新しくデータを書き込もう(`SET`など)とすると、エラーが返ってきます。ただし、既存のデータを読んだり(`GET`)、削除したり(`DEL`)することはできます。
- 向いている用途:データを絶対にロストしたくない、キャッシュではなく厳密なデータベースとして使いたい場合。
② allkeys-lru (全データ対象・最近使ってない順)
- 対象:すべてのキー
- 動作:しばらく使われていない(Least Recently Used)古いデータを削除
デスクの例えで言うと、「ここ数日、一度も手に取っていないペンやメモ」を探し出して捨てる方式です。Redisの最も王道なキャッシュ戦略の一つです。
- 向いている用途:どのデータも等しくキャッシュとして扱いたい一般的なWebアプリケーション。
③ volatile-lru (期限付きデータ対象・最近使ってない順)
- 対象:Expire(有効期限)が設定されているキーのみ
- 動作:期限付きデータの中から、しばらく使われていないものを削除
「ずっと残す大事な書類」と「一時的なメモ(有効期限付き)」が混ざっているデスクで、一時的なメモの中から使っていないものを捨てます。
- 向いている用途:永続データと一時的なキャッシュを同じRedis内で同居させている場合。
④ allkeys-random (全データ対象・完全ランダム)
- 対象:すべてのキー
- 動作:どれを消すか、完全にランダムに選ぶ
引き出しの中身をろくに見もせず、目をつぶって「これ!」と掴んだものを捨てる豪快な方式です。
- 向いている用途:すべてのデータに優劣がなく、均等に古いものを捨てたい場合(実務ではあまり使われません)。
⑤ volatile-random (期限付きデータ対象・完全ランダム)
- 対象:Expire(有効期限)が設定されているキーのみ
- 動作:期限付きデータの中から、ランダムに選んで削除
期限付きのメモの中から、ランダムにポイっと捨てる方式です。
⑥ volatile-ttl (寿命が短い順)
- 対象:Expire(有効期限)が設定されているキーのみ
- 動作:残り寿命(TTL)が一番短い(=もうすぐ自動で消える予定の)ものを優先して削除
「あと5分で賞味期限が切れる牛乳」から順に片付けていくようなイメージです。
- 向いている用途:もうすぐ消える運命のデータなら、今すぐ消しても実害が少ないだろうという発想のとき。
⑦ allkeys-lfu (全データ対象・アクセス頻度が少ない順)— ★注目!
- 対象:すべてのキー
- 動作:アクセスされた「回数(Least Frequently Used)」が少ないデータを削除
LRUが「最後に使ってからの時間」を見るのに対し、LFUは「使われた回数」を見ます。
例えば、「昨日1回だけ見たデータ」と「1年間に1万回も見ているデータ」があった場合、LRUだと「昨日見たデータの方が新しい」と判断して残しますが、LFUは「アクセス回数が圧倒的に多い」後者を大切に残します。
- 向いている用途:アクセス頻度の偏りが激しいサービス(バズっている記事と、そうでもない記事が混在するニュースサイトなど)。
⑧ volatile-lfu (期限付きデータ対象・アクセス頻度が少ない順)
- 対象:Expire(有効期限)が設定されているキーのみ
- 動作:期限付きデータの中で、アクセス回数が少ないものを削除
LFUの考え方を、有効期限付きのデータだけに適用するルールです。
—
4. 実務での選び方:先輩からのアドバイス
「じゃあ、結局どれを使えばいいの?」という声が聞こえてきそうですね。実務の現場で迷ったら、まずは以下の基準で選んでみてください。
1. 迷ったらこれ!王道の `allkeys-lru`
一般的なWebアプリケーションのキャッシュであれば、大半のケースで `allkeys-lru` を選んでおけば間違いありません。「最近アクセスされていないデータは、今後も使われないだろう」という自然な法則に基づいているからです。
2. トレンドを正確に掴みたいなら `allkeys-lfu`
Redis 4.0から導入されたLFUは、長期的な人気データを正確に残してくれます。「アクセス回数」という直感的な指標がマッチするシステムなら非常に強力です。
3. 絶対にデータを失いたくないなら `noeviction`
セッションストアや、カートの中身など、「勝手にデータが消えるとユーザーが困るもの」を扱う場合は、勝手に消されるよりエラーになってくれた方が安全です。
—
5. 設定と確認の方法
最後に、実際にRedisでこれを確認・設定する方法を軽く見ておきましょう。
現在のポリシーを確認するには、Redisのcliからこう打ちます:
現在設定されている最大メモリポリシーを確認する
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) “maxmemory-policy”
2) “noeviction” # デフォルトでは「お断り」設定になっています
もし、これを `allkeys-lru` に変更したい場合は、動的にこう変更できます(※本番環境では `redis.conf` ファイルの書き換えも忘れないようにしましょう):
動的にポリシーを allkeys-lru に変更
127.0.0.1:6379> CONFIG SET maxmemory-policy allkeys-lru
OK
これで、Redisはメモリが一杯になった瞬間から、自動的に賢くLRUで古いデータを片付けてくれるようになります。
—
まとめ
- Redisのメモリが一杯になったときの動きを決めるのが Evictionポリシー。
- 対象範囲(すべてのデータか、期限付きか)と、削除基準(LRU, LFU, Random, TTL, noeviction)の組み合わせ。
- 基本は `allkeys-lru` または新しめの `allkeys-lfu` を押さえておけばバッチリ!
Redisのメモリ管理の仕組みが、ぐっと身近に感じられたのではないでしょうか。この引き出しの整理整頓ルールを味方につければ、大規模なトラフィックが来てもメモリ溢れで慌てることのない、強靭なシステムを構築できますよ。
それでは、次のステップでも一緒に楽しくRedisを極めていきましょう!
コメント