【大内存服务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生态组件的生产线实践,所以谈几个关...

继续阅读

HBase 2.2.1随机读写性能测试

团队小伙伴前段时间对HBase 2.2.1的随机读写性能进行了初步的基准测试,这次测试主要目的是评估社区HBase 2.版本的整体性能,量化当前HBas的性能指标,对常见KV场景下HBas性能表现进行评估,为业务应用提供参考。

测试环境

测试环境包括测试过程中HBas集群的拓扑结构、以及需要用到的硬件和软件资源,硬件资源包括:测试机器配置、网络状态等等,软件资源包括操作系统HBas相关软件以及测试工具等。

集群拓扑结构

本次测试中,测试环境总共包含台物理机作为Hadoo数据存储,其中台物理机作为RegionServe部署宿主机,每个宿主机上起RegionServe节点,整个集群一共RegionServe节点。生成数据的YCS程序与数据库并不运行在相同的物理集群。

单台机器主机硬件配置

软件版本信息

测试工具

YCS全称Yahoo! Cloud Serving Benchmar...

继续阅读

HBase内存管理之MemStore进化论

Java工程中内存管理总是一个绕不过去的知识模块,无论HBase、Flink还是Spark等,如果使用的JVM堆比较大同时对读写延迟等性能有较高要求,一般都会选择自己管理内存,而且一般都会选择使用部分堆外内存。HBase系统中有两块大的内存管理模块,一块是MemStore ,一块是BlockCache,这两块内存的管理在HBase的版本迭代过程中不断进行过各种优化,接下来笔者结合自己的理解,将这两个模块的内存管理迭代过程通过几篇文章梳理一遍,相信很多优化方案在各个系统中都有,举一反三,个人觉得对内核开发有很大的学习意义。本篇文章重点集中介绍MemStore内存管理优化。

基于跳表实现的MemStore基础模型

实现MemStore模型的数据结构是SkipList(跳表),跳表可以实现高效的查询\插入\删除操作,这些操作的期望复杂度都是O(logN)。另外,因为跳表本质上是由链表构成,所以理解和...

继续阅读

学习HBase,你需要这样一本书

为什么要学习HBase?

整个互联网都建立在数据库的底座之上,数据库又林林总总分为很多种,但每个互联网业务发展到一定规模都不可缺少的数据库只有这么几种:以MySQL为代表的关系型数据库以及其分布式解决方案,以Redis为代表的缓存数据库,以ES为代表的检索数据库,再就是分布式持久化KV数据库。而在开源领域,尤其是国内,HBase几乎是分布式持久化KV数据库的首选方案。HBase应用的业务场景非常之多,比如用户画像、实时(离线)推荐、实时风控、社交Feed流、商品历史订单、社交聊天记录、监控系统以及用户行为日志等等。

为什么要写一本这样的书?

笔者在之前的几年时间里写了部分HBase相关的文章,虽然说每篇文章都自成体系,但从HBase系统的层面来看,这些博客之间又似乎缺乏联系。另外,博客中还是缺少很多关键的知识模块,比如HBase负载均衡机制、集群复制功能等。之外,很多读者反馈后期想要尝试生产线上...

继续阅读

时序数据库技术体系 – Druid 多维查询之Bitmap索引

时序数据库从抽象语义上来说总体可以概括为两个方面的基本需求,一个方面是存储层面的基本需求:包括LSM写入模型保证写入性能、数据分级存储(最近2小时的数据存储在内存中,最近一天的数据存储在SSD中,一天以后的数据存储在HDD中)保证查询性能以及存储成本、数据按时间分区保证时间线查询性能。另一方面是查询层面的基本需求:包括基本的按时间线进行多个维度的原始数据查询、按时间线在多个维度进行聚合后的数据统计查询需求以及TopN需求等。

可见,多维条件查询通常是时序数据库的一个硬需求,其性能好坏也是评价一个时序数据库是否优秀的一个重要指标。调研了市场上大多时序数据库(InfluxDB、Druid、OpenTSDB、HiTSDB等),基本上都支持多维查询,只有极个别的暂时支持的并不完美。通常来说,支持多维查询的手段无非两种:BitmapIndex以及InvertedIndex,也称为位图索引和倒排索引。
接...

继续阅读

时序数据库技术体系 – InfluxDB TSM存储引擎之数据读取

任何一个数据库系统内核关注的重点无非数据在内存中如何存储、在文件中如何存储、索引结构如何存储、数据写入流程以及数据读取流程。关于InfluxDB存储内核,笔者在之前的文章中已经比较全面的介绍了数据的文件存储格式、倒排索引存储实现以及数据写入流程,本篇文章重点介绍InfluxDB中时序数据的读取流程。
InfluxDB支持类SQL查询,称为InfluxQL。InfluxQL支持基本的DDL操作和DML操作语句,详见InfluxQL_Spe,比如Select语句

select_stmt = "SELECT" fields from_clause [ into_clause ] [ where_clause ][ group_by_clause ] [ order_by_clause ] [ limit_clause ][ offset_clause ] [ slimit_clause ] [ soffset_clause ] .

使用InfluxQL可以非常方便、人性化地对InfluxDB中的时序数据进行多维聚合分析。那InfluxDB内部是如何处理Query请求的呢?接下来笔者结合源码对InfluxDB的查询流程做一个剖析。另外,如果看官对源码这部分感兴趣,推荐先阅读官方文档对应部分https://docs.influxdata.com/influxdb...

继续阅读