在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表示内核允许分配超过所有物理内存和交换空间总和的内存