最近发现我们的hadoop集群的客户端机器负载经常飙到几百,导致机器反应很慢, 客户反应无法提交job,或者job跑的很慢。

针对这种情况通常有几个解决方案,一个是增加客户端机器数量,把他们做到一个pool里面,根据系统负载情况来自动切换不同的客户端机器,也叫负载均衡这个我们已经做到了;一个是找出负载高的根源,因为如此高的负载是很不寻常的表现,通常是因为系统参数不对或者应用程序有bug。

现象

用perf top观察占用最多cpu time的程序,发现大部分是compaction.c这个程序造成的。

可以通过如下命令抓取一分钟的记录看下:

$ sudo perf record -a -g -F 1000 sleep 60

这里借用Brendan Gregg’s的工具 flame graph 分析下抓取的数据。

google查看后了解compaction.c 是与Transparent Huge Pages 相关的一个程序,简称THP,THP是Redhat6 以后出现的功能,目的有两个,一个是整理物理内存的碎片,应用程序在请求内存的时候可以分到2MB的内存(正常是4KB);一个是应用程序分配到的内存不能被交换到swap。

这个特性当然用它的应用场景,但不是任何情况下都是好的,所以要视情况而决定要不要打开此功能。

很明显在系统负载如此高的情况下,大部分cpu time都是在整理内存碎片,因此果断取消此功能。

echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled

echo never > /sys/kernel/mm/redhat_transparent_hugepage/defrag


取消后过了一会就看到了效果,负载下来了,通过打开此功能后负载又上去了,如此问题彻底解决了。


下面介绍另外一种场景,需要打开THP功能的。

某日发现oracle机器的内存几乎被用完,但正常情况下不是这样的,通过cat /proc/meminfo 发现Pagetables 居然有5GB,太离谱了,pagetables 是映射虚拟内存和物理内存地址关系的tables,这些表太多了,通过开启THP,结果pagetables降到了一百多MB的水平。

在实际场景下要看情况对待。