redis : Can't save in background: fork: Cannot allocate memory
專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)海淀免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千多家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
JAVA程序報(bào)錯(cuò)信息:
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
數(shù)據(jù)回寫分同步和異步兩種方式:
同步回寫(SAVE), 主進(jìn)程直接向磁盤回寫數(shù)據(jù). 在數(shù)據(jù)量大的情況下會(huì)導(dǎo)致系統(tǒng)假死很長(zhǎng)時(shí)間
異步回寫(BGSAVE), 主進(jìn)程fork后, 復(fù)制自身并通過(guò)這個(gè)新的進(jìn)程回寫磁盤, 回寫結(jié)束后新進(jìn)程自行關(guān)閉
由于 BGSAVE 不需要主進(jìn)程阻塞, 系統(tǒng)也不會(huì)假死, 一般會(huì)采用 BGSAVE 來(lái)實(shí)現(xiàn)數(shù)據(jù)回寫.
redis在dump數(shù)據(jù)的時(shí)候會(huì)啟動(dòng)fork子進(jìn)程,由于內(nèi)存不夠,導(dǎo)致無(wú)法持久化落盤
redis有個(gè)默認(rèn)的選項(xiàng):
stop-writes-on-bgsave-error yes
這個(gè)選項(xiàng)默認(rèn)情況下,如果在RDB snapshots持久化過(guò)程中出現(xiàn)問(wèn)題,設(shè)置該參數(shù)后,Redis是不允許用戶進(jìn)行任何更新操作。
不徹底的解決方式是,將這個(gè)選項(xiàng)改為false
stop-writes-on-bgsave-error false
但是這樣只是當(dāng)redis寫硬盤快照出錯(cuò)時(shí),可以讓用戶繼續(xù)做更新操作,但是寫硬盤仍然是失敗的
徹底解決方案:直接修改內(nèi)核參數(shù) vm.overcommit_memory = 1
編輯文件 /etc/sysctl.conf 添加:
vm.overcommit_memory=1
執(zhí)行sysctl -p使其生效
Linux內(nèi)核會(huì)根據(jù)參數(shù)vm.overcommit_memory參數(shù)的設(shè)置決定是否放行。
vm.overcommit_memory = 1,直接放行
vm.overcommit_memory = 0:則比較 此次請(qǐng)求分配的虛擬內(nèi)存大小和系統(tǒng)當(dāng)前空閑的物理內(nèi)存加上swap,決定是否放行。
vm.overcommit_memory = 2:則會(huì)比較進(jìn)程所有已分配的虛擬內(nèi)存加上此次請(qǐng)求分配的虛擬內(nèi)存和系統(tǒng)當(dāng)前的空閑物理內(nèi)存加上swap,決定是否放行。