作者:范欣欣,网易杭研大数据技术专家
问题背景
网易杭研作为网易互联网技术底座,提供了HBase在内的大数据技术支持。近期,某业务HBase集群之前使用CMS GC,在某些离线请求量非常大的场景下,会出现长时间的Promotion Failure类型的FGC,导致RegionServer宕机。Promotion Failure类型的FGC发生大多是因为系统长时间运行后产生大量的内存碎片,导致没有完整的一片可用内存。为了防止这种情况发生,尝试使用G1GC代替CMS GC,理论上可以解决Promotion Failure类型的FGC。
问题现象
改成G1GC后,业务线上HBase集群一个分组的RegionServer发生了FGC,导致节点宕机,服务受到一定影响。网易杭研大数据团队查看了对应的GC日志,如下图所示:
![34f4f79ed2783800f4988a65da864896.png](https://i-blog.csdnimg.cn/blog_migrate/fd5d97f004d379a7c50f62104bb76a84.jpeg)
问题分析
分析日志,网易杭研大数据团队基本上确认JVM在GC的时候依然不断地进来数据,导致内存无法分配,最终导致Full GC。这里面有两个原因,其中之一是MixGC触发的时机不对,本实例设置的最大内存为40g,InitiatingHeapOccupancyPercent值为65,理论上所占内存达到40g*65%=26g的时候就应该执行MixGC。但实际上JVM执行MixGC的时候内存已经占用到了34g。如下图:
![6b01106295a42343cdfeb72ed45bd109.png](https://i-blog.csdnimg.cn/blog_migrate/d73b77117aa445b50881ca224b49319c.png)
为什么会这样?很简单,JVM就是需要这么多内存,没有多少内存垃圾可以GC出来。怎么确认需要这么多内存呢?看了下Memstore的大小就确认了:
![4706bd711e82af90bae84859f813fef1.png](https://i-blog.csdnimg.cn/blog_migrate/7d797ee48d6d4e2a7040c85bf2fd1c62.jpeg)
在高峰期光Memstore就需要25G的内存,已经达到了InitiatingHeapOccupancyPercent阈值所规定的的MixGC执行阈值,这还不算读缓存以及预留的10%~20%内存。可见,JVM就是需要36G那么多内存,GC不下去属于正常情况,一旦在GC的时候进来大量数据,就很有可能导致所有内存都被耗尽,最终FGC。
为什么MemStore占用那么多?答案也很简单,这个RegionServer上的region很多,达到了559个,一个region最大占用128M内存,25G内存也是容易达到的。
解决方案
这种FGC如何避免呢?网易杭研大数据团队建议做如下2点优化:
- 内存需要增大,从40g增大到60g
- 留给Memstore的26g不变,这样hbase.regionserver.global.memstore.size需要从0.65调整成0.45
业务实践证明,经过这样的调整后,65%的InitiatingHeapOccupancyPercent可以不用变,基本上可以满足JVM需求,不会发生FGC。
注:G1GC是一个需要根据业务不同,最典型的是Xmx总内存大小需要根据Memstore占用总内存大小的不同进行设置,占用内存越大,设置的总内存大小就越大,防止出现内存不够导致FGC发生。