こんにちは!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はいつでも軽快に、最高のパフォーマンスを叩き出してくれます。
現場で「お、メモリ管理わかってるね!」と言われるエンジニアを目指して、ぜひ明日の運用から意識してみてくださいね。それではまた!
コメント