1. 程式人生 > >Redis "MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on

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

今天遇到Redis “MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk”的問題。這個錯誤資訊是Redis客戶端工具在儲存資料時候丟擲的異常資訊。

很多人都是建議“config set stop-writes-on-bgsave-error no”。這樣做其實是不好的,這僅僅是讓程式忽略了這個異常,使得程式能夠繼續往下執行,但實際上資料還是會儲存到硬碟失敗!本人並不推薦這種方式。如果是在自己的電腦做一些練手專案,直接重啟一下虛擬機器就可以了

當然,如果先徹底解決這個問題還有以下的解決方案

由於Redis是daemon模式執行的,沒法看到詳細的日誌。修改配置檔案設定logfile引數為檔案(預設是stdout,建議以後安裝完畢就修改這個引數為檔案,不然會丟掉很多重要資訊),重啟Redis,檢視日誌,看到程式啟動時就有一行警告提示:

“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' )使其生效。)

當時沒明白意思,就忽略了。再啟動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”這個提示,找到了解決方法:

view plaincopy to clipboardprint?

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

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

為什麼系統明明還剩2GB的記憶體,Redis會說記憶體不夠呢?

網上查了一下,有人也遇到類似的問題,並且給出了很好的分析(詳見:http://www.linuxidc.com/Linux/2012-07/66079.htm),簡單地說:Redis在儲存資料到硬碟時為了避免主程序假死,需要Fork一份主程序,然後在Fork程序內完成資料儲存到硬碟的操作,如果主程序使用了4GB的記憶體,Fork子程序的時候需要額外的4GB,此時記憶體就不夠了,Fork失敗,進而資料儲存硬碟也失敗了。