我们都知道 HBase 的基本结构由 rowkey,column, timestamp 组成。列存储数据不同于关系型数据库,MySQL 一旦建表,需要修改表结构时则需要执行对应的修改语句,而 HBase 在建完表之后,对于列的增加则不需要修改建表语句,但这并不意味着 HBase 的建表就可以随意建。

首先来看看 HBase 的结构

  • Table, 表,HBase 按照表来组织数据
  • Row, 行,Table 可以有多 Row,Table 按照 RowKey 进行索引
  • Column Family,列族,一行可以分为多个列族,列族需要在建表 Schema 中指定
  • Column Qualifier,和列族一起确定唯一列,一个列族可以有任意多个 Qualifier
  • TimeStamp,支持多版本,用时间戳来确定数据版本

通过以上 Row, Column Family, Column Qualifier, TimeStamp 可以唯一确定一个基本存储单元 Cell。

关系型 vs 列存储

并没有关系型数据库到列存储数据库一对一的设计迁移,在关系型数据库中,设计的重点是描述实体和其他实体之间的关系,查询和索引可以在之后设计。

而在 HBase 中,遵循着查询优先的设计模式,所有可能的查询都需要在设计中体现,因此 Schema 的设计方式也因此而来。考虑查询的方式,然后设计 Schema,这样可以使得数据能够快速被查询到。另外需要注意 HBase 被设计用来在大数据集群中使用,当预计数据量能够到达一个层级的时候再考虑使用。

rowkey 设计

rowkey 是 Table 的”主键”,设计时需要确保唯一性,数据按照 rowkey 大小顺序存储,rowkey 不是 schema 的一部分,但需要仔细设计:

  • 类型:rowkey 为 byte[],HBase 提供 String/int/short/long/float/double/boolean 向 byte[] 转化的函数。
  • 随机读:根据 rowkey 的随机读会有索引的支持,效率很高。
  • 顺序读:数据按 rowkey 大小顺序存储,按照 rowkey 范围 [startKey, endKey) 的顺序读,吞吐量很高。
  • RowKey 字段的设计需要参考最高频的查询场景

rowKey 设计热点问题,rowKey 要尽量随机,不要出现连续 rowKey。

列族设计

建议 HBase 设计为高表,不宜使用过多列族。

列和列族名字不宜太长,HBase 会在内存中对列和列族做索引和缓存。