HBase数据压缩 Column family Compress & Data Block Encoding

    说到HBase数据压缩,在HBase中有两种方式可以达到该目的,一个就是column family的compress,HBase支持none/snappy/lzo/lz4/gz等几种压缩方式来压缩数据,最后降低数据总量的大小;另一个是data block 的encoding,通过对data block中的KeyValue中key的相同部分进行处理来减少存储的占用,目前支持prefix/diff/fast diff/prefix tree等几种方式来实现data block 的encoding,另外,两者是可以叠加使用的,但是必须要根据详细的数据情况进行测试方可以使用。下面说分别说一下两者的内容:

Compress/DeCompress

数据压缩是HBase提供的另一个特性,HBase在写入数据块到HDFS之前会首先对数据块进行压缩,再落盘,从而可以减少磁盘空间使用量。而在读数据的时候首先从HDFS中加载出block块之后进行解压缩,然后再缓存到BlockCache,最后返回给用户。写路径和读路径分别如下:

写路径:

 

读路径:

 

结合上图,来看看数据压缩对资源使用情况以及读写性能的影响:



(1) 资源使用情况:压缩最直接、最重要的作用即是减少数据硬盘容量,理论上snappy压缩率可以达到5:1,但是根据测试数据不同,压缩率可能并没有理论上理想;压缩/解压缩无疑需要大量计算,需要大量CPU资源;根据读路径来看,数据读取到缓存之前block块会先被解压,缓存到内存中的block是解压后的,因此和不压缩情况相比,内存前后基本没有任何影响。

(2) 读写性能:因为数据写入是先将kv数据值写到缓存,最后再统一flush的硬盘,而压缩是在flush这个阶段执行的,因此会影响flush的操作,对写性能本身并不会有太大影响;而数据读取如果是从HDFS中读取的话,首先需要解压缩,因此理论上读性能会有所下降;如果数据是从缓存中读取,因为缓存中的block块已经是解压后的,因此性能不会有任何影响;一般情况下大多数读都是热点读,缓存读占大部分比例,压缩并不会对读有太大影响。

可见,压缩特性就是使用CPU资源换取磁盘空间资源,对读写性能并不会有太大影响。HBase目前提供了三种常用的压缩方式:GZip | LZO | Snappy,下面表格是官方分别从压缩率,编解码速率三个方面对其进行对比:

HBase数据压缩 Column family Compress & Data Block Encoding_第1张图片

 

综合来看:

1、Gzip压缩比最高,但是压缩和解压缩的速度比较慢,适合存储冷数据,节省硬盘空间

2、大部分场景下,开启 Snappy 或者 LZO 压缩会是比较好的选择,其中 Snappy 整体性能优于 LZO,主要表现在解压/压缩速度更快,适合存储热数据和温数据,目前一般建议使用Snappy。

3、LZ4是一种追求极致解压/压缩速度的压缩方式,HBase 官网上介绍不多。根据 HBase 社区的测试结果来看,在不同业务类型数据下,LZ4 的压缩率与 LZO 相当或者略小于 LZO,但是解压速度却明显高于 LZO,部分场景下可以达到 LZO 的两倍以上。由于该类型的压缩笔者使用经验不多,所以建议在使用时针对数据进行相关的测试来进行验证和比较。

Encode/Decode

除了数据压缩之外,HBase还提供了数据编码功能。和压缩一样,数据在落盘之前首先会对KV数据进行编码;但又和压缩不同,数据块在缓存前并没有执行解码,因此即使后续命中缓存的查询也是编码的数据块,需要解码后才能获取到具体的KV数据。写路径和读路径分别如下:

写路径:

 

读路径:

 

同样,来看看数据压缩对资源使用情况以及读写性能的影响:



(1) 资源使用情况:和压缩一样,编码最直接、最重要的作用也是减少数据硬盘容量,但是数据压缩率一般没有数据压缩的压缩率高,理论上只有5:2;编码/解码一般也需要大量计算,需要大量CPU资源;根据读路径来看,数据读取到缓存之前block块并没有被解码,缓存到内存中的block是编码后的,因此和不编码情况相比,相同数据block快占用内存更少,即内存利用率更高。

(2) 读写性能:和数据压缩相同,数据编码也是在数据flush到hdfs阶段执行的,因此并不会直接影响写入过程;前面讲到,数据块是以编码形式缓存到blockcache中的,因此同样大小的blockcache可以缓存更多的数据块,这有利于读性能。另一方面,用户从缓存中加载出来数据块之后并不能直接获取KV,而需要先解码,这却不利于读性能。可见,数据编码在内存充足的情况下会降低读性能,而在内存不足的情况下需要经过测试才能得出具体结论。

总结:

  1. 如果Table的rowkey比较长,且column比较多,则建议使用一个prefix encoder,建议使用fast_diff,prefix_tree需要进行足够的测试来确认是否能达到一个很好的效果
  2. 如果Table的value很大(value未被压缩),则建议使用压缩来节省硬盘使用
  3. Gzip压缩比最高,但是压缩和解压缩的速度比较慢,适合存储冷数据,节省硬盘空间
  4. 大部分场景下,开启 Snappy 或者 LZO 压缩会是比较好的选择,其中 Snappy 整体性能优于 LZO,主要表现在解压/压缩速度更快,占用的资源也更少,但是压缩比没有Gzip高,适合存储热数据和温数据,目前一般建议使用Snappy。

你可能感兴趣的:(HBase)