系统内存申请策略导致的redis 报错分析

发现在redis的日志中出现如Can't save in background : fork: cannot allocate memory错误,如图:

不难看出这是redis在尝试用子进程进行数据备份时无法从系统中分配到内存的提示(假设fork后父子进程进行了内存数据的复制,当然有copy on write技术的加入实际所需要内存会小),这是由于Linux系统的对程序申请内存时有相关策略控制引起的
redis官方建议的解决方案是把vm.overcommit_memory设置为1
出现这种情况一般满足以下三点:

linux系统预设的阈值可通过grep -i commit /proc/meminfo查看,其中:

Committed_AS: 表示所有进程已经申请的内存总大小
CommittedLIMIT: 所有进程总共可以申请内存+swap的上限值

CommittedLIMIT的计算公式为: (Physical RAM * vm.overcommit_ratio / 100) + Swap
vm.overcommit_ratio默认为50%


关于linux系统对程序进行内存申请的策略控制由vm.overcommit_memory 设置,有三种:

to set the overcommit_memory parameter to 1 temporarily, run the following command:

echo 1 > /proc/sys/vm/overcommit_memory

To set this value persistently, add

vm.overcommit_memory=1

in /etc/sysctl.conf then run the following command:

sysctl -p

参考链接:
https://jingchao.org.cn/2020/03/25/Linux%E4%B8%AD%E7%9A%84Committed_AS%E4%B8%8ECommitLimit.html

https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

https://redis.io/topics/faq#background-saving-fails-with-a-fork-error-under-linux-even-if-i-have-a-lot-of-free-ram

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/performance_tuning_guide/sect-red_hat_enterprise_linux-performance_tuning_guide-configuration_tools-configuring_system_memory_capacity

2021-01-28