日期:2014-05-16  浏览次数:20463 次

HBase HFile与Prefix Compression内部实现全解--KeyValue格式

1. 引子

?

HFile (HBase File)是HBase使用的一种文件存储格式的抽象,

?

目前存在两种版本的HFile: HFile V1和HFile V2

?

HBase 0.92之前的版本仅支持HFile V1,

HBase 0.92/0.94同时支持HFile V1和HFile V2。

?

以下分别是HFile V1/V2的结构图:

?

HFile V1

HFile V2


(注: 这两个图片在hbase 0.94的svn目录: src\site\resources\images)

?

图中的数据块(Data block)正是实际存放应用数据的地方,

每个数据块又由一系列的KeyValue组成,并且这些KeyValue之间是按Key升序排列的,

本文将说明KeyValue到底是什么以及当KeyValue越来越多时出现大量类似的数据有哪些算法能减少重复?

?

首先来看一个例子:

假设需要将用户的基本信息以及正在参与的开源项目的有关信息存入HBase:

?

?

?

Java代码 复制代码?收藏代码
  1. ????用户基本信息???????????????????参与的开源项目 ??
  2. ---------------------???????---------------------------- ??
  3. 用户Id????职业???性别??????????tomcat???????????hbase??????????? ??
  4. ---------------------???????---------------------------- ??
  5. zhh2009???码农???男????????????提patch打酱油????提patch打酱油 ??
  6. ??
  7. 用户Id????职业???性别??????????tomcat???????????ant ??
  8. ---------------------???????---------------------------- ??
  9. jdd1999???码神???男????????????创始人???????????创始人 ??
  10. --------------------- ??
  11. ??????????????????????表1.1??
	用户基本信息                   参与的开源项目
---------------------       ----------------------------
用户Id    职业   性别          tomcat           hbase           
---------------------       ----------------------------
zhh2009   码农   男            提patch打酱油    提patch打酱油

用户Id    职业   性别          tomcat           ant
---------------------       ----------------------------
jdd1999   码神   男            创始人           创始人
---------------------
                      表1.1

?

?

?

从这个例子来看,用户的基本信息比较好确定,但是参与的开源项目不确定且在开源项目中扮演的角色也不确定,

所以用关系数据库不太好建表,因为不知道具体有多少列,也无法把相关的列归成一个组。

?

1.1 列族

?

HBase是一种基于列的数据库,相关的列可以归到一个列族(Column Family),

每个列族中具体有哪些列不必事先知道,可以在需要的时候添加,比如在用户基本信息中为zhh2009加入email这样的列,

上例中"用户基本信息"和"参与的开源项目"可以作为两个列族,

不同的列族在HBase内部通常对应一个目录,这样不同的列值只会放到它所属的列族目录下。

?

1.2 rowKey

?

我们希望通过查询某个列就能把同一个列族或多个列族中的信息取出来,用户Id就是这样的列,

比如当我们要查询zhh2009的邮箱和参与的开源项目时,根据用户Id来查就不会查到jdd1999的信息,

在HBase中称这样的列为rowKey。

?

?

HBase是如何存放上例中的信息呢?

?

将用户Id这一列抽出来作为rowKey, 把上面的信息按如下格式扁平化:

?

?

Java代码 复制代码?收藏代码
  1. <rowKey,??列族名称,???????列名???=>?列值> ??
  2. ----------------------------------------------------- ??
  3. <zhh2009,?用户基本信息,???职业???=>?码农> ??
  4. <zhh2009,?用户基本信息,???性别???=>?男> ??
  5. <zhh20