HBase列族设计

在创建HBase表时,一个好的列族设计,能够达到事半功倍的效果

列族设计中,对于一些属性参数的设置,会影响该表的读写性能,有些参数设置很简单,有些参数设置起来需要根据业务场景进行选择

今天我们来搞一搞HBase的列族设计,围绕以下几个方面:

1.BlockSize 数据块大小

2.BlockCache 数据块缓存

3.BloomFilter 布隆过滤器

4.Compression 压缩

5.Data Block Encoding 数据块编码

6.Version 版本

7.生存时间 TTL


1.BlockSize 数据块大小

BlockSize默认值 64K65536字节

数据块大小,即每次读请求读取的最小数据大小

将数据块调大可以提高扫描的性能,将数据块调小可以增加随机读的速度

如果业务请求以Get请求为主,可以考虑将块大小设置较小;如果以Scan请求为主,可以将块大小调大;

命令如下:

create 'test',{name => 'column1', BLOCKSIZE=> '65536'}

2.BlockCache 数据块缓存

LRUBlockCache是HBase目前默认的BlockCache机制

HBase在此基础上采用了分层设计,将整个BlockCache分成了三个部分,BlockCache包含三个级别的优先级队列:

Single: 如果一个Block被第一次访问,则放在这一级的队列中

Multi:  如果一个Block被多次访问,则从Single队列移动Multi队列

In Memory: 优先级最高,常驻cache,在创建列族时定义,不会像其他两种cache会因访问频率而发生改变,这就决定了它的独立性,另外两种block访问次数再多也不会被放到in-memory的区段里去,in-memory的block不管是第几次访问,总是被放置到in-memory的区段中,但是In Memory除了保证优先级外,不会提供其他的保证


BlockCache数据块缓存默认是true

但值得注意的是:把数据放进缓存,不一定能够提升性能

如果在实际情况中,某些表或表中的列族不经常访问,或者只是进行有序扫表的话,数据块缓存可以关闭

命令如下:

create 'test',{name => 'column1', BLOCKCACHE => 'false'}

关于IN_MEMORY的作用,上面已经说了,默认值是false,在实际应用中可以将其设置为true

create 'test',{name => 'column1', IN_MEMORY=> 'true'}

3.BloomFilter 布隆过滤器

BloomFilter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法,通常应用在一些需要快速判断某个元素是否属于该集合,但是并不严格要求100%正确的场合

BloomFilter的数据存在StoreFile的meta中,一旦写入无法更新,因为StoreFile是不可变的

BloomFilter是一个列族级别的配置属性,如果在表中设置了BloomFilter,那么HBase会在生成StoreFile时包含一份BloomFilter结构的数据,称其为MetaBlock;MetaBlock与DataBlock(真实的KeyValue数据)一起由LRU BlockCache维护

所以,开启BloomFilter会有一定的存储及内存cache开销

BloomFilter包含三种参数:NONE(默认)、ROW、ROWCOL

ROW:表示行级布隆过滤器,根据KeyValue中的来过滤StoreFile

ROWCOL:表示列级布隆过滤器,根据KeyValue中的行+列来过滤StoreFile

所以ROWCOL的空间开销,要高于ROW

region下的StoreFile数目越多,bloomfilter的效果越好

region下的StoreFile数目越少,HBase读性能越好

在HBase中设置列族开启BloomFilter命令如下:

create 'test',{name => 'column1', BLOOMFILTER => 'ROW 或 ROWCOL'}

对于已经存在的表,可以使用alter表的方式修改表结构,但这种修改对于之前的数据不会生效,只针对修改后插入的数据

4.Compression 压缩

Hfile可以被压缩并存放到HDFS上,这样有助于节省磁盘IO,但是读写数据时压缩和解压缩会提高CPU的利用率

压缩特性就是使用CPU资源换取磁盘空间资源,对读写性能并不会有太大影响

默认值是NONE,即不开启压缩

推荐打开表的压缩,除非压缩不适合业务场景,例如对图片,音频,视频进行压缩

HBase目前提供了三种常用的压缩方式:GZip、LZO、Snappy

在Snappy发布之前(Google 2011年对外发布Snappy),HBase采用的LZO算法,目标是达到尽可能快的压缩和解压速度,同时减少对CPU的消耗; 

在Snappy发布之后,建议采用Snappy算法,具体可以根据实际情况再做选择

下面表格是官方分别从压缩率,编解码速率三个方面对其进行对比:

综合来看,Snappy的压缩率最低,但是编解码速率最高,对CPU的消耗也最小,目前一般建议使用Snappy

命令如下:

create 'test',{name => 'column1', COMPRESSION=> 'SNAPPY'}

如果建表之初没有压缩,后来想要加入压缩算法,可以通过alter进行修改

注意:压缩只是在磁盘上进行,内容和网络传输中没有进行压缩

5.Data Block Encoding 数据块编码/解码

HBase提供了四种编码/解码类型:Prefix、Diff、Fast Diff、Prefix Tree

分别介绍一下

Prefix

适用于key有相同前缀,仅后几位有所不同

如果使用Prefix编码,会产生一个额外的列,用于存储当前key与前一个key之间的相同前缀的长度

举个例子:

下图是一个没有使用编码的列族,可以看到前三列数据只有最后一位不同


下图是使用Prefix编码的列族

第一个key与之前的key完全不同,它的前缀长度是0

第二个key的前缀长度是23,因为它们有相同的前23个字符,仅最后一位不同

第三个key的前缀长度也是23,同上


如果业务场景中,符合这样的需求,可以将编码格式设置为Prefix

Diff

这种格式编码扩展了Prefix编码,与按顺序将key看作一个整体的字节序列不同,它将每个key字段被分割,以便更有效地压缩key的每个部分

如果使用Diff编码,会产生两个额外的列timestamp和type,用于存储时间戳和类型

如果当前行的列族与前一行相同,则从当前行中省略它

如果key的长度、value的长度或类型与前一行相同,则省略该字段

此外,为了增加压缩,时间戳存储为与前一行时间戳的差异,而不是完全存储

Diff编码在默认情况下是禁用的,因为写入和扫描比较慢,但是缓存了更多的数据

示例:

下图与上面Prefix编码的列族进行对比

第一行数据正常进行记录

第二行的key长度和类型与前一行相同,则不需要存储,第二行的时间戳值为0,而不是完整的时间戳,即时间戳与第一行时间戳相同

第三行的数据key的长度和value的长度与前一行相同,则不需要记录,时间戳仅记录于前一行的差值即,并记录类型(类型列中的4和8应该是数字和字符的对应类型码,这仅为vv的猜测)


Fast Diff

Fast Diff的工作原理与Diff类似,但是使用了更快的实现

它还添加了另一个字段,该字段存储一个位来跟踪数据本身是否与前一行相同,如果是,则不再存储数据

Prefix Tree

前缀树编码是HBase 0.96中的一个实验特性

它提供了与前缀、Diff和快速Diff编码器类似的内存节省,提供了更快的随机访问,但代价是编码速度较慢

Prefix Treehbase-2.0.0中被删除

如果设计的表,rowkey很长,并且有很多推荐使用Fast Diff格式

使用命令如下:

create 'test',{name => 'column1', DATA_BLOCK_ENCODING => 'FAST_DIFF'}

注意:由于VV没有实际测试过不同编码在实际情况中的性能状况,所以,大家选择使用时,需要进行测试,选择适合自己业务场景的格式

6.Version 版本

用于设置列族所能记录的最多的版本数量,默认值是3,可以通过alter进行修改

对于更新频繁的应用,建议设置为1,可以快速淘汰无用的数据,节省存储空间同时还能提升查询效率

命令如下:

create 'test',{name => 'column1', VERSIONS=> 1}

除此之外,还可以设置最小版本数量

create 'test',{name => 'column1', VERSIONS => 5 , MIN_VERSIONS=> '1'}

7.生存时间 TTL

用于设置单元格的生存周期,如果单元格过期,则会将其删除

单位是秒,默认值:FOREVER (永不过期)

早于TTL值的数据会在下次大合并中删除

如果在同一单元格上有多个版本,早于TTL的值会被删除,值得注意的是,果最小版本MIN_VERSIONS设置为0时,TTL过期后,将全部彻底删除该family下所有的数据,如果MIN_VERSIONS 不等于0那将保留最新的MIN_VERSIONS个版本的数据,其它的全部删除

命令如下:

create 'test',{name => 'column1', TTL=> '18000'}

总结

以上就是今天带来的HBase列族设计

大家在实际场景应用的时候,多多进行调研和测试后再使用哦!


亲,看完了点个赞呀!!

赫墨拉

我是一个喜爱大数据的小菜鸡,这里是我分享我的成长和经历的博客

You may also like...

2 Responses

  1. 匿名说道:

    特地登陆点个攒

发表评论

邮箱地址不会被公开。