HBase压缩方式LZ4和SNAPPY对比

张开慧

1、背景

目前我公司的HBase服务都是没有经过压缩算法的,为了提高存储的利用率,决定对现有的和将来的hbase表进行压缩。正式执行之前,先对Hbase压缩算法来个小测试。

2、方案

基于snappy压缩算法在hive的良好表现,以及lz4在spark中的表现,我们决定从这两个主流的压缩算法中选其一作为hbase的压缩算法。
我们知道对hbase表的压缩其实是针对列簇的压缩。而我们使用的是phoenix+hbase的组合,phoenix建的表可以简单的看成是只建立了一个列簇的hbase表,所以我们可以在建表的时候指定压缩算法,看作是对这个列簇的压缩。当然也可以对已有的表进行修改。
有一个问题是先用lz4压缩,然后修改压缩方式为snappy,不知道会不会有两层压缩?所以我们新建两个表来测试压缩效果和对读写的影响。

3、过程

我们只研究lz4和snappy的相对表现,因此关于cpu、网络的信息就不列出来了。
3.1 安装lz4和snappy
3.2 新建两个phoenix表分别制定压缩方式为lz4和snappy

create_table_lz4 create_table_snappy 3.3 分别插入数据 upsert_select

3.4 查看压缩情况

du_h 3.5 查询速度对比 select * from USER.USER_TRADE_LOG_20161207_SNAPPY where USER_ID=13673; select_one select settle_tm-(settle_tm+28800)%86400 biz_date,coalesce(sum(case when amt>=0 then amt end),0.0) income,coalesce(sum(case when amt<0 then amt end)*(-1),0.0) outcome from ( select cast(TO_NUMBER(SETTLE_TIME)/1000.0 as bigint) settle_tm,amt from USER.USER_TRADE_LOG_20161207_SNAPPY where USER_ID=13673 and TRADESTATUS=1 ) GROUP BY settle_tm - (settle_tm+28800)%86400; select_group

4、结论

从压缩比来看,lz4达到了17.63%,snappy达到了17.48%,snappy压缩比略高一点。
从写速度来看,lz4用了21.23s,snappy用了37.11s,也就是说lz4压缩速度更快。
从读速度来看,三者相差不大。lz4>snappy>不压缩,按理说读取压缩之后的数据要经过解压缩的过程,应该比不压缩的时候慢。我们猜测是因为数据量太少(数据量多的情况下直接在phoenix-cli执行upsert into select 是不可取的,可以使用spark),数据保存在内存中。另一个可能的原因是不压缩时要去多个文件取,io消耗比cpu更高。
hbase是IO密集型的,CPU相对来说是很空闲,正好适合于相对来说CPU运算密集的解压缩。解压缩是HBase内部机制,不需要额外操作。

5、补充

5.1 修改已有的表的压缩方式
hbase shell命令下:
a) disable相关表:
    disable 'table1';
b) 修改表的压缩格式,phoenix默认列簇_0
    alter 'table1', NAME => '_0', COMPRESSION => 'snappy';
c) 重新enable表
    enable 'table1';
d) major_compact,enable之后并没有立即生效
    major_compact 'table1';

5.2 major_compact
    Compaction是buffer->flush->merge的关键操作,主要起合并文件,清除删除、过期、多余版本的数据等作用。又分为Minor Compaction和Major Compaction。
    Minor操作只用来做部分文件的合并操作以及包括minVersion=0并且设置ttl的过期版本清理,不做任何删除数据、多版本数据的清理工作。
    Major操作是对Region下的HStore下的所有StoreFile执行合并操作,最终的结果是整理合并出一个文件。
    Major Compaction触发的方式有三种,其一hbase配置的major compaction时间到了,其二HFile小文件过多时,其三手动执行。