redis bgsave失败,因为fork无法分配内存

Jim*_*ray 46 fork linux-kernel redis

all:这是我的服务器内存信息'free -m'

              total       used       free     shared    buffers     cached
 Mem:         64433       49259      15174          0          3         31
 -/+ buffers/cache:      49224      15209
 Swap:         8197        184       8012
Run Code Online (Sandbox Code Playgroud)

我的redis-server使用了46G内存,剩下几乎15G的内存空闲

据我所知,fork是写入时的副本,当有15G可用内存时它不应该失败,这足以malloc必要的内核结构.

此外,当redis-server使用42G内存时,bgsave还可以,fork也可以.

是否有任何vm参数我可以调整以使fork返回成功?

谢谢.

Jef*_*ood 77

更具体地说,来自Redis FAQ

Redis后台保存模式依赖于现代操作系统中fork的copy-on-write语义:Redis forks(创建子进程),它是父进程的精确副本.子进程将数据库转储到磁盘上,最后退出.理论上,孩子应该使用尽可能多的内存作为副本,但实际上由于大多数现代操作系统实现的写时复制语义,父和子进程将共享公共内存页.只有在子页面或父级页面中发生更改时,页面才会重复.由于理论上所有页面都可能在子进程保存时发生变化,因此Linux无法预先知道子进程将占用多少内存,因此如果将overcommit_memory设置设置为零,则fork将失败,除非有尽可能多的可用RAM需要真正复制所有父内存页面,结果是如果你有一个3 GB的Redis数据集和2 GB的可用内存,它将失败.

将overcommit_memory设置为1表示Linux放松并以更乐观的分配方式执行fork,这确实是你想要的Redis.

Redis不需要像操作系统认为写入磁盘那样多的内存,因此可能会先发生故障.


Gan*_*nan 63

修改/etc/sysctl.conf并添加:

vm.overcommit_memory=1
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令重启sysctl:

在FreeBSD上:

sudo /etc/rc.d/sysctl reload
Run Code Online (Sandbox Code Playgroud)

在Linux上:

sudo sysctl -p /etc/sysctl.conf
Run Code Online (Sandbox Code Playgroud)


Uto*_*oah 29

proc(5)手册页:

的/ proc/sys目录/ VM/overcommit_memory

此文件包含内核虚拟内存记帐模式.价值观是:

0:启发式过度使用(这是默认值)

1:总是过度使用,永远不要检查

2:经常检查,永远不要过度使用

在模式0中,不检查具有MAP_NORESERVE设置的mmap(2)的调用,并且默认检查非常弱,导致获得进程"OOM-killed"的风险.在Linux 2.4下,任何非零值都意味着模式1.在模式2(从Linux 2.6开始提供)中,系统上的总虚拟地址空间限制为(SS + RAM*(r/100)),其中SS是大小交换空间的大小,RAM是物理内存的大小,r是文件/ proc/sys/vm/overcommit_ratio的内容.