`

在HBase中应用MemStore-Local Allocation Buffers解决Full GC问题:第二部分

阅读更多

 

maoyidao注:上个月写了一遍博文,介绍一种高效的Java缓存实现,http://maoyidao.iteye.com/admin/blogs/1559420。其本质是模仿Memcached的Slab,通过分配连续定长的byte[]减少大规模使用Java Heap作为缓存时不可避免的GC问题。虽然当时构思和实现这一思路时并没有参照其他开源产品,但这一思路在很多著名的开源产品上也有类似的实现。

 

随着内存使用成本越来越低,高并发海量数据应用开发者逐渐倾向于这样一种思路:“内存就是新的硬盘,硬盘就是新的磁带”。即通过尽量多的使用内存,和尽量多的顺序读写磁盘实现高吞吐。因此大规模使用内存引起的Java GC问题就成为了一个普遍问题。翻译这篇文章的初衷是:(1)该系列文章以Hadoop为例介绍了GC停顿带来的问题,比较生动。(2)比较详细的介绍了GC原理,特别是CMS错误产生的原因,并且有实验例子。(3)介绍了一系列GC参数及GC profile思路,比较有借鉴价值。(4)最终实现方式几乎和我自己的实现思路一致,可以作为对照。

 

http://www.cloudera.com/blog/2011/02/avoiding-full-gcs-in-hbase-with-memstore-local-allocation-buffers-part-2/

 

作者:Todd Lipcon, software engineer for Cloudera. Todd在2012年Hadoop峰会上介绍了:Optimizing MapReduce Job Performance,对性能调优有丰富经验。

 

在HBase中应用MemStore-Local Allocation Buffers解决Full GC问题:第二部分

在上周的文章中,我们注意到HBase有垃圾收集导致的长时间停顿问题,总结了Java 6 VM使用的不同垃圾收集算法。然后我们推测长时间的垃圾收集暂停是由内存碎片引起的,并设计了一个实验证实这一假说,并探讨哪种场景(workload)最最容易产生这种问题。

 

实验结果

概述

正如以前的描述,我在HBase服务器上跑了三个不同的场景,同时打开-XX:PrintFLSStatistics= 1收集详细GC日志。结果如下:



图的上半部分显示free_space,即堆的总自由空间。图底部显示max_chunk,即最大连续可用块空间的大小。X轴是时间(以秒为单位),Y轴是堆word大小,一个堆word是8个字节,因为我在运行64位JVM。

 

从图中很容易看出,这三个不同的场景有非常不同的内存使用特性。我们将仔细看看每个部分。

 

只写场景

我们可以看到两个有趣的情况:free_space在2.8GB和3.8GB之间波动。每次free_space到2.8G时,就开始执行CMS

并释放了1GB左右的空间。这表明,CMS开始收集的时间(maoyidao注:由-XX:CMSInitiatingOccupancyFraction = N参数指定)已调整到足够低 - 即CMS开始运行时堆中有足够的自由空间。我们也可以看到没有内存泄漏 - 堆使用状况相当一致,随着时间的推移,没有偏向任何方向的趋势。


然而CMS工作时,从图中看到最大连续可用块空间的大小(max_chunk)急剧下降近下降到0。每次达到0(如在时间102800秒),我们看到max_trunk陡然回升到了最大值。同时考虑GC日志,长时间的GC停顿正好和max_chunk陡然回升的时间吻合 - 即每次FGC后整个堆碎片被整理,使所有的自由空间成为一个完整的大型块。

 

因此我们认识到当堆中没有大的连续空闲块时,确实造成堆碎片并导致写场景中的GC长暂停。

 

有缓存逐出情况的只读场景

(maoyidao注:有缓存逐出的意思是缓存大小不足以缓存所有数据,因此有缓存更替的情况)

在第二个场景中,客户端仅执行读取,要读取的记录集是远远大于LRU缓存的大小。所以,我们看到大量的对象从缓存中被驱逐。


只读场景的free_space图反映了这一点 - 它显示了比只写场景更加频繁的GC。然而,我们注意到max_chunk图

显示max_chunk值几乎保持常数。这表明只读的工作量不造成堆碎片,即使缓存交互比只写要高得多。

 

没有缓存逐出情况的只读场景

第三种场景(overview图中的绿色部分),因为有没有缓存逐出的情况,内存中分配是为每个RPC请求提供服务的短生命周期对象。因此,他们从未被晋升为老年代,free_space和max_chunk时间序列保持完全不变。

 

试验总结

总结这个实验的结果:

我们想消除的FGC是由于碎片,而不是并发模式失败。

只写的场景导致比只读多很多的碎片。

 

HBase的写路径

为了在分布式集群存储一个非常大的数据集,Apache HBase把每个表分割成段,叫做Region(区)。每个Region都有一个指定的“开始键”和“停止键”,包含每个落在两者之间的行key。这个方案可以和基于RDBMS中的主键分区相比较(尽管HBase透明的管理分区)。每个Region通常是小于1GB,所以每一个HBase的集群中的服务器负责几百个Region,因此有大量读取和写入请求被发送到服务器。

 

一旦一个写请求已经达到了正确的服务器,新的数据首先被添加到一个内存中的结构称为:MemStore。这本质上是一个包含所有最近写入的数据的有序映Map。当然,内存是一种有限的资源,因此该地区的服务器仔细估算内存的使用情况,并在内存使用达到阈值时触发刷新,把数据写入到磁盘并释放内存。

 

MemStore碎片

让我们想象一下,一个Region服务器托管5个Region - 粉色,蓝色,绿色,红色和黄色。


随机写入均匀地分散在整个地区,并没有特定的顺序到达。新写入到达时,为每一行数据分配新的缓冲区,然后这些缓冲数据被提升到老年代,并在MemStore中等待几分钟,然后被刷新到硬盘。由于没有特定的顺序写入到达,来自不同地区的数据混杂在老一代。当其中一个region被刷新时,意味着我们不能释放任何大的连续块,因此一定会得到碎片:

 

 

这种行为的结果,正是我们的实验结果表明:随着时间的推移,导致一个FGC。

未完继续...

 

在这篇文章中,我们回顾我们的实验结果,明白了为什么在HBase内存碎片的原因。在本系列的下一个,即最后一篇文章中,我们将看看MemStore避免碎片的缓冲区设计。

 
  • 大小: 63.9 KB
  • 大小: 47.5 KB
  • 大小: 86.5 KB
  • 大小: 15.1 KB
0
0
分享到:
评论
1 楼 langyu 2012-07-25  
翻译的不错,第三部分正是关键。楼主辛苦下!

相关推荐

    hbase-hadoop2-compat-1.2.12-API文档-中文版.zip

    赠送jar包:hbase-hadoop2-compat-1.2.12.jar; 赠送原API文档:hbase-hadoop2-compat-1.2.12-javadoc.jar; 赠送源代码:hbase-hadoop2-compat-1.2.12-sources.jar; 赠送Maven依赖信息文件:hbase-hadoop2-compat-...

    hbase-hadoop2-compat-1.1.3-API文档-中文版.zip

    赠送jar包:hbase-hadoop2-compat-1.1.3.jar; 赠送原API文档:hbase-hadoop2-compat-1.1.3-javadoc.jar; 赠送源代码:hbase-hadoop2-compat-1.1.3-sources.jar; 赠送Maven依赖信息文件:hbase-hadoop2-compat-...

    hbase-hadoop2-compat-1.1.3-API文档-中英对照版.zip

    赠送jar包:hbase-hadoop2-compat-1.1.3.jar; 赠送原API文档:hbase-hadoop2-compat-1.1.3-javadoc.jar; 赠送源代码:hbase-hadoop2-compat-1.1.3-sources.jar; 赠送Maven依赖信息文件:hbase-hadoop2-compat-...

    hbase-prefix-tree-1.1.3-API文档-中文版.zip

    赠送jar包:hbase-prefix-tree-1.1.3.jar; 赠送原API文档:hbase-prefix-tree-1.1.3-javadoc.jar; 赠送源代码:hbase-prefix-tree-1.1.3-sources.jar; 赠送Maven依赖信息文件:hbase-prefix-tree-1.1.3.pom; ...

    hbase-hadoop-compat-1.1.3-API文档-中英对照版.zip

    赠送jar包:hbase-hadoop-compat-1.1.3.jar; 赠送原API文档:hbase-hadoop-compat-1.1.3-javadoc.jar; 赠送源代码:hbase-hadoop-compat-1.1.3-sources.jar; 赠送Maven依赖信息文件:hbase-hadoop-compat-1.1.3....

    HBase(hbase-2.4.9-bin.tar.gz)

    就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非...

    hbase-hadoop-compat-1.1.3-API文档-中文版.zip

    赠送jar包:hbase-hadoop-compat-1.1.3.jar; 赠送原API文档:hbase-hadoop-compat-1.1.3-javadoc.jar; 赠送源代码:hbase-hadoop-compat-1.1.3-sources.jar; 赠送Maven依赖信息文件:hbase-hadoop-compat-1.1.3....

    hbase-metrics-api-1.4.3-API文档-中文版.zip

    赠送jar包:hbase-metrics-api-1.4.3.jar; 赠送原API文档:hbase-metrics-api-1.4.3-javadoc.jar; 赠送源代码:hbase-metrics-api-1.4.3-sources.jar; 赠送Maven依赖信息文件:hbase-metrics-api-1.4.3.pom; ...

    hbase-hadoop2-compat-1.2.12-API文档-中英对照版.zip

    赠送jar包:hbase-hadoop2-compat-1.2.12.jar; 赠送原API文档:hbase-hadoop2-compat-1.2.12-javadoc.jar; 赠送源代码:hbase-hadoop2-compat-1.2.12-sources.jar; 赠送Maven依赖信息文件:hbase-hadoop2-compat-...

    hbase-annotations-1.1.2-API文档-中英对照版.zip

    赠送jar包:hbase-annotations-1.1.2.jar; 赠送原API文档:hbase-annotations-1.1.2-javadoc.jar; 赠送源代码:hbase-annotations-1.1.2-sources.jar; 包含翻译后的API文档:hbase-annotations-1.1.2-javadoc-...

    hbase-prefix-tree-1.4.3-API文档-中文版.zip

    赠送jar包:hbase-prefix-tree-1.4.3.jar; 赠送原API文档:hbase-prefix-tree-1.4.3-javadoc.jar; 赠送源代码:hbase-prefix-tree-1.4.3-sources.jar; 赠送Maven依赖信息文件:hbase-prefix-tree-1.4.3.pom; ...

    hbase-client-1.1.2-API文档-中英对照版.zip

    赠送jar包:hbase-client-1.1.2.jar; 赠送原API文档:hbase-client-1.1.2-javadoc.jar; 赠送源代码:hbase-client-1.1.2-sources.jar; 包含翻译后的API文档:hbase-client-1.1.2-javadoc-API文档-中文(简体)-...

    hbase-hbck2-1.1.0-SNAPSHOT.jar

    hbase-hbck2-1.1.0-SNAPSHOT.jar

    ycsb-hbase14-binding-0.17.0

    ycsb-hbase14-binding-0.17.0

    hbase-common-1.1.2-API文档-中英对照版.zip

    赠送jar包:hbase-common-1.1.2.jar; 赠送原API文档:hbase-common-1.1.2-javadoc.jar; 包含翻译后的API文档:hbase-common-1.1.2-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven信息:groupId:org....

    hbase-hadoop2-compat-1.4.3-API文档-中文版.zip

    赠送jar包:hbase-hadoop2-compat-1.4.3.jar; 赠送原API文档:hbase-hadoop2-compat-1.4.3-javadoc.jar; 赠送源代码:hbase-hadoop2-compat-1.4.3-sources.jar; 赠送Maven依赖信息文件:hbase-hadoop2-compat-...

    hbase-hbck2-1.0.0.jar

    Q:如果一个region即不在META表中,又不在hdfs上面,但是在regionserver的online region集合中 A:加上选项 -fixAssignments 解决 Q:如果一个region在META表中,并且在regionserver的online region集合中,但是...

    hbase-common-1.4.3-API文档-中文版.zip

    赠送jar包:hbase-common-1.4.3.jar; 赠送原API文档:hbase-common-1.4.3-javadoc.jar; 赠送源代码:hbase-common-1.4.3-sources.jar; 赠送Maven依赖信息文件:hbase-common-1.4.3.pom; 包含翻译后的API文档:...

    hbase-common-1.2.12-API文档-中英对照版.zip

    赠送jar包:hbase-common-1.2.12.jar; 赠送原API文档:hbase-common-1.2.12-javadoc.jar; 赠送源代码:hbase-common-1.2.12-sources.jar; 赠送Maven依赖信息文件:hbase-common-1.2.12.pom; 包含翻译后的API文档...

    hbase-prefix-tree-1.2.12-API文档-中英对照版.zip

    赠送jar包:hbase-prefix-tree-1.2.12.jar; 赠送原API文档:hbase-prefix-tree-1.2.12-javadoc.jar; 赠送源代码:hbase-prefix-tree-1.2.12-sources.jar; 赠送Maven依赖信息文件:hbase-prefix-tree-1.2.12.pom;...

Global site tag (gtag.js) - Google Analytics