内容简介:没有碰到过 GC 问题的人生对写 Java 的人来说是不完整的。大数据生态圈的框架大都以 JVM 系语言开发(Java Scala 为主),毕竟生态成熟嘛要啥有啥。HDFS 作为大数据领域的默认分布式文件系统,其运作方式导致了非常容易碰到 GC 问题:下面就举两个例子,简单分享下我们做的一些调优。
没有碰到过 GC 问题的人生对写 Java 的人来说是不完整的。大数据生态圈的框架大都以 JVM 系语言开发(Java Scala 为主),毕竟生态成熟嘛要啥有啥。
HDFS 作为大数据领域的默认分布式文件系统,其运作方式导致了非常容易碰到 GC 问题:
-
大量的元数据需要保存在内存中,使得很容易就需要几十 G 甚至 100 多 G 的堆
-
大量且高并发的文件读写操作使得频繁地产生新对象
下面就举两个例子,简单分享下我们做的一些调优。
案例一
有业务同事反馈任务跑的慢,虽然后来确认是其他原因导致的,但在分析过程中,我们从监控观察到 RPC 排队时间和处理时间不是很稳定,有时会出现几秒甚至10多秒的的毛刺,进而注意到 GC。
一分钟一个点,大概每分钟有 2、3秒花在 GC 上。我们用的是经典的 ParNew + CMS 的组合,查看 GC 日志发现大部分都是新生代的 GC,也就意味着有 3% - 5%的时间是 STW 的。这个比例看着不大,但在 NameNode 每秒几 K 甚至几十 K 的事务的压力下,绝对数值和对具体业务的影响还是不能忽视的。
知道了原因,调整就很简单了。从 NameNode 的工作原理分析,大量文件的读写确实会创建很多临时对象,调大新生代就是很自然也很正确的办法。一方面,更大的新生代能减少 minor gc 的次数;另一方面,更多临时对象在新生代回收也减少了晋升到老年代的对象的数量,减少了 CMS GC 的压力。
但还有个不能忽视的问题,NameNode 的元数据会占据非常大的老年代空间,因此新生代也不能调的太大,否则可能触发频繁的 CMS GC 甚至 Full GC。
具体调多大,很显然不会有标准值,只能根据实际数据总量和 TPS 来综合考虑。好在 NameNode 每个元数据的内存占用是确定的,乘以对象数,再留些余量,就能准确计算出老年代需要的内存。剩下的就可以分给新生代了。如果余量不足,也可以考虑适当调大整个堆的大小。
在我们的生产环境下,80+G 的 heap,我们把新生代设置为 12G,到达了可以接受的效果。
除了 GC 时间变为几分之一外,GC 次数也减少了几乎一个数量级,RPC 排队时间的毛刺也减少到百毫秒级别,恶劣情况下 2 秒左右,CMS GC 的次数也减少到 10 多个小时 1 次。
案例二
第一个案例调整过程中,有一天突然收到流量异常的告警,查看 NameNode 监控,发现这样的情况:
大部分监控数据都出现了中断,但 Host CPU Usage 这类机器级别的监控却正常,可以排除监控、机器和网络问题,确定是服务问题。很快发现是发生了一次 Full GC。
我们使用的 ParNew + CMS 组合,发生 Full GC 通常有这么几种原因:
-
主动触发,比如程序调用 System.gc()
-
老年代空间不足,可能是 promotion failed 或者 concurrent mode failure 等
-
永久代空间不足
首先排除 1。而观察日志,老年代空间还很充足,也没有发现 concurrent mode failure 和 concurrent mode failure 这样的 log,Full GC 发生前全是 ParNew GC,都没有发生 CMS GC。
那就只能是 3,永久代空间不足,发生了扩容,导致发生 Full GC。
我们查看了默认的永久代大小:
默认值是 20.75M,实在有点小,和 log 中的值对比,也确实发生了扩容,然后又再次逼近了扩容后的值。
解决方法也很简单,我们把 -XX:PermSize 调整到 256M,并把 -XX:MaxPermSize 设置成一样大,这样初始值够用,也不会再有扩容的问题。
设置上线后,再也没有出现过 Full GC。
这两个案例都不算难,相信大家都能顺利解决。我想更值得总结的是,怎样能更快地解决。
对 GC 的理解,对 NameNode 工作原理的理解,从诸多现象中快速分析出重点,这三点结合在一起才能保证你能迅速解决掉问题。前两点需要平时系统性地学习,最后一点需要点天赋但也能通过不断训练加强。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
正则表达式在线测试
正则表达式在线测试
HSV CMYK 转换工具
HSV CMYK互换工具