linux服务器lowmem不足引起系统崩溃的解决

来源:互联网 发布:双立人去味皂淘宝 编辑:程序博客网 时间:2024/03/29 06:10

近日,一台linux的mq服务器频繁发生队列管理器被异常终止的情况,查看mqlog得知mq关键进程被异常终止,查看/var/log/messgaes中的信息得知,mq进程被oom-killer杀掉。但该服务器内存空余一直很多,遂进行进一步分析。


linux将内存分为DMA区、lowmem区及highmem区(zone),其中dma区及lowmem区的大小默认是固定的。经过对于日志的仔细分析,及使用free -lm命令分区域查看系统剩余内存,发现lowmem剩余不足20M,虽然highmem剩余很多,但是由于许多kernel程序只能在lowmem中运行,当lowmem剩余不多时,也会触发oom-killer来杀掉一部分进程保证系统的正常运行。这也是我们机器上出现的情况。


需要注意的是,当看到日志中关于oom-killer的报错时,很多文章建议在oom-killer的参数上做文章,如改变overcommit_memory和overcommit_ratio的值,等等。但是此处的问题不是还有内存的情况下被overcommit了,而是lowmem确实不足了,因此并不适用,如果一不注意改了后果可能十分严重。(顺便提一下有篇关于overcommit的很好的文章, http://url.cn/Duklig  )。


针对lowmem不足的问题,主要有以下三种解决方案:

1、升级至64位系统,64位系统中,所有内存都被划分为lowmem,彻底解决了lowmem不足的问题,可惜我们服务器由于客观条件限制,无法进行该项升级;

2、升级至hugemem内核,可以将lowmem的范围扩大,这也是redhat推荐的方法(http://url.cn/BJD0w7),但对于我们的sles来说同样不适用;

3、更改系统配置,将更多的程序分配至highmem区,这是目前状态下最好的方法了。在不同版本的内核上该文件不同,如 lower_zone_protection或者lowmem_reserve_ratio等,在我们的机器上为后者。使用echo命令将新的参数写入即可。

需要注意的是lowmem_reserve_ratio参数的含义。当发起内存请求时,系统会从低段区域开始,逐级尝试进行内存分配(这句属于看了官方文档后的个人理解,个人认为原因是为了充分利用内存空间,避免出现高位内存被大量使用,而低位内存没有使用的浪费情况)。会将该区的水印值(watermark,含义暂时没查清楚,待完善)与protection值相加,如果free pages小于该数值,则不在该区域进行内存分配,会被依次向更高区域申请。而protection数值就是由lowmem_reserve_ratio数值来计算的,计算方法为该区域以上所有区域内存总页数除以lowmem_reserve_ratio的数值。也就是,排除掉watermark因素之后,lowmem_reserve_ratio的数值为权衡时所使用的当前区域以上区域内存的比例。显然是该数值越低,则protection值越大,则更不容易在当前区域进行分配。

最后,附几个命令:
查看分区域的系统内存情况:
free -l
查看各个zone的protection数值:
cat /proc/zoneinfo | grep "zone\|protection" 
写入 lowmem_reserve_ratio数值:
echo "128 128 32" > /proc/sys/vm/lowmem_reserve_ratio
久更改lowmem_reserve_ratio数值:

编辑 /etc/sysctl.conf 并添加

vm.lowmem_reserve_ratio = 256 512 32
(此处很奇怪,如果将该数组加双引号,则更改无效) 

# sysctl -p 
原创粉丝点击