発生したエラー内容
開発環境サーバにアクセスすると、突如エラーが発生するようになった。
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に殺られてしまう可能性があるので注意です。