搜索
查看: 3642|回复: 2
收起左侧

[安全行业] hadoop集群System Cpu消耗过高问题分析

[复制链接]
我爱我听
发表于 2013-4-2 22:02:29 | 显示全部楼层 |阅读模式
Hadoop集群服务器升级为rhel6内核后,System Cpu占用非常高,有任务运行的时候经常到50%以上。对其中一台机器一天的运行状态采样的数据:
idle: 76%   sys:14%  user: 9%
从采样数据中,可以发现System CpuUser Cpu还要高,这在Hadoop集群环境中很不寻常。
先简单地用strace看了一下占用cpu高的java程序经常去调哪些系统调用,发现sched_yield调用频率非常之高,莫非是锁的问题?分析了下内核中的文档和代码,发现CFS调度下sched_yield的行为与以前的O(1)算法略有出入——CFSsched_yield返回非常快,对于一些借助sched_yield实现锁的应用来说,开销会很大。内核提供了一个proc参数sched_compat_yield,设置该参数为1,就可以解决这个问题。于是设置了该参数,仍然没有效果,分析代码后,竟然发现sched_compat_yieldrhel6内核中并没有实现,只是留下了一个接口兼容而已。于是乎将upstream中的相关部分的代码portrhel6的内核中,sched_compact_yield终于能干活了,但出乎意料的是,系统态cpu仍然非常高。
没办法了,上个大招:oprofile,结果如下:
samples         %          symbol name
2822865   71.2192    compact_zone
160729     4.0551       clear_page_c
156913      3.9588      compaction_alloc
47691        1.2032       copy_user_generic_string
一看到结果,一头雾水。compact_zone为何物?为何cpu占用如此之高?不懂了就看代码。
__alloc_pages_slowpath
__alloc_pages_direct_compact
try_to_compact_pages
compact_zone_order
compact_order
有点头绪了,内核要分配一块高阶物理内存,buddy system中又没有满足条件的,似乎内核要在compact_zone中做些什么事,来满足对高阶物理内存的分配。
下一步,快速验证下是不是compact_zone的问题,修改config文件,去掉CONFIG_COMPACTION,重新编译,换内核,竟然真的OK 那基本断定是compact_zone的问题了,后面就得分析下代码,研究下其中的原理了。
经过几天的艰苦奋战,终于把compaction的基本原理搞明白了。
linux物理内存的管理采用的是经典的伙伴系统,当然也就存在伙伴系统的问题——内存碎片。当然,此处的内存碎片问题并不算大,因为伙伴系统是以页为单位为管理内存的,碎片也是以为单位,4k的物理内存还算不上是碎片。对于用户态的程序,几乎不需要超过4k的连续空间。但是对内核来说,碎片永远都不是好东西。某些硬件相关的操作会需要连续的物理内存,如果无法满足,内核就只能panic
1.jpg
那哪些页面是可以移动的呢? 非空闲的物理内存,当然要么是用户态进程在用,要么内核本身在用。对于前者,进程在访问物理内存的时候,实际上要通过页表的映射来访问。页表是一个可以做文章的地方:如果把一个页移动到另一个地方,如果可以同时修改页表,那么对应用程序就不会有影响。而对于内核访问物理内存时,是通过简单的常量偏移来做的。因此内核使用的物理页面无法移动。
定义了可移动的页面,具体到某一个页面,内核怎样知道它是否是可移动的?分配内存的函数,kmalloc,alloc_pages等在任何地方都可能被调用。内核又是怎样知道在这些地方分配的页面属于哪种类型呢?看这几个函数的原型
void *kmalloc(size_t size, gfp_t flags)
struct page * alloc_pages(gfp_t gfp_mask, unsigned int order)
内核自然不知道kmalloc分配的内存是作什么用途的,但是kernel 开发者知道,一个页面是否可移动,自然也是开发者们告诉内核的。gft_t中有个标志位:GFP_MOVABLE,开发者需要根据相应的内存是否要移动来设置该位。
了解了如何识别可移动页面,下面看看页面移动的流程:
1.         锁定页,以避免在移动页的过程中有进程修改页面。页面记为oldpage
2.         确保“writeback”已经完成
3.         删除当前页面的全部映射,并将指向该页的页表项标记MIGRATION
4.         查找新页,记为newpage
5.         获取radix tree的锁,以阻塞所有试图通过radix tree来访问页面的进程。将radix treeoldpage的指针指向newpage。释放radix tree的锁。
6.         旧页的内容被拷到新页面中,设置新页面的各项标志
7.         将所有页表项指向新页面
了解了compaction的目标和原理,那么该怎样查看系统中当前的碎片情况呢?/proc/pagetypeinfo文件提供了可移动不可移动页面的分布数据, 一方面方便开发者调试,另一方面可以让系统管理员了解当前的系统运行状态。
Compactionhadoop上所带来的性能问题,目前还不知道是在这种特定场景下才出现还是compaction本身就影响了性能。不过现在看来,在其它机器上还没有发现这种情况。
Compaction的目的是减少内存碎片,主要和THP搭配使用,适合需要大量连续内存的应用,比如KVM,能提升TLB效率和减少page fault次数,从而提高应用程序的执行效率。因此,去掉Compaction的支持,会对此类应用的性能所有影响。
参考:http://lwn.net/Articles/359158/
冷冷的夜
头像被屏蔽
发表于 2013-4-3 16:42:22 | 显示全部楼层
这样的说呢
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛|卡饭乐购| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 苏ICP备07004770号 ) GMT+8, 2019-8-26 02:42 , Processed in 0.049187 second(s), 6 queries , MemCache On.

快速回复 返回顶部 返回列表