【大内存服务GC实践】- 一文看懂G1GC垃圾回收器

一. 背景介绍

笔者在这个系列的第一篇文章《一文看懂"ParNew+CMS"垃圾回收器》中详细介绍了"ParNew+CMS"垃圾回收器的工作原理。文章最后笔者提到CMS垃圾回收器有两个比较显著的问题,一个是长时间运行无法避免Full GC,一个是Remark阶段STW时间较长。正是因为这两个问题的存在,CMS垃圾回收器在JDK9被标记弃用,慢慢开始退出历史舞台。有走的,就有来的,JVM重新设计了另一款垃圾回收器G1,有效地解决了CMS垃圾回收器遇到的上述两大问题。那么,这篇文章我们就详细探讨一下G1垃圾回收器是如何解决上述两大问题的。
和上篇文章介绍"ParNew+CMS"垃圾回收器一样,笔者会从G1垃圾回收器最基础的数据结构和算法出发,深入分析它的工作原理,对其中的一些关键机制进行剖析。

二. G1回收器核心数据结构

1.1 Regio

为什么CMS垃圾回收器长时间运行无法避免FGC?本质是因为CMS垃圾回收器中老年代采用标记清理算法,这种算法会产生较多内存碎片,当内存碎片很碎无法给对象分配出连续空间的时候,JVM就会触发FGC整理老年代。那有些同学就会问为什么不在每次老年代GC的时候执行整理操作呢?这主要是因为老年代如果很大的话,整理一次STW的时间会不可控。那怎么破这个局呢?JVM设计者提出了一个思路老年代不是很大吗,那就将老年代划分成很多小的格子,在此基础上GC算法基本不变,还是先标记,不过在标记完成后,按照优先级选择部分格子使用复制算法进行整理,这样每次整理的内存空间是可控...

继续阅读

【大内存服务GC实践】- “ParNew+CMS”实践案例 (一)- NameNode YGC诊断优化

这是"大内存服务GC实践"的第三篇文章,前面两篇文章分别系统地介绍了"ParNew+CMS"组合垃圾回收器的原理以及FullGC的一些排查思路。分别见
  1. 【大内存服务GC实践】- 一文看懂”ParNew+CMS”垃圾回收器
  2. 【大内存服务GC实践】- “ParNew+CMS”实践案例 : HiveMetastore FullGC诊断优化
本篇文章重点结合生产线上NameNode RPC毛刺这个现象,分析两起严重的YGC问题。NameNode是HDFS服务最核心的组件,大数据任务读写文件都需要请求NameNode,该服务一旦出现RPC处理毛刺,就可能会引起上层大数据平台离线、实时任务的延迟甚至异常。公司内部NameNode采用"ParNew+CMS"组合垃圾回收器。

案例一 NameNode升级之后RPC大毛刺问题探究

问题背景

随着HDFS集群规模的增大,NameNode性能压力越来越大,因此我们结合社区新版本的优化进行了内部分支的优化并发布上线。上线之后观察了一周,发现上线后RPC排队毛刺明显变大变多。如下图所示

问题分析

为什么RPC排队毛刺会出现?

按照经验来看,NameNod...

继续阅读

【大内存服务GC实践】- “ParNew+CMS”实践案例 : HiveMetastore FullGC诊断优化

Metastore服务是Hive的核心组成部分,是整个hadoop大数据体系的元数据基石,所有数据表相关schema信息、partition信息、元数据统计信息等都存储在Metastore所依赖的MySQL中,通过Metastore服务执行各种元数据操作。Metastore服务一旦长时间异常,所有依赖服务(诸如HiveServer、Spark、Impala等)就都会出现功能或服务异常。
Metastore是一个相对成熟的服务,通常情况下不会发生特殊的异常。但和所有的数据库系统一样,一旦上层业务使用姿势不对的话,是可能导致发生一些莫名其妙的系统异常。这篇文章重点介绍两起因为上层业务使用用法不恰当导致Metastore服务频繁FGC,底层MySQL负载飙升问题。

线上案例一

之前有段时间,Hive运维反馈三天两头Metastore服务会发生FGC,发生FGC之后只能通过重启来解决,好在重启对业务的影...

继续阅读

【大内存服务GC实践】- 一文看懂”ParNew+CMS”垃圾回收器

因为工作的需要,笔者前前后后分别接触了HBase RegionServer、HiveServer\Metastore以及HDFS NameNode这些大内存JVM服务。 在和这些JVM系统打交道的过程中,GC优化始终是一个绕不过去的话题,有的是因为GC导致NameNode RPC请求耗时增大,有的是因为GC导致RegionServer/HiveServer/Metastore经常宕机。在优化的过程中,笔者花时间系统地学习并梳理了CMS、G1GC以及ZGC这几款垃圾回收器的原理,并基于这些原理进行了多次线上GC问题的定位以及优化。这个系列的文章初步安排了多篇

  1. 【大内存服务GC实践】- 一文看懂"ParNew+CMS"组合垃圾回收器
  2. 【大内存服务GC实践】- "ParNew+CMS"组合垃圾回收器实践案例(一
  3. 【大内存服务GC实践】- "ParNew+CMS"组合垃圾回收器实践案例(二
  4. 【大内存服务GC实践】- 一文看懂G1垃圾回收器...

继续阅读

Hello World – 大数据实践之路

HBase博客停更了很长一段时间。因为工作原因这两年时间先是研究了一段时间Iceberg数据湖技术,后来因为团队的需要开始负责网易Hadoop\Hive等组件的开发运维工作。这两年,接触的技术栈丰富了许多,对大数据基础设施各种底层技术有了更加全面深入的理解。但让我觉得最有价值的还是这两年在线上运维过程中遇到并解决的各种各样问题,以及在分析排查这些问题过程中积累的一些排查问题的工具以及方法论。
笔者觉得这些生产线上的真实案例以及附带在这些案例后面的方法论作为宝贵的资源不应被私藏,应该拿出来与大家一起来分享交流,于是就有了重新续写博客的这份心思。也因为接下来的文章基本上都是生产线上的真实案例,所以笔者就将这些文章归入"大数据实践之路"专题。

对大数据生态现状的认识

随着近两年大数据技术的蓬勃发展,很多新的发展趋势、研究热点层出不穷。因为这个专题主要是基于Hadoop生态组件的生产线实践,所以谈几个关...

继续阅读

BigData-‘基于代价优化’究竟是怎么一回事?

还记得笔者在上篇文章无意中挖的一个坑么?如若不知,强烈建议看官先行阅读前面两文-SparkSQL – 有必要坐下来聊聊Joi》和BigData – Join中竟然也有谓词下推!》。第一篇文章主要分析了大数据领域Join的三种基础算法以及各自的适用场景,第二篇文章在第一篇的基础上进一步深入,讨论了Join基础算法的一种优化方案 - Runtime Filter,文章最后还引申地聊了聊谓词下推技术。同时,在第二篇文章开头,笔者引出了两个问题,SQL执行引擎如何知晓参与Join的两波数据集大小?衡量两波数据集大小的是物理大小还是纪录多少抑或两者都有?这关系到SQL解析器如何正确选择Join算法的问题。好了,这些就是这篇文章要为大家带来的议题-基于代价优化(Cost-Based Optimization,简称CBO)。

CBO基本原理

提到CBO,就不得不提起一位’老熟人’ - 基于规则优化(...

继续阅读

BigData – Join中竟然也有谓词下推!?

作者:何李夫、范欣欣

上文简要介绍了Join在大数据领域中的使用背景以及常用的几种算法-broadcast hash join 、shuffle hash join以及sort merge join等,对每一种算法的核心应用场景也做了相关介绍,这里再重点说明一番:大表与小表进行join会使用broadcast hash join,一旦小表稍微大点不再适合广播分发就会选择shuffle hash join,最后,两张大表的话无疑选择sort merge join。

好了,问题来了,说是这么一说,但到底选择哪种算法归根结底是SQL执行引擎干的事情,按照上文逻辑,SQL执行引擎肯定要知道参与Join的两表大小,才能选择最优的算法喽!那么斗胆问一句怎么知道两表大小?衡量两表大小的是物理大小还是纪录多少抑或两者都有?其实这是另一门学问-基于代价优化(Cost BaseOptimization,简称CB...

继续阅读