hbase表结构模型

时间:2022-03-11 08:25:44

1.hbase 基本概念

1.1 namespace

namespace命名空间指对一组表的逻辑分组,类似RDBMS中的database,方便对表在业务上划分。namespace可以更方便对表进行管理、授权操作。
hbase内部有两个缺省的namespace。hbase:系统命名空间,主要存放hbase内部表,如meta元数据表;default:默认namespace,用户建表时无指定namespace都在这个下面。
可以通过grant、revoke对用户授权namespace的使用权限。具体操作可参考这个链接(http://blog.csdn.net/opensure/article/details/46470969)。

1.2 table

table就是hbase中表,类似RDBMS中的表。

1.3 列族

一个hbase中包含一个或多个列族。列族需要预先定义,所有的列归属于某个列族。

1.4 列

属于某一个columnfamily,familyName:columnName,每条记录可动态添加

1.5 version

每个列的值可以有多个版本,通过版本的不同时间戳来标识。version对应每次操作对应的时间戳,支持用户自定义,默认为当前时间的毫秒值。

2. schema表结构设计

2.1 表属性设置

  • 最大版本数:通常是3,如果对于更新比较频繁的应用完全可以设置为1,能够快速的淘汰无用数据,可以节约存储空间和查询速度。
  • 压缩算法:对于对查询速度要求比较高的,可使用snappy。对应离线数据,追求高压缩率的可使用lzo。
  • bloomfilter:可以用于提高随机读(Get)的性能,对于顺序读(Scan)而言,bloomfilter没有什么作用.bloomfilter主要用于过滤要查询storefile文件。即如果一个region下的hfile数量很多,bloomfilter的作用越明显。适合那种compaction赶不上flush速度的应用。更多关于bloomfilter的介绍可参考(http://zjushch.iteye.com/blog/1530143
  • blocksize:如果业务请求以Get请求为主,可以考虑将块大小设置较小;如果以Scan请求为主,可以将块大小调大;

2.2 预设分区设置

  • 在创建hbase表时,可以预设分区,一般预设每个regionserver上5-10个region.预设分区之后,可以根据分区文件的增长速度来确定是否需要进行split,增加新的分区。
  • 在确定预分区时候,需要指定每个分区region的startKey、endKey。由于hbase确定数据的分区是根据rowkey的ascii码,所以设定startKey、endKey的时候要根据hbase里面的数据rowkey的分布情况,保证每个数据分布均匀。比如数据的rowkey基本为md5加密小写的字符串,可以HexString作为分隔字符。

2.3 rowkey设置

  • 在设置rowkey时,要防止数据热点,要保证rowkey分散的比较均匀。比较常用的是对rowkey进行hash散列、加盐前缀。
  • 对于需要将rowkey的从大到小排序:由于原生hbase只支持从小到大的排序,这样就对于排行榜一类的查询需求很尴尬。那么采用rowkey+(Long.MAX_VALUE - timestamp)的方式将rowkey带上时间戳,最大的变最小,最小的变最大。每次scan就能取出最新数据。
  • 保证rowkey、列族的长度尽量短。Hbase中一条记录是由存储该值的行键,对应的列以及该值的时间戳决定。HBase 中索引是为了加速随机访问的速度。该索引的创建是基于“行键+列族:列+时间戳+值”的,如果行键和 列族的大小过大,将会增加索引的大小,加重系统的存储负担。

2.4 列族设置

  • 尽量保证HBASE列族的数量设置的越少越好。由于HBASE的FLUSHING和压缩是基于REGION的当一个列族所存储的数据达到FLUSHING阀值时,该表的所有列族将同时进行FLASHING操作,这将带来不必要的I/O开销。
  • 尽量保证列族的字符长度尽量短。

2.5 高表模式

  • HBase里有高表和宽表两种设计模式,前者行多列少,整个表结构高且窄;后者行少列多,表结构平且宽;但是由于HBase只能在行的边界做split,因此如果选择宽表的结构,那么在特殊行变的超级大(超过file或region的上限)时,那么这种行为会导致compaction,而这样做是要把row读内存的~~因此,强烈推荐使用高表模式设计表结构,这样结构更趋近于key value,性能更好。
  • 高表模式不能保证写入数据的原子性。而宽表能够保证写入单个key多列数据的原子性。

3.示例

shell建表示例
create ‘test’, { NAME => ‘info’, COMPRESSION => ‘snappy’ }, {NUMREGIONS => 9, SPLITALGO => ‘HexStringSplit’}