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

时间:2012-08-01 04:24:40

标签: linux-kernel redis fork

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

              total       used       free     shared    buffers     cached
 Mem:         64433       49259      15174          0          3         31
 -/+ buffers/cache:      49224      15209
 Swap:         8197        184       8012

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

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

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

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

感谢。

3 个答案:

答案 0 :(得分:70)

更具体地说,来自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并不需要像操作系统认为写入磁盘那样多的内存,因此可能会先发制人地使用fork。

答案 1 :(得分:55)

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

vm.overcommit_memory=1

然后使用:

重启sysctl

在FreeBSD上:

sudo /etc/rc.d/sysctl reload

在Linux上:

sudo sysctl -p /etc/sysctl.conf

答案 2 :(得分:20)

来自 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的内容。