欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Hbase入门(四)——表结构设计-RowKey

程序员文章站 2022-08-08 16:10:16
Hbase的表结构设计与关系型数据库有很多不同,主要是Hbase有Rowkey和列族、timestamp这几个全新的概念,如何设计表结构就非常的重要。 创建 Hbase就是通过 表 Rowkey 列族 timestamp确定一行数据。 这与关系型数据库完全不同: | 属性 | HBase | RDB ......

Hbase入门(四)——表结构设计-RowKey

hbase的表结构设计与关系型数据库有很多不同,主要是hbase有rowkey和列族、timestamp这几个全新的概念,如何设计表结构就非常的重要。

Hbase入门(四)——表结构设计-RowKey

创建

hbase就是通过 表 rowkey 列族 timestamp确定一行数据。

这与关系型数据库完全不同:

属性 hbase rdbms
数据类型 只有字符串 丰富的数据类型
数据操作 简单的增删改查 不支持join 各种函数和表连接
存储模式 基于列式存储 基于表格结构和行式存储
数据保护 更新后仍然保留旧版本 替换
可伸缩性 轻易的增加节点,兼容性高 需要中间层,牺牲功能

所以hbase需要考虑的因素有:

1、这个表应该有多少列族

2、列族使用什么数据

3、每个列族有多少列

4、列名是什么

5、单元应该存放什么数据

6、每个单元存储多少时间版本

7、rowkey结构是什么,应该包含什么信息

需要注意的点:

1、join

hbase中没有join 所以需要大表结构 行记录加关键字 解决这个问题

2、rowkey

rowkey设计非常重要 由于hbase是有序的 需要考虑前缀后缀问题

可以通过hbase shell和 java api创建:

configuration config = hbaseconfiguration.create();
admin admin = new admin(conf);
tablename table = tablename.valueof("mytable");

admin.disabletable(table);

hcolumndescriptor cf1 = ...;
admin.addcolumn(table, cf1);      // adding new columnfamily
hcolumndescriptor cf2 = ...;
admin.modifycolumn(table, cf2);    // modifying existing columnfamily

admin.enabletable(table);

rowkey设计

rowkey是不可分割的字节数组,按字典序存储在表中。

由于:region基于rowkey为一个区间的行提供服务 hfile在硬盘上存储有序的行 所以rowkey就极大的影响了hbase的性能。

rowkey就是索引,如果不清楚rowkey就只能扫描全表,那么性能将会大幅度下降。

这里用影片热度排行榜举例:

1、rowkey是以字典序从大到小

原生hbase只支持从小到大排序,要想实现从大到小,可以采用 rowkey=integer.max_value-rowkey的方式,在应用层再转回来完成需求。

2、rowkey尽量散列

rowkey要尽量散列,这样可以保证数据不在一个region上,从而避免了读写的集中。

比如我们可以设计 userid_videoid 拼接字符串 这样的话user就会不均匀。

有三种办法解决: 反转userid 散列userid 将userid取模后进行md5加密 取前6位加入userid中

3、rowkey长度要尽量短

rowkey过长,存储开销会大。

rowkey过长,会导致内存的利用率降低,进而降低索引命中率。

列族

列族是一些列的集合,一个列族所有成员都有同样的前缀,比如courses:history 和 courses:math都是courses列族的成员。冒号是分隔符。列族前缀必须是可输出字符,列可由任意字节数组组成。

列族必须在表建立的时候声明,列则不需要特别声明,用户随时可以创建新列。

经验法则:

  • 目标是把 region 的大小限制在 10 到 50 gb 之间。
  • 目标是限制 cell 的大小在 10 mb 之内,如果使用的是 mob类型,限制在 50 mb 之内。否则,考虑把 cell 的数据存储在 hdfs 中,并在 hbase 中存储指向该数据的指针。
  • 典型的 scheme 每张表包含 1 到 3 个列族。hbase 表设计不应当和 rdbms 表设计类似。
  • 对于拥有 1 或 2 个列族的表来说,50-100 个 region 是比较合适的。请记住, region 是列族的连续段。
  • 保持列族名称尽可能短。每个值都会存储列族的名称(忽略前缀编码)。它们不应该像典型 rdbms 那样,是自文档化,描述性的名称。
  • 如果你正在存储基于时间的机器数据或者日志信息,并且 row key 是基于设备 id 或者服务 id + 时间,最终会出现这样一种情况,即更旧的数据 region 永远不会有额外写入。在这种情况下,最终会存在少量的活动 region 和大量不会再有新写入的 region。对于这种情况,可以接受更多的 region 数量,因为资源的消耗只取决于活动 region。
  • 如果只有一个列族会频繁写,那么只让这个列族占用内存。当分配资源的时候注意写入模式。

实例

店铺与商品

店铺shop 商品 item 是多对多的关系

rdbms表结构设计:

商铺表:

列名 列含义
id 主键
name 店铺名称
address 所在地
regdate 注册日期

商品表:

列名 列含义
id 主键
name 商品名称
price 价格
details 商品详情
title 展示名称

关系表:

列名 列含义
shop_id 店铺主键
item_id 商品主键
type 关联类型
hbase表结构设计:

店铺表:

Hbase入门(四)——表结构设计-RowKey

商品表:
Hbase入门(四)——表结构设计-RowKey

微博用户与粉丝

用户与粉丝是一对多

rdbms表结构设计:

用户表:

列名 列含义
id 主键
nickname 用户名

粉丝对应表:

列名 列含义
user_id 用户id
fans_id 粉丝id
hbase表结构设计:

Hbase入门(四)——表结构设计-RowKey

更多实时计算,hbase,flink,kafka等相关技术博文,欢迎关注实时流式计算

Hbase入门(四)——表结构设计-RowKey