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

HBase-0.96中新BlockEncoding算法-PREFIX_TREE压缩的初步探究及测试


PREFIX_TREE(HBASE-4676)是HBase 0.96版本中新增加的一种DataBlock Encode算法。

?

1.什么是PREFIX_TREE

关于前缀树的介绍可以参考维基百科http://zh.wikipedia.org/wiki/Trie?

当然其的实现会有差别

?

2.HBase中的DataBlock

DataBlock是KeyValue的集合,是Hfile中存储数据的结构体,可以搜索Hfile了解之

?

3.什么是DataBlock Encode

DataBlock Encode是HBase 0.94版本引入的特性,可以将重复的row/family/qualifier/进行压缩,减少block的空间占用,提高内存使用率,可以通过http://zjushch.iteye.com/blog/1585066了解更多

?

4.PREFIX_TREE提升从DataBlock中查找数据的效率

在没有PREFIX_TREE之前,无论是否开启DataBlock Encode,都是按照KeyValue的排序,将其一条条顺序地写入到Block中,所以从block中查找数据,只能采用遍历的方式。而开启了PREFIX_TREE后,DataBlock中的数据存储不再是简单的将KeyValue按照顺序进行堆压,而是按照特有的方式进行组织,可以在解析时生成前缀树,并且树节点的儿子是排序的,所以从block中查找数据,其效率至少在二分查找以上。

?

5.作者提供的DataBlock查找性能对比

?

说明:

1.作者没有指出单条KV的平均大小

2.NONE 指的是不启用DataBlock Encode;PREFIX指的是PREFIX Encode算法;TRIE才是前缀树block压缩算法。

3. 前缀树压缩算法在不同的block size下查找性能都很稳定,而NONE和PREFIX由于是用遍历的方式查找数据,所以查找性能随着blocksize直线下降。对于我们默认的64K的block大小,性能相差40+倍

4.NONE比PREFIX算法性能好,是由于PREFIX算法需要解压

?

6.HBase中的PREFIX_TREE结构

PREFIX_TREE会分别对KeyValue中的row family qualifier形成三颗树,以Row为例,插入aa、aac、bb、bc、bc的过程如图




?
?

?

树上的节点分为3类:

branch(黄色): 内部节点,不代表实际数据,必定含有子节点

leaf(绿色):一个叶子节点,没有子节点,代表着实际数据

nub(紫色):branch与leaf的混合,既代表了实际数据,又含有子节点

节点中的数字代表该节点对应的实际数据的数目,如果一个row下有多条KeyValue,那么每条KeyValue对应的qualifier、family、timestamp等都会在encode时进行记录

?

7.Encode/Decode

PREFIX_TREE的encode算法,相对而言比较复杂,简单地说,它会按顺序向Block中写入ptBlockMeta、所有的row、所有的family、所有的qualifier、所有的timestamp、所有的value。可以看出,这与之前按照keyvalue顺序写入的block结构有很大的不同。 ptBlockMeta里面维护了decode时重建树结构所需要的元数据,以及一些为了压缩所需要的数据。整个encode/decode的过程还是直接看代码为好。

?

8.实际性能测试

?

测试环境:

16核CPU,HBase-0.94 version,单客户端200线程,单regionserver,BlockCache命中率100%

?



?

?

?说明:

1.在加大BlockSize后,开启PREFIX_TREE,QPS基本无变化,而对于NONE/DIFF而言,QPS影响很大

2.PREFIX_TREE的空间压缩效果接近于DIFF算法

3.DIFF/FAST_DIFF等block encoding算法是以CPU计算换取空间,在不计较空间的情形下,即命中率都为100%,那么开启DIFF/FAST_DIFF,相比于NONE,其性能是反而会下降的,从测试case看大概有5%~20%的下降

?

个人结论:

PREFIX_TREE在压缩空间的基础上又可以减少CPU,不仅可以取代其他block encoding算法了,像是PREFIX、DIFF、FAST_DIFF都可以退役了,足以成为标配

?

9.适用场景

a.随机读(Get)

b.一Row多qualifier

c.Key/Value 很小

d.除了scan场景有待测试外,其实对于所有的随机读场景,都可以开启,因为副作用小于正作用(DIFF/FAST_DIFF算法,对于数据无法压缩的场景,会加重CPU,带来副作用)

?

10.More

之前的顺序存储的Block结构下,逆序scan十分困难(只有后继,没有前继指针),而PREFIX_TREE则可以支持逆序scan,等0.96发布PREFIX_FREE普及后,相信逆序scan功能随之而来