在Redis終端上進行讀寫操作,發現唯讀不可寫,GET操作是正常的,SET操作提示錯誤:(error)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.如圖所示:
這一問題通報給營運後得到解決,方法是修改配置為vm.overcommit_memory=1.
原因:
Redis在儲存資料到硬碟時為了避免主進程假死,需要Fork一份主進程,然後在Fork進程內完成資料儲存到硬碟的操作,如果主進程使用了4GB的記憶體,Fork子進程的時候需要額外的4GB,此時記憶體就不夠了,Fork失敗,進而資料儲存硬碟也失敗了。
Linux核心會根據參數vm.overcommit_memory參數的設定決定是否允許存取。
如果 vm.overcommit_memory = 1,直接允許存取。
vm.overcommit_memory = 0:則比較 此次請求分配的虛擬記憶體大小和系統當前閒置實體記憶體加上swap,決定是否允許存取。
vm.overcommit_memory = 2:則會比較 進程所有已指派的虛擬記憶體加上此次請求分配的虛擬記憶體和系統當前的空閑實體記憶體加上swap,決定是否允許存取。
如圖提示這個錯誤:
[13223] 17 Mar 13:18:02.207 # 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.
錯誤提示明確說明瞭解決辦法,也是設定vm.overcommit_memory=1.
Redis核心參數overcommit_memory
它是記憶體配置策略可選值:0、1、2。
0表示核心將檢查是否有足夠的可用記憶體供應用進程使用;如果有足夠的可用記憶體,記憶體申請允許;否則,記憶體申請失敗,並把錯誤返回給應用進程。
1表示核心允許分配所有的實體記憶體,而不管當前的記憶體狀態如何。
2表示核心允許分配超過所有實體記憶體和交換空間總和的記憶體