Redisで発生したメモリ不足エラーの調査メモ


発生したエラー内容

開発環境サーバにアクセスすると、突如エラーが発生するようになった。

MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.

原因は、サーバのメモリ不足により、Redisがデータ保存できない状態だった。(getは問題なし)
調査した経緯をメモ。

Redisのログを確認

エラーメッセージに「Redis」とあるので、Redisのログを見てみる。
以下のようなログがいっぱい出力されていた。

[30198] 02 Sep 17:13:22.092 * 10 changes in 300 seconds. Saving...
[30198] 02 Sep 17:13:22.100 # Can't save in background: fork: Cannot allocate memory

redis.confを確認。この設定によるデータ永続化保存時のエラーらしい。

save 300 10

サーバのメモリを確認

どうやらメモリっぽいので、サーバのメモリを確認してみる。

$ cat /proc/meminfo
(略)
MemTotal:        2052728 kB
MemFree:          164416 kB
(略)

たしかにメモリは不足ぎみだが、空きが160Mあるので、致命的には見えない。

Redisの使用メモリを確認

Redisの使用メモリも確認してみる。

$ redis-cli info
(略)
# Memory
used_memory:235072168
used_memory_human:224.18M
(略)

Redisのメモリについて調査

Redisのメモリについて調べていたら、本家サイトに書いてあった。
http://redis.io/topics/admin

If you are using Redis in a very write-heavy application, while saving an RDB file on disk or rewriting the AOF log Redis may use up to 2 times the memory normally used.

AOFログ保存時に、Redisが通常の2倍のメモリを使用するとのこと。

結論

Redisがデータ永続化のために、AOFログ保存を行う際にメモリの割り当て(allocate)を行おうとしたが、使用可能メモリが不足していたため、エラーになったとのこと。
今回は、開発環境ということもあり、オーバーコミットを有効にして回避しました。

$ vi /etc/sysctl.conf
# ↓追加
vm.overcommit_memory=1

本番環境などでこの設定にしてしまうと、RedisプロセスがOOMKillerに殺られてしまう可能性があるので注意です。

[参考]
Linux のオーバーコミットについて調べてみた

  • このエントリーをはてなブックマークに追加