こんにちは!Redisの世界へようこそ。
今回は、Redisの心臓部とも言える「メモリ管理と最適化」、その中でも特に重要な「LRU(Least Recently Used)アルゴリズム」について、徹底的に解き明かしていきます。
「LRUなんて、教科書通りの用語で難しそう……」なんて身構える必要は全くありません。
実はこれ、私たちの日常生活にめちゃくちゃ近い場所で行われている、とってもシンプルで賢い「お片付けの知恵」なんです。
ここをしっかりとクリアすれば、Redisのメモリ管理の仕組みはバッチリマスターできますよ!それでは、優しく、そして深く、その本質の世界へご案内します。
—
1. なぜRedisには「お片付け」が必要なのか?
まず前提として、Redisはデータの読み書きをものすごく高速に行うために、パソコンの「メモリ(RAM)」という特等席にデータを置いています。
しかし、この特等席の広さは無限ではありません。いつかは満杯になります。
メモリがパンクしかけたとき、Redisはこう考えます。
「新しいデータを置くスペースを作るために、古くて使われていないデータを何か一つ捨てなきゃいけない……どれを捨てよう?」
この「どれを捨てるか」を決めるルールのひとつが、今回主役のLRUアルゴリズムです。
—
2. 日常で例えるLRU:「本棚の整理」
LRUは、「最も長い間使われていない(Least Recently Used)ものから処分する」というルールです。
あなたの部屋にある小さな本棚を想像してください。この本棚には、最大で5冊しか本が入りません。
そこに新しい本が届きました。でも、すでに本棚はパンパンです。さて、どうしますか?
- 直近で何度も読んでいるお気に入りの本は、すぐ取り出せるように残しておきたいですよね。
- 逆に、「最後に開いたのはいつだっけ……?」というホコリをかぶった難しい本は、一旦本棚から出して、ダンボール箱にしまいそうです。
この「最後に使ってからの経過時間が一番長いものを追い出す」という仕組みこそが、LRUの本質です。直感的で、理にかなっていますよね。
—
3. 本物のLRUは「贅沢病」?Redisの選択
「なるほど、じゃあ一番古いやつを完璧に探して捨てればいいんだね!」と思ったそこのあなた。さすが鋭い視点ですが、ここに大きな罠があります。
コンピュータの世界で「完全な(真の)LRU」をやろうとすると、ものすごい手間のコストがかかります。
すべてのデータに「最後にアクセスされた正確な日時」を記録し、誰かがアクセスするたびに並び替えを行い、一番古いものを正確に特定する……。
これを数百万件という膨大なデータを持つRedisでやるとどうなるか?
「片付けの計算」に夢中になりすぎて、肝心の「データの読み書き(本来の仕事)」が遅くなってしまうのです。本末転倒ですよね。
そこでRedisの生みの親たちはこう決断しました。
「完璧な一番古いデータじゃなくて、だいたい一番古そうなやつをサクッと選んで捨てよう!」
これが、Redis独自の「近似(きんじ)LRUアルゴリズム」の正体です。
—
4. 近似LRUの仕組みと、神設定 `maxmemory-samples`
Redisは、メモリがいっぱいになって何かを捨てなきゃいけない時、次のようなスマートなサボり方(効率化)をします。
1. メモリ上のデータから、テキトウにいくつか(例えば5個とか)のデータをつまみ食いして選びます。
2. そのつまみ食いしたデータの中で、「一番最後に使われてから時間が経っているもの」を1つだけ選びます。
3. それを容赦なく削除します!
ここで重要になってくるのが、Redisの設定ファイルにある `maxmemory-samples` という項目です。
これは、先ほど言った「一度につまみ食いする数」を指定する設定です。
サンプル数のマジックを知ろう
- `maxmemory-samples 3` の場合:
3個だけデータを覗いて、その中で一番古そうなものを捨てます。
メリット: 計算が一瞬で終わるので、スピードが最速!
デメリット: もしかしたら、もっと古いデータが別の場所にあるかもしれない(精度はそこそこ)。
- `maxmemory-samples 10` の場合:
10個のデータを覗いて、その中で一番古そうなものを捨てます。
メリット: たくさん覗く分、「本当により古いデータ」を見つけやすくなり、精度が上がる。
デメリット: ちょっぴりCPUのパワーを使う(とはいえ、人間には体感できないレベルですが)。
公式のベンチマークや実務の現場では、`5` から `10` あたりに設定されることが多く、これが「スピード」と「精度」の絶妙な黄金バランスと言われています。
—
5. 設定してみよう(Redisの設定)
実際にRedisの設定ファイル(`redis.conf`)やコマンドラインで、この挙動をコントロールしてみましょう。
Redisが使用できる最大メモリを 100メガバイト に制限する
maxmemory 100mb
メモリがいっぱいになった時のポリシーを「近似LRUを使った削除」に指定する
maxmemory-policy volatile-lru
捨てる候補を選ぶときの「つまみ食いする数」を 5 に指定する
maxmemory-samples 5
※ `volatile-lru` は、「有効期限(TTL)が設定されているデータの中から、LRUのルールで古いものを探して消す」という実務でよく使われる安全なポリシーです。
—
6. チーフアーキテクトからの実践的なアドバイス
実務でRedisを運用する際、このLRUの仕組みを知っているだけで、障害を防ぐ大きな武器になります。
1. 「完璧を求めない美学」を理解する
RedisのLRUは「厳密な古い順」ではありません。「だいたい古い順」です。この割り切りがあるからこそ、ミリ秒単位の超高速応答が維持できています。厳密な順序が必要な複雑なログ管理などは、他のデータベース(RDBなど)に任せましょう。
2. メモリに余裕を持たせたサイジングを
`maxmemory-samples` をどれだけチューニングしても、そもそも物理メモリがカツカツすぎると、Redisはひっきりなしにデータの削除と追加を繰り返すことになり(キャッシュミス・ストーム)、パフォーマンスが落ちます。常に最大メモリに対して20〜30%の余裕を持たせる設計がプロの技です。
—
まとめ
いかがでしたでしょうか?
- Redisはメモリを守るために古いデータを捨てる必要がある。
- しかし完璧な順番を調べると遅くなるので、「近似LRU」という賢い手抜きをしている。
- その精度の舵取りをするのが `maxmemory-samples` である。
この仕組みが頭に入っていれば、Redisのメモリ管理はもう怖くありません。
日々の開発やインフラ運用で、ぜひこの「知的なサボり方」の美学を活かしてみてくださいね!
コメント