多核心服务器在G1垃圾回收策略下的卡顿问题处理

两周前,公司IT部门将公司的服务器从48核更换为了96核,其他各方面配置也对应提升,上线第一天,即发现


问题时刻CPU监控信息

这是非常高的cpu_system占用,看了下以往的数据,这个数值一般也就2%,但现在是20%。而从业务系统层面,用户持续感觉到环境卡顿,于是马上开展了环境排查。
经排查,同时刻排除了以下几种情况:
1、IO问题,没有见到明显的IO瓶颈
2、GC问题,不存在特别高频GC,更没有FGC。
3、数据库连接问题

至此,基本可以排除业务系统自身导致出现本问题,问题转向到操作系统方向做排查。

两日后,趁着晚上人少,根据当时的监控图,做了CPU火焰图的抽取,信息如下:


夜间时CPU_System占用仍然很高
同时刻CPU火焰图

从上图可以非常清楚的看到,绝大部分CPU被耗费在了GC上,但,并不是在内存的回收上,而是一段从未见过的堆栈:


主要CPU占用堆栈

一下子走到了我的知识盲区,毕竟,这已经是内核态的方法了,作为一个Java码农,对于Linux内核确确实实就是一只小白。

虽然到这里,已经基本可以确认,当前问题和应用程序无关,但问题到底是什么,如何解决,客户如果遇到怎么办?这几个问题一直萦绕在我脑海里,让我不想放弃对于这个问题的排查。

隔日,开始认真解读这一段堆栈,先拆解放下来

page_fault
do_page_fault
_do_page_fault
handle_mm_fault
do_numa_page
raw_qspin_lock
queued_spin_lock_slowpath
native_queued_spin_lock_slowpath

page_fault是缺页错误,这个是很显然的。但为何GC会走到缺页错误呢?难道是回收内存时,遇到了无法申请到内存页?或者是虚拟内存页指向错误?而且第4层堆栈handle_mm_fault,正好就是内存映射错误的处理,难道真的是无法申请到内存了吗?

没有思路,继续往下看,第5层堆栈,do_numa_fault,查询到了一篇介绍非常详细的文章numa balance

根据这张numa balance的作业流程图


作业流程图

可知,前面的page_fault实际是numa balance的一种特定的执行过程,为了达到多核心就近访问的目的,在linux内核中设置的陷阱,一旦系统发生特定内存页访问时,系统就会陷入内核态中,执行内存页迁移的操作。

因此,我们做了numa关闭的验证,结果发现


numa关闭前后对比图

如上图,cpu_system时间基本归零了,也侧面证明了,这个思路方向是对的。

但,为何这个为了提升多核心访问效率的linux特有行为,为何反而成了系统卡顿的原因呢?所以问题到这里,仍然不算很好的解决,继续向下。

第6行raw_qspin_lock,找不到对应的资料,可能是当前的linux版本的代码跟最新的代码不一致的关系,只找到了raw_spin_lock的解释,其本义,就是spin_lock,也就是本文真正的主角:“自旋锁”。(恨自己英文不好,如果第一时间看懂了,何必要花这么久的时间,泪啊)

走到这里,相信大多数读者都想到问题点所在了。我们都知道自旋锁一种同步策略,常用于资源竞争,但我们也都知道,自旋锁也是尤其局限性的,那就是如果竞争锁的线程比较多时,其性能反而会下降,以至于反倒不如独占锁,这里就不展开了。

这里还有另外一篇文章,也提到了类似的问题,大家可以参考, Why having more and faster cores makes my multithreaded software slower?

于是,读到这里,结合前面的场景,我有了一个猜测:

这是否是一个由Linux操作系统,96核X86CPU服务器以及JVM的GC线程共同导演的一场运行事故呢?

事实可能是这样的:

由于目前应用JVM采取的是G1的垃圾回收策略,而G1的垃圾回收线程数默认是8个,当CPU核心数超过8时,其线程数为8+(核心数-8)5/8,按照目前的服务器则为8+(96-8)5/8=63,当执行垃圾回收时,按照多核心下linux操作系统的逻辑,会执行numa自平衡操作,这里会通过自旋锁进行页表的抢占式竞争,而得不到页表的线程,会等待直至前面的线程完成操作,又因为同一时刻进行抢占的线程非常多,导致了大量的自旋带来的CPU消耗,又因为当前CPU完全陷落在内核态中,用户线程完全无法得到响应,最终导致业务系统出现卡顿的现象。

既然有了这样的猜测,那么解决的方法就很简单了,即,限制最大GC线程数,从而降低自旋锁的竞争度,提高执行效率。于是手动设置GC线程数,即-XX:ParallelGCThreads=24,验证,重启后CPU监控结果如下:


调整GC线程数以后的CPU监控情况

明显可知,CPU_System占用已经降低到了完全不影响用户事情的程度。

为何是24,原因是原系统是48核,经计算,其默认GC线程数为33,为了保险起见,我把线程数定在了24,根据后续验证情况而定。

至此

问题终于得到了比较完美的解决。

为何只是比较,因为这里还有一个场景问题没有回答,即当前环境是X86架构,而我们都知道ARM架构下,多核心是常态,常有96以及192核心的ARM架构服务器,而ARM架构下,指令集比X86架构的指令集更精简,其实现自旋的逻辑是否与X86效率相似,目前没有答案,因此,在ARM架构下,同类问题是否存在以及如何处理,仍然需要机会验证。

这里忍不住要吐槽一下,这个问题在X86的Linux环境下,只要CPU数量足够多,发生这个问题是大概率事件,如果JVM的G1垃圾回收器没有做任何有效的应对和处置,这个开发能力,真是不忍直视,自觉应该找地方给他们提的ISSUE。

同时,也是建议,任何超过48核心的X86架构Linux系统,都务必要关注垃圾回收器的线程数,避免出现此次楼主的尴尬时刻。
当然,这也是为何题目说这是有钱人的烦恼了,因为穷人,谁又会用96核单独跑一个Java进程呢?

其他参考文档:
深入理解Page Fault处理
关于numa loadbance的死锁分析
Linux源码

特别感谢运维负责人:龙波

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容