Chinaunix首页 | 论坛 | 博客
  • 博客访问: 41565
  • 博文数量: 16
  • 博客积分: 365
  • 博客等级: 一等列兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-08 13:58
文章分类
文章存档

2014年(1)

2013年(1)

2012年(14)

我的朋友

分类: NOSQL

2013-03-01 16:35:23

HbaseFull GC的避免

廉价商用服务器上的内存数量在过去的几年中不断的增长。当ApacheHBase项目于2007年开始时,运行Hadoop的典型配置有48GB内存。今天,大多数Hadoop客户以至少24G内存运行Hadoop,使用48G甚至72G内存的客户也变得越来越普遍,而内存使用成本则继续回落。表面上,这对像HBase数据库这样对延迟敏感的软件来说,这似乎是一个伟大的胜利,大量的内存可以容纳更多的数据缓存,在刷新到磁盘前作为写入缓存,避免昂贵的磁盘寻址和读。然而在实践中,HBase使用的内存不断增长,但JDK可用的垃圾收集算法仍然相同。这导致了HBase的许多用户的一个主要问题:随着Java使用堆大小继续增长,产生的内存碎片也会不断的增加,最终导致Full GC问题。

HBase中的内存碎片

Hbase的系统架构如图1,由图1可知HBase为了提高写入性能,为每个region添加了一个内存写缓存Memstore。当单个Memstore的大小达到memstore.sizeHeap内存达到hbase.regionserver.global.memstore.upperLimit/lowerLimit百分比限制时,就会触发整个regionflush,最终将所有数据写入HDFS并释放region下所有Memstores占用的内存(GC不一定及时)。而Region flush最终会导致大量的内存碎片(见图2),进而触发Full GC问题。

 

                                                                      图1 Hbase的系统架构


                                                                图2 Region flush导致内存碎片的示意图

图2中,左边五颜六色的是不同的region在内存中的位置,它是无序的,因为客户端的请求是无规律的。此时假设黄色的region触发了flush,那么右边将会出现与之对应的多个空洞,即内存碎片。这张图以region为粒度,仅仅是为了更直观地表示这种现象。真实场景中,这些空洞是更细粒度的Key/Value级对象,它能直接导致创建对象时触发Full GC

Arena Allocation

Arena Allocation是一种非传统的内存管理方法。它通过顺序化分配内存,内存数据分块等特性使内存碎片粗化,有效改善了内存碎片导致的Full GC问题。

它的原理有:

1)创建一个大小固定的bytes数组和一个偏移量,默认值为0

2)分配对象时,将新对象的data bytes复制到数组中,数组的起始位置是偏移量,复制完成后为偏移量自增data.length的长度,这样做是防止下次复制数据时不会覆盖掉老数据(append)。

3)当一个数组被充满时,创建一个新的数组。

4)清理时,只需要释放掉这些数组,即可得到固定的大块连续内存。

Arena Allocation方案中,数组的大小影响空间连续性,越大内存连续性越好,但内存平均利用率会降低。

HBase的解决方案-MSLAB

MSLAB,全称是 MemStore-Local Allocation Buffer,它基于Arena Allocation解决了HBaseRegion flush导致的内存碎片问题。

MSLAB的实现原理:

1MemstoreLABMemstore提供Allocator

2)创建一个2M(默认)的Chunk数组和一个chunk偏移量,默认值为0

Memstore有新的KeyValue被插入时,通过KeyValue.getBuffer()取得data bytes数组。将data复制到Chunk数组起始位置为chunk偏移量处,并增加偏移量=偏移量+data.length

3)当一个chunk满了以后,再创建一个chunk

4)所有操作的lock free,基于CMS原语。

MSLAB的优势在于:

1Key/Value格式的原始数据在minor gc时被销毁。

2)数据存放在2M大小的chunk中,chunk归属于memstore

3flush时,只需要释放多个2Mchunkschunk未满也强制释放,从而为Heap腾出了多个2M大小的内存区间,减少碎片的密集程度。由此避免由于大量内存碎片而导致的Full GC问题。

阅读(4059) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~