エラーの内容Redisは、すべてをRAM上に保持することで高速動作するように設計されています。しかし、そのRAMがいっぱいになると動作が停止します。このエラーが表示される場合、アプリケーションがすでに「ハードリミット(上限)」に達しているRedisインスタンスにデータを書き込もうとしたことを意味します。
(error) OOM command not allowed when used memory > 'maxmemory'
本質的に、Redisは設定で定義された maxmemory 制限に達しており、現在の設定では新しいデータを入れるために古いデータを削除することが許可されていません。安全策として、ほとんどのコマンドに対して読み取り専用モードになります。
即時の診断ログがOOMエラーで埋め尽くされ始めたら、すぐにメモリの内訳を確認します。インスタンスに接続して以下を実行してください。
redis-cli info memory
特に以下の3つの指標に注目してください:
used_memory_human: 実際のデータサイズ(例: 1.95G)。-maxmemory_human: 設定されている制限(例: 2.00G)。-maxmemory_policy: 通常、これが原因です。ポリシーがnoevictionに設定されている場合、Redisはキーを自動的に削除しません。手動でスペースを確保するか制限を増やすまで、すべての新しい書き込みを拒否します。
ステップバイステップの修正方法### 1. 応急処置: 制限を引き上げるサーバーに物理RAMの余裕がある場合(例: 4GBのVPSで2GBしか使用していない場合)、制限を引き上げることで即座にサービスを再開できます。この変更は再起動なしでリアルタイムに反映されます:
# 3ギガバイトに増やす
redis-cli config set maxmemory 3gb
新しい制限が有効であることを確認します:
redis-cli config get maxmemory
2. データクリーンアップの自動化 (エボリューションポリシー)RAMを増やすのは一時的な修正です。持続可能なセットアップのためには、バケットがいっぱいになったときに古いデータを削除するエボリューション(追い出し)ポリシーが必要です。ほとんどのキャッシュのユースケースでは、最も長く使われていないキーを最初に削除する allkeys-lru が標準的な選択肢です。
redis-cli config set maxmemory-policy allkeys-lru
一般的なポリシーの実際の動作は以下の通りです:
- allkeys-lru: 空きを作るために、最も古く、使用頻度の低いキーを破棄します。ほとんどのキャッシュに最適です。- volatile-lru: 有効期限(TTL)が設定されているキーのみを削除します。TTLの設定を忘れている場合は危険です。- allkeys-random: キーを無作為に選択して削除します。データの鮮度が重要でない場合にのみ使用してください。### 3. 設定を恒久化する
redis-cliによる変更は、サーバーが再起動すると消えてしまうことを忘れないでください。通常/etc/redis/redis.confにある設定ファイルを更新する必要があります。
sudo nano /etc/redis/redis.conf
# 以下の行を探して更新します:
maxmemory 3gb
maxmemory-policy allkeys-lru
ファイルを保存します。すでにCLI経由で変更を適用しているため、今すぐサービスを再起動する必要はありません。
4. メモリを大量消費している原因を特定する原因は制限が小さいことではなく、一つの巨大なキーである場合があります。 --bigkeys ツールは、データベースをスキャンして最大の文字列、リスト、またはセットを見つけ出します。 SCAN コマンドを使用するため、サーバーをブロックすることはありませんが、念のためトラフィックの少ない時間帯に実行してください。
redis-cli --bigkeys
500万個のメンバーを持つ単一の「Set」が見つかった場合、それがメモリリークの原因です。
確認テスト用のキーを設定して、書き込みロックが解除されたか確認します:
redis-cli set health_check "ok"
OK と表示されれば、アプリケーションは再び書き込み可能です。通常、私はその後に60秒間メモリの傾向を監視します:
redis-cli --interval 1 --stat

