redis : Can't save in background: fork: Cannot allocate memory

haoge0205發表於2019-12-02

redis : Can't save in background: fork: Cannot allocate memory


JAVA程式報錯資訊:

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日誌:

18793:S 02 Dec 10:02:02.069 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:08.088 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:14.006 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:20.021 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:26.038 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:32.054 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:38.067 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:44.086 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:50.002 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:02:56.017 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:03:02.037 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:03:08.056 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:03:14.073 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:03:20.091 # Can't save in background: fork: Cannot allocate memory

18793:S 02 Dec 10:03:26.007 # Can't save in background: fork: Cannot allocate memory



資料回寫分同步和非同步兩種方式:

同步回寫(SAVE), 主程式直接向磁碟迴寫資料. 在資料量大的情況下會導致系統假死很長時間

非同步回寫(BGSAVE), 主程式fork後, 複製自身並透過這個新的程式回寫磁碟, 回寫結束後新程式自行關閉


由於 BGSAVE 不需要主程式阻塞, 系統也不會假死, 一般會採用 BGSAVE 來實現資料回寫.


redis在dump資料的時候會啟動fork子程式,由於記憶體不夠,導致無法持久化落盤


redis有個預設的選項:

stop-writes-on-bgsave-error yes

這個選項預設情況下,如果在RDB snapshots持久化過程中出現問題,設定該引數後,Redis是不允許使用者進行任何更新操作。


不徹底的解決方式是,將這個選項改為false

stop-writes-on-bgsave-error false

但是這樣只是當redis寫硬碟快照出錯時,可以讓使用者繼續做更新操作,但是寫硬碟仍然是失敗的


徹底解決方案:直接修改核心引數 vm.overcommit_memory = 1

編輯檔案 /etc/sysctl.conf 新增:

vm.overcommit_memory=1

執行sysctl -p使其生效


Linux核心會根據引數vm.overcommit_memory引數的設定決定是否放行。

vm.overcommit_memory = 1,直接放行

vm.overcommit_memory = 0:則比較 此次請求分配的虛擬記憶體大小和系統當前空閒的實體記憶體加上swap,決定是否放行。

vm.overcommit_memory = 2:則會比較程式所有已分配的虛擬記憶體加上此次請求分配的虛擬記憶體和系統當前的空閒實體記憶體加上swap,決定是否放行。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28939273/viewspace-2666454/,如需轉載,請註明出處,否則將追究法律責任。

相關文章