IT技术博客大学习 共学习 共进步

linux下redis执行bgsave时,报overcommit_memory错误问题

博学无忧 2016-02-20 16:42:46 浏览 1,603 次
现象

   一台机器如果内存用完,在进行bgsave时,可能会报错。错误信息大概如下:

[1946] 23 Mar 15:21:02.308 # 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.
原因

   当执行redis的bgsave命令时,redis会fork一个进程把redis中的内存数据写入磁盘。这样的好处是,copy on write,有效的节省了内存占用。但是,bgsave时,如果有数据变更,一样需要申请内存。当申请内存时,如果发现内存不够,可能就会报上面的错误。

内核参数overcommit_memory

   参数vm.overcommit_memory控制着linux的内存分配策略。

   这个参数有三个值: 0 1 2

   0 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。 会尽量减少swap的使用,root可以分配比一般用户略多的内存。默认值。

   1 表示根据vm.overcommit_ratio定义的值,允许分配超出物理内存加上交换内存的请求。vm.overcommit_ratio参数是一个百分比,加上内存量决定内存可以超量分配多少内存。例如,vm.overcommit_ratio值为50,而内存有1GB,那么这意味着在内存分配请求失败前,加上交换内存,内存将允许高达1.5GB的内存分配请求。

   2  表示不允许超过CommitLimit值。

   之所以允许申请大于内存的malloc,其中一个原因是,malloc后,并不一定马上使用。

设置方法

   很简单,按提示的操作(将vm.overcommit_memory 设为1)即可:

   有三种方式修改内核参数,但要有root权限:

   (1)编辑/etc/sysctl.conf ,改vm.overcommit_memory=1,然后sysctl -p 使配置文件生效

   (2)sysctl vm.overcommit_memory=1

   (3)echo 1 > /proc/sys/vm/overcommit_memory

   设置完后,可以通过 sysctl -n vm.overcommit_memory 验证设置是否生效。

延伸阅读

OOM

   当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。

   当oom-killer发生时,linux会选择杀死哪些进程?选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该函数会计算每个进程的点数(0~1000)。点数越高,这个进程越有可能被杀死。每个进程的点数跟oom_score_adj有关,而且oom_score_adj可以被设置(-1000最低,1000最高)。

查看内存总量和已用内存

   grep -i commit /proc/meminfo

   看到CommitLimit和Committed_As参数。

   CommitLimit是一个内存分配上限,CommitLimit = 物理内存 * overcommit_ratio(默认50,即50%) + swap大小

   Committed_As是已经分配的内存大小。

建议继续学习

  1. redis源代码分析 - persistence (阅读 32,103)
  2. Redis消息队列的若干实现方式 (阅读 11,925)
  3. 基于Redis构建系统的经验和教训 (阅读 10,381)
  4. 浅谈redis数据库的键值设计 (阅读 9,221)
  5. redis运维的一些知识点 (阅读 8,521)
  6. redis在大数据量下的压测表现 (阅读 8,202)
  7. Redis和Memcached的区别 (阅读 7,942)
  8. redis 运维实际经验纪录之一 (阅读 7,583)
  9. Redis作者谈Redis应用场景 (阅读 7,543)
  10. 记Redis那坑人的HGETALL (阅读 7,321)