54

all:这是我的服务器内存信息,带有“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 返回成功吗?

4

3 回答 3

93

更具体地说,来自Redis FAQ

Redis 后台保存模式依赖于现代操作系统中 fork 的写时复制语义:Redis forks(创建子进程)是父进程的精确副本。子进程将数据库转储到磁盘上并最终退出。理论上,子进程应该使用与作为副本的父进程一样多的内存,但实际上由于大多数现代操作系统实现的写时复制语义,父进程和子进程将共享公共内存页面。仅当页面在子级或父级中发生更改时,才会复制页面。由于理论上所有页面都可能在子进程保存时发生变化,Linux 无法提前知道子进程将占用多少内存,因此如果将 overcommit_memory 设置设置为零,除非有足够的可用 RAM,否则 fork 将失败需要真正复制所有父内存页面,

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

Redis 不需要操作系统认为它写入磁盘所需的内存量,因此可能会先发制人地使 fork 失败。

于 2015-04-23T21:11:58.283 回答
75

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

vm.overcommit_memory=1

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

在 FreeBSD 上:

sudo /etc/rc.d/sysctl reload

在 Linux 上:

sudo sysctl -p /etc/sysctl.conf
于 2016-06-08T00:03:27.447 回答
32

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

于 2012-08-01T05:02:42.133 回答