MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk

今天第二次遇到Redis 「MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk」的問題。這個錯誤信息是Redis客戶端工具在保存數據時候拋出的異常信息。linux

網上查了一下,不少人都是建議「config set stop-writes-on-bgsave-error no」。這樣作實際上是很差的,這僅僅是讓程序忽略了這個異常,使得程序可以繼續往下運行,但實際上數據仍是會存儲到硬盤失敗!redis

上一次遇到這個問題是由於一個程序的Bug形成系統內存被耗盡了,後來修復了那個Bug問題就解決了。今天出現問題時查看系統內存還有2GB左右,「感受好像不是內存的緣故」(後面發現仍是由於內存的緣故)。工具

因爲Redis是daemon模式運行的,無法看到詳細的日誌。修改配置文件設置logfile參數爲文件(默認是stdout,建議之後安裝完畢就修改這個參數爲文件,否則會丟掉不少重要信息),重啓Redis,查看日誌,看到程序啓動時就有一行警告提示:this

「WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.」(警告:過量使用內存設置爲0!在低內存環境下,後臺保存可能失敗。爲了修正這個問題,請在/etc/sysctl.conf 添加一項 'vm.overcommit_memory = 1' ,而後重啓(或者運行命令'sysctl vm.overcommit_memory=1' )使其生效。)spa

當時沒明白意思,就忽略了。再啓動Redis客戶端,程序保存數據時繼續報「MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk」異常,再查看Redis日誌,看到有這樣的錯誤提示「Can’t save in background: fork: Cannot allocate memory」,這個提示很明顯"Fork進程時內存不夠用了!"(仍是內存的問題)。日誌

經過谷歌查詢「Can’t save in background: fork: Cannot allocate memory」這個提示,找到了解決方法:xml

  1. // 原文:http://pydelion.com/2013/05/27/redis-cant-save-in-background-fork-cannot-allocate-memory/  
  2. If you get this error  
  3.   
  4. Can't save in background: fork: Cannot allocate memory  
  5.   
  6. it means that your current database is bigger than memory you have. To fix the issue enable vm.overcommit_memory:  
  7.   
  8. sysctl vm.overcommit_memory=1  
  9.   
  10. To have if after reboot add this line to /etc/sysctl.cnf:  
  11.   
  12. vm.overcommit_memory=1  

修改vm.overcommit_memory=1後問題果真解決了。htm

爲何系統明明還剩2GB的內存,Redis會說內存不夠呢?進程

網上查了一下,有人也遇到相似的問題,而且給出了很好的分析(詳見:http://www.linuxidc.com/Linux/2012-07/66079.htm),簡單地說:Redis在保存數據到硬盤時爲了不主進程假死,須要Fork一份主進程,而後在Fork進程內完成數據保存到硬盤的操做,若是主進程使用了4GB的內存,Fork子進程的時候須要額外的4GB,此時內存就不夠了,Fork失敗,進而數據保存硬盤也失敗了。內存

相關文章
相關標籤/搜索