【入門編】 メモリ断片化(Fragmentation) – Redis

こんにちは!Redisの奥深い世界へようこそ。
今日は、現場のエンジニアが思わず「うっ…」と唸る、しかし避けて通れないテーマ「メモリ断片化(Fragmentation)」についてお話しします。

「Redisはメモリが命」なんてよく言われますが、長く運用しているとなぜか『OSから見えているメモリ使用量』と『Redis内部のデータ量』が大きく乖離していく現象に出会います。
今回は、この謎を日常の例えを交えながら、一緒にスッキリ解き明かしていきましょう。

ここをクリアすれば、Redisのメモリ管理の基本はバッチリマスターできますよ!

—

1. まずは結論:`mem_fragmentation_ratio` の正体

Redisの状態を調べるために `INFO memory` というコマンドを叩くと、様々な数値が出てきます。その中にある `mem_fragmentation_ratio`(メモリ断片化率) という項目を見たことはありますか?

これは、次のようなシンプルな計算式で成り立っています。

> `mem_fragmentation_ratio` = OSがRedisに割り当てているメモリ量 ÷ Redis自身が「データで使っている」と認識しているメモリ量

  • 1.0 に近い(または少し高い): 理想的な状態。ムダがありません。
  • 1.5 を超えている: 黄信号。OSから貰ったはいいものの、実際には使えていない「デッドスペース」が増えています。
  • 3.0 を超えている(あるいはそれ以上): 赤信号。メモリの深刻なメタボ状態です。

「OSがくれたメモリ」と「実際にデータがあるメモリ」に、なぜそんな差が生まれるのでしょうか?
次の章で、身近な例えを使ってそのメカニズムを覗いてみましょう。

—

2. 【日常の例え】引っ越し屋さんのダンボール箱で考える断片化

イメージしやすいように、「ダンボール箱を使った荷物の整理」に例えてみましょう。

  • OS = あなたにダンボール箱を支給してくれる大家さん
  • Redis = その箱に荷物を詰めていくあなた
  • メモリ断片化 = 使われていないスカスカの隙間

① 荷物を詰める(データの書き込み)

あなたは日用品をどんどんダンボール箱に詰めていきます。「りんご」「本」「洋服」……。Redisはデータを保存するとき、OSからまとめてドカンとメモリ(ダンボール箱)を確保します。

② 荷物を捨てる(データの削除・有効期限切れ)

しばらくして、「いらなくなった本や洋服を捨てよう!」と思い立ち、ダンボール箱の中からそれらを取り出して捨てました。
すると、どうでしょう? 箱の中には「ぽっかりと空いたスペース(隙間)」ができますよね。

③ そして悲劇が起きる……

ここで、新しく「冷蔵庫のようなめちゃくちゃデカい荷物」が入ってきたとします。
先ほど空いたスペースには、冷蔵庫は入りません。なぜなら、空きスペースが「あちこちにバラバラに散らばっている」からです。

結果として、あなたは「すでにある箱の隙間を使えないから」という理由で、大家さん(OS)に新しいダンボール箱をもう一つ要求することになります。

これが、メモリの断片化の正体です。
データ自体の量は減っているのに、OSから見たメモリの使用量は減るどころか増えていく……という現象が、Redisの内部で起きているのです。

—

3. パフォーマンスへの影響:なぜ断片化を放置してはいけないのか?

「メモリがたくさん余ってるなら、別にいいんじゃないの?」と思ったそこのあなた。甘い、甘いです!

断片化が進むと、以下のような恐ろしい問題を引き起こします。

1. 「メモリ足りませんエラー」の突然の訪問
実際のデータ量はサーバーのメモリ容量に余裕があるはずなのに、OS側で「これ以上メモリを渡せません!」と言われ、Redisが強制終了(OOM Killerによるクラッシュ)させられることがあります。
2. スワップ(Swap)による性能の急降下
OSが「もう物理メモリが足りない!」と判断すると、使われていない(ように見える)メモリの断片を、遅いハードディスク(またはSSD)に追いやり始めます。これをスワップと呼びます。
超高速なインメモリデータベースであるはずのRedisが、ディスクアクセスを挟むことでカクつき、パフォーマンスが地の底まで落ちます。

—

4. どうやってこの「メタボ状態」を解消するのか?

では、断片化が進んでしまったらどうすればよいのでしょうか?
安心してください。現代のRedisには、これを綺麗に片付ける強力な機能が備わっています。

方法A:アクティブデフラグ(Active Defragmentation)を使う(おすすめ)

Redis 4.0以降では、「お片付け機能(Active Defragmentation)」が導入されました。
これは、Redisが稼働している最中に、あちこちに散らばったデータをこっそりと「一つの箱にまとめ直す」という神業のような機能です。

`redis.conf` 設定ファイルで、以下のように有効化できます。

自動断片化解消を有効にする
activedefrag yes

断片化率がこれを超えたら(例: 10%超)片付けを開始する
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-threshold-upper 100

方法B:再起動、またはフェイルオーバー

もし古いバージョンのRedisを使っている場合や、どうしてもメモリを綺麗に掃除したい場合は、計画的な再起動(レプリケーション構成であればフェイルオーバー)が最も確実です。
Redisが再起動されると、OSに一度すべてのメモリが綺麗に返却され、まっさらな状態からデータを再読み込みするため、断片化は綺麗にゼロにリセットされます。

—

5. まとめ

いかがでしたでしょうか?
メモリ断片化は、一見すると難しそうな言葉ですが、要するに「データの出し入れを繰り返すうちに、メモリの使い方が汚部屋になっていく現象」です。

  • `mem_fragmentation_ratio` を定期的に監視する(1.5を目安にする)
  • 怪しい動きを察知したら、アクティブデフラグや適切な運用でケアする

この2つを抑えておけば、あなたの管理するRedisはいつでも軽快に、最高のパフォーマンスを叩き出してくれます。

現場で「お、メモリ管理わかってるね!」と言われるエンジニアを目指して、ぜひ明日の運用から意識してみてくださいね。それではまた!

コメント

タイトルとURLをコピーしました