Sumary:

  MemStore结构
  KeyValue构成细节
  HFile分析
  Maven

项目例子使用了Maven来管理Dependency,要运行例子,需要有maven环境,后面提到的HFile,StoreFile,HStoreFile指的是同一样东西,也就是HBase中Region每个CF对应的数据文件。
    HBase一直有一个问题,困扰着我一段时间了.时而思考一下,终不得解。
    问题发生于5月某天,在做大量Put测试去观察MemStore的flush, HStoreFile的Split和Compact操作时,奇怪的事情发生了,默认MemStore的size为128M,headSize达到128M,进行flush之后,MemStore恢复为0M,生成snapshot写hfile,最终生在hdfs的大小却是30M左右。
    百思不得奇怪,为什么会减少了这么多,压缩?NO!
    最近开始研究HFile的相关内容时,又想起了MemStore size和HFile size不一致问题,再次做试验。最终找到了答案.

场景设置:
  环境: 64位 CentOS VM 伪分布Hadoop ,standalone方式的HBase 连接本机hdfs. 4G内存 4核
  Hadoop 2.3 HBase 0.98.1-hadoop2 HFileReader(Writer) V2
  单个表,1个CF, 10W rows,即 70WKV,每个KV heapSize占100+byte左右,目测KV headSize会占有 70M

具体见测试代码。

1. 执行App.java 结束后,查看后台 master:60010 ,memStore的内存达到 112.9M

图1
2.通常,数据不会被flush至HFile中,重启HBase,强制flush memStore,再次查看后台web gui.
stop-hbase.sh
start-hbase.sh

图2
查看HFile只有26M。只有源数据的25%不到,很好,是我想要的结果。
也可以在stop后,直接使用hadoop 命令查看dfs中的文件大小 :hadoop fs -ls -R /hbase/data/default/t_sample/

图3
至此,第一个小实验做完了,结果很明显,MemStore 112.9M flush到StoreFile中只有26M,不到1/4的容量,why?

首先我们看一个KeyValue的构成

图4
从图中可以得知KeyValue的细节,我们继续一些有趣的小实验。
1.构建一个KeyValue

 public static void main(String[] args) throws Exception {
final byte[] row = Bytes.toBytes("u1");
final byte[] family = Bytes.toBytes("info");
final byte[] qualifier = Bytes.toBytes("sex");
final byte[] value = Bytes.toBytes("M"); KeyValue kv = new KeyValue(row, family, qualifier, value);
kv.setMvccVersion(System.currentTimeMillis());
System.out.println(kv.heapSize());
}

输出: 96

顺手抓了一幅图如下:

图5
结合KeyValue结构图4及实际一个KeyValue的字节码图5我们分析一下:

第0-3个字节 为 int类型 Key的长度,在这里是 21
第4-7个字节 为 int类型 Value的长度,在这里只有1
第8-28个字节为Key的内容
8-9 short类型,指定了 rowKey的长度 值为 2.
10-11 对应的rowKey,转为原String为u1
12 byte型的ColumnFamility Length,值为4
13-16 对应CF值,转为原String为info
28为KeyType,由于我们创建KeyValue时没有显式指定,默认为Put(4)
20-27为8字节的Long型,对应timestamp.
所以剩下的为 17-19 三字节为Qualifier,转为原String为sex
第29,即最后一字节,是Value内容 : "M"

好,假设我们KeyValue的真实内容,就是这堆长度为30的字节码,我们简单算一下, 30 * 70 * 10000 / 1024 / 1024 = 20M,这个数值是不是和我们的HFile的大小有点接近呢?我们试想一下,文件中还有一些Index、MetaBlock、Meta、FileInfo等信息,七七八八加起来,再加上本身其它column的 value就不止1字节,所以已经非常接近我们这26M的目标大小了。
好的,我们假设这些字节码,就是直接存入到HFile中的,那么MemStore呢,存的又是哪样?我们再简单地算一下, 96 * 70*10000 / 1024 / 1024 = 64M,离 112.9M差了近一倍。

走另一条路,我们想另一个问题,再来看看,为什么KeyValue本身只有30byte,但是打印出来是在MemStore的heapSize是96?看看heapSize()方法。

public long heapSize() {
int sum = 0;
sum += ClassSize.OBJECT;// the KeyValue object itself 16字节
sum += ClassSize.REFERENCE;// pointer to "bytes" 8字节
sum += ClassSize.align(ClassSize.ARRAY);// "bytes" 24字节
sum += ClassSize.align(length);// number of bytes of data in the "bytes" array 以刚才的为例,30,会转化为32字节.
sum += 2 * Bytes.SIZEOF_INT;// offset, length 2字节
sum += Bytes.SIZEOF_LONG;// memstoreTS 8字节
return ClassSize.align(sum);
}

OK,由于在内存中的原因,一个KeyValue对象除了本身实际内容外,还有 64byte是对象的内部实例等占用了部分空间,从而会这么大。
    另外,我们查看MemStore的结构:

volatile KeyValueSkipListSet kvset;

KeyValue是放在SkipListSet中的,内部其实就是一个Map,那么我们每个KeyValue存在Map中其实是一个又一个是Entry.其中每一个Entry又占了64byte.所以,一个KeyValue占MemStore的空间大约是160bytes.
    我们取168个字节为一个KeyValue大概算一算 168 * 70 * 10000 / 1024 / 1024 = 112.1 ,之所以取168其实也就是一行中7个KeyValue肉眼大约算出来的平均值,112.1M已经非常接近112.9M了.
    假设我们用38* 70 * 10000 / 1024 / 1024来算,25.3M,更为精确点,所以结合二个size,我们假定,这就是它们的真实的内存大小和文件大小。

为了论证这一点,我们还是做一个实例。具体源码见附件中。


我们直接通过HFileReader去读取HDFS中的HFile,然后Scan里面所有的KeyValue进行统计。结果输出为:
MemStoreSize:118391920,HFileSize:27723608,KeyValue Count:700000 转化单位
MemStoreSize:112.9M,HFileSize:26.4M,KeyValue Count:700000

好了,真相大白,完全证明了上面的推断是正确的。

项目源码下载: http://files.cnblogs.com/bdifn/MemStore_HStore_sample.zip

HBase MemStore与HStoreFile 的大小分析的更多相关文章

  1. 深入理解HBase Memstore

    2013/08/09 转发自http://www.cnblogs.com/shitouer/archive/2013/02/05/configuring-hbase-memstore-what-you ...

  2. Xamarin生成的APK大小分析

    原文:Xamarin生成的APK大小分析 刚接触Xamarin都会被Xamarin的售价吓一跳,另外就是它生成的APK大小,官方也有相关的说明,这里加上自己的理解同意讲解下: 以下是针对Android ...

  3. Hbase WAL线程模型源码分析

    版权声明:本文由熊训德原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/257 来源:腾云阁 https://www.qclo ...

  4. HBase Thrift2 CPU过高问题分析

    目录 目录 1 1. 现象描述 1 2. 问题定位 2 3. 解决方案 5 4. 相关代码 5 1. 现象描述 外界连接9090端口均超时,但telnet端口总是成功.使用top命令观察,发现单个线程 ...

  5. C++基础之---union联合体大小分析

    #include <iostream> using namespace std; union un { int a[7]; double b; char c[10]; int d[3]; ...

  6. YUV和RGB格式单像素所占内存大小分析

    图片的大小定 义为:w * h,宽高分别为w和h 一.YUV格式 1.1.YUV420格式存储方式:先Y,后V,中间是U.其中的Y是w * h,U和V是w/2 * (h/2)举例:如果w = 4,h ...

  7. bzoj2906 颜色 分块+块大小分析

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2906 题解 如果可以离线的话,那么这个题目就是一个莫队的裸题. 看上去这个数据范围也还会一个根 ...

  8. C#数组大小分析(附测试过程中想起的debug和release区别)

    C#数组的理论最大长度到底是多少呢?曾经一度问过度娘,谷歌,貌似都没有得出一个比较准确的答案,无外乎是什么Int32的最大值啊什么的,今天终于决定写个软件来自己测试一下,在几台不同的电脑里面实际测试看 ...

  9. HBase与传统关系数据库的对比分析

随机推荐

  1. Android RxJava/RxAndroid结合Retrofit使用

    概述 RxJava是一个在 Java VM 上使用可观測的序列来组成异步的.基于事件的程序的库.更重要的是:使用RxJava在代码逻辑上会非常简洁明了,尤其是在复杂的逻辑上.告别迷之缩进. RxAnd ...

  2. Android fragment 切换载入数据卡顿问题

    接着上一篇项目的进度.上一篇讲了怎样利用fragment来实现下拉菜单.公用菜单,以实现切换主界面数据的功能,这时候遇到的问题是:使用了fragment的切换界面方法.但载入的数据太多.用户从一个界面 ...

  3. Navicat for SQL Server创建连接提示错误08001怎么办

    创建连接之后提示如下错误 打开SQL Server配置工具,把能打开的都打开(什么远程连接,什么SQL Server Browser之类的) 你再创建连接的时候就有不止一个连接了,连那些Named P ...

  4. [转]bing壁纸天天换 初识shell魅力

    原文链接:http://www.cnblogs.com/atskyline/p/3679522.html 原文的程序跑在window上,curl的使用不太一样,想要获取的图片也不太一样.修改后的代码如 ...

  5. 运用Unity实现依赖注入[有参构造注入]

    上一篇章讲到关于使用Unity实现依赖注入的简单功能,针对有博友提出关于有参构造注入的问题; 本文同样通过一个实例来讲解如何实现此功能,文中一些分层讲解可以看上一文章(运用Unity实现依赖注入[结合 ...

  6. Java之基础(1) - 编程中“为了性能”尽量要做到的一些地方

    最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...

  7. Loadrunner socket协议lrs_receive函数接收到返回数据包 仍然等待服务器返回--解决

    前段时间在使用loadrunner socket协议发送数据包到到服务器,使用lrs_receive接收服务器应答数据包,已经接收到数据包,但LR仍然在等待服务器端返回,而且日志打印显示每次接收返回都 ...

  8. Java构建工具_Ant详解

    1,什么是antant是构建工具2,什么是构建概念到处可查到,形象来说,你要把代码从某个地方拿来,编译,再拷贝到某个地方去等等操作,当然不仅与此,但是主要用来干这个3,ant的好处跨平台   --因为 ...

  9. 通过 thread dump 分析找到高CPU耗用与内存溢出的Java代码

    http://heylinux.com/archives/1085.html通过 thread dump 分析找到高CPU耗用与内存溢出的Java代码 首先,要感谢我的好朋友 钊花 的经验分享. 相信 ...

  10. 【转】OMCS网络语音视频聊天框架(跨平台)

    原文地址:http://www.cnblogs.com/zhuweisky/archive/2012/08/02/2617877.html OMCS网络语音视频框架是集成了语音通话.视频通话.远程桌面 ...