【入門編】 OOM(Out Of Memory)の挙動 – Redis

こんにちは!Redisの世界へようこそ。
システム開発の現場で「高速なキャッシュ」として引っ張りだこのRedisですが、実はちょっとお茶目で、同時に「めちゃくちゃ几帳面で頑固な一面」を持っているのを知っていますか?

今回は、Redisのメモリ管理の心臓部である「OOM(Out Of Memory:メモリ切れ)」と、そこでの振る舞いについて、シニアエンジニアの視点から優しく、そして深く解説していきますね。

ここをクリアすれば、Redisのメモリまわりの挙動はバッチリマスターできますよ。肩の力を抜いて、一緒に見ていきましょう!

—

1. Redisにとっての「メモリ」は、私たちの「机の広さ」

まず、Redisがどうやって動いているのかをイメージしてみましょう。
Redisは、すべてのデータをハードディスクではなく「メモリ(RAM)」の上に置いています。だからこそ、電光石火の速さでデータを読み書きできるわけです。

これを、あなた専用の「デスク(机)」だと想像してください。

  • Redis(プロセス):「この机の上だけで仕事をしてね」と言われている。
  • maxmemory(最大メモリ設定):その机の物理的な広さの限界。

新人エンジニアの頃によやりがちなのが、「限られた広さの机の上なのに、次から次へと書類を山積みにしてしまう」というミスです。Redisでも全く同じことが起きます。設定された限界値(maxmemory)を超えてまで、新しいデータを置くことはできないのです。

—

2. 机がいっぱいになった時、Redisはどうする?

では、Redisの「机(maxmemory)」がパンパンに埋まった状態で、あなたが「新しいデータ(書類)を置いて!」と命令したら、Redisは一体どうするでしょうか?

ここで重要になるのが、Redisの頑固なポリシーです。
設定によりますが、一般的なデフォルトや安全重視の設定の場合、Redisはこう言います。

> 「もう机の上には1ミリも隙間がありません!新しいものは一切置きません!これ以上置いたら崩れちゃうから、書き込みは拒否します!」

これが、RedisにおけるOOM(メモリ上限到達)時の挙動です。
Redisは、勝手に古い大切なデータをゴミ箱にポイ捨てしたりしません(もちろん、そういう設定にすることもできますが)。基本的には、「これ以上データを増やして、システム全体をクラッシュさせるわけにはいかない」という防衛本能から、書き込み系(`SET`など)のコマンドに対してエラーを返すようになります。

実際のRedisのエラーを見てみよう

もしこの状態のRedisに書き込もうとすると、クライアント(アプリ側)には次のようなエラーが返ってきます。

RedisのCLIから新しくデータを書き込もうとした例
127.0.0.1:6379> SET user:1001 “Taro”
(error) OOM command not allowed when used memory > ‘maxmemory’.

出ました!これが噂の `OOM command not allowed` エラーです。
「おいおい、メモリの上限を超えてるから、そのコマンドは実行させないよ」というRedisからの強烈なメッセージですね。読者の皆さんも、実務でこのエラーに出会ったら「お、机が満杯だな」と慌てずに状況を把握してください。

—

3. アプリケーション側はどう迎え撃つべきか?(エラーハンドリングの重要性)

さて、Redisがこうして頑固に書き込みを拒否した時、あなたの作ったWebアプリケーション側では何が起きるでしょうか?

もし、アプリ側がこのエラーを想定していないとどうなるでしょう?
「ユーザーがボタンを押す ➔ アプリがRedisにデータを保存しようとする ➔ Redisが `OOM` エラーを返す ➔ アプリが真っ白な画面(500エラー)になってクラッシュする」という、最悪のユーザー体験を生み出してしまいます。

だからこそ、クライアント側での丁寧なエラーハンドリング(例外処理)が絶対に不可欠なのです。

アプリケーションコードのイメージ(Pythonの例)

例えば、PythonからRedisを操作する時は、このように「メモリがいっぱいになった時の逃げ道」を作ってあげます。

import redis

Redisに接続
client = redis.Redis(host=’localhost’, port=6379, decode_responses=True)

try:
# データを書き込もうとする
client.set(“user:1001”, “Taro”)
print(“データの保存に成功しました!”)

except redis.exceptions.ResponseError as e:
# Redisからエラーが返ってきた場合のキャッチ
if “OOM” in str(e):
print(“【警告】Redisのメモリが限界を迎えています!緊急対応が必要です。”)
# ここで古いキャッシュを消す処理を呼ぶか、DBに直接書き込むなどのフォールバックを行う
else:
print(f”その他のRedisエラー: {e}”)

このように、エラーを優しく受け止めて、アプリが完全に止まってしまわないように設計するのが、プロのエンジニアの技の見せ所です。

—

4. 先輩エンジニアからの処方箋:OOMを防ぐために

最後に、Redisがこの「OOMの悲劇」を起こさないために、実務で私たちがどんな対策をしているのか、こっそり教えちゃいますね。

1. メモリの限界(maxmemory)を正しく設定する
サーバーの物理メモリすべてをRedisに使わせてはいけません。OSの動作領域も必要なので、余裕を持ったサイズ(例:サーバーの7割程度)を `redis.conf` の `maxmemory` に指定しましょう。
2. 追い出し方針(maxmemory-policy)を決めておく
「机がいっぱいになったら、最近使っていない古いデータから自動で捨てていいよ」というルール(`allkeys-lru` など)をあらかじめ設定しておくと、Redisは書き込みを拒否する代わりに古いデータを掃除してスペースを作ってくれます。用途に合わせて使い分けましょう。
3. 定期的なモニタリング
「今、机の何パーセントが埋まっているか」を監視ツール(PrometheusやGrafanaなど)で常に見張っておくこと。これが一番の予防薬です。

—

まとめ

いかがでしたでしょうか?
RedisのOOMは、一見すると怖いエラーに見えますが、「システム全体の崩壊を防ぐためにRedisが発してくれている大切なアラート」です。

  • Redisのメモリは有限(机の広さと同じ)。
  • 限界を超えると、Redisは頑固に書き込みを拒否する(OOMエラー)。
  • アプリ側では、その拒否を想定して優しく受け止める(エラーハンドリング)が超重要。

この基本原則さえ押さえておけば、もうRedisのメモリ管理で迷うことはありません。
明日からの開発に、ぜひこの知見を生かしてみてくださいね。応援しています!

コメント

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