生产中,磁盘空间不够存储未来几年的数据,怎么使用Hbase呢?

Hbase+ES的存储方案

    • 介绍
    • 启动数据块编码
      • 属性值介绍
        • PREFIX:前缀编码
        • DIFF:差异编码
        • FAST_DIFF:快速差异编码
        • PREFIX_TREE: 前缀树编码
          • 该算法的特点
    • 把Hive中一行数据在存储的时候生成json存储到一个列中
      • 磁盘占用情况
      • 查询数据耗时测试

介绍

​ 最近的一个项目中,需要使用Hbase+ES的存储方案,把Hive中的数据导入到Hbase和ES中,方便检索。但是在预估未来几年的数据量后, 发现当前的磁盘不够存储未来几年的数据,不过现有的数据存储是没有问题的。这个该怎么实施呢?

​ Hbase在存储数据的时候必须采用了压缩算法,这个当时比对了现有几种压缩算法的查询性能以及压缩比,最后选定了snappy压缩,在这里就不多说了.使用Hbase+ES主要是为了检索速度快,所以在这里主要关注的是数据写入后的查询性能。

​ 由于Hbase是一个列式数据库,一行中的不同列可以被存储在不同的地方,甚至不同的服务器中。为了实现这样的结构,势必要在每一个单元格上都存储进所有可以定位到这个单元格的维度信息,比如行键、列簇、列、时间截等信息。这样的存储结构非常浪费存储空间,因为真正存储值的部分可能只占到了5-10%,如果只存储一两个字符, 那么比例就下降的更厉害。在这里有两种方案。

启动数据块编码

​ 数据块编码是在列簇上的属性,属性名为: DATA_BLOCK_ENCODING, 属性值有PREFIX_TREE、DIFF、PREFIX、FAST_DIFF。

  • 如果在代码中创建表加上

    hcolumnDescriptor.setDataBlockEncoding (DataBlockEncoding.PREFIX_TREE);
    
  • 如果在命令行创建表则为

    create '命名空间:表名',{NAME=>'列簇',DATA_BLOCK_ENCODING=>'属性值'}
    

属性值介绍

PREFIX:前缀编码

​ 如果使用了前缀编码作为数据块编码方式,那么它只会存储第个key的完整字符串,后面的key只存储跟第一个key的差异字符。这样会把存储的key的占用空间极大的压缩,空间占用减少79%。

DIFF:差异编码

​ 这种数据块编码比前缀编码更能减少空间占用率,但是在查询的时候会比其他编码都要慢,算法复杂,只适合数据的存档。这里不做考虑。

FAST_DIFF:快速差异编码

​ 快速差异编码借鉴了差异编码的功能,进行了适量优化,比差异编码快,但是查询还是会消耗很多时间,这里不做考虑。

PREFIX_TREE: 前缀树编码

​ 从名字上看就能发现它是前缀编码的变体,这个算法设计的出发点是应该对前缀进行编码压缩。在数据块中应该支持随机查询,由于数据块中总是顺序查找key-value, 所以带来一个问题,那就是数据块越大查询越慢。

该算法的特点
  • 对rowkey进行字典树编码以消除重复的rowkey,并把相似的rowkey以字典树的形式来存储。
  • 每个数据块中只在开头的部分存储一次列族
  • 每个数据块的限定符以字典树的形式存储。
  • 每个数据块的头部存储有一个最小时间戳,其他时间戳用该最小时间戳换算得出
  • 提高了随机读写的能力,但是因为复杂的算法也相对降低了写入的速度,消耗了更多资源。数据块编码选择前缀树编码方式。

把Hive中一行数据在存储的时候生成json存储到一个列中

​ 把Hive中一行数据存储到Hbase一列中,这种方式极大的降低了存储的空间占用,并且也极大的增加了Hbase的bulkload的写入速度, 基本是指数级增加。但是缺点也明显,舍弃了hbase列式存储的特性,对于行数据上千列只需要指定几列的情况极大的增加了网络工I/0。降低了查询性能,在这里通过测试查看具体情况。

磁盘占用情况

数据量700万左右,测试情况下都开启了snappy压缩。

存储方式 占用空间
单列 2.3G
多列 4.7G
多列加数据块编码 2.6G

查询数据耗时测试

​ 当数据烈数不是很多时,查询耗时差别不大,如果列数有近干列建议使用数据块编码这种方式,当前的业务因为基本需要所有的列数据并且导入效率也有要求,所以选择了单列写入的方式。

你可能感兴趣的:(#,Hbase)