一条数据的HBase之旅,简明HBase入门教程7:构建Put对象

举报
Jaison 发表于 2018/04/03 17:28:37 2018/04/03
【摘要】 本文介绍如何将一条待写入的数据组装成HBase的Put对象,这过程涉及到了如何设计RowKey,比较了几种RowKey设计的优劣,以及如何设计列

设计合理的RowKey

RowKey通常是一个或若干个字段的直接组合或经一定处理后的信息,因为一个表中所有的数据都是基于RowKey排序的,RowKey的设计对读写都会有直接的性能影响。

我们基于本文的样例数据,先给出两种RowKey的设计,并简单讨论各自的优缺点:

样例数据:

一条数据的HBase之旅,简明HBase入门教程-Write全流程

示例数据

RowKey Format 1: Mobile1 + StartTime

为了方便读者理解,我们在两个字段之间添加了连接符”^”。如下是RowKey以及相关排序结果:

一条数据的HBase之旅,简明HBase入门教程-Write全流程

RowKey Format 1

RowKey Format 2: StartTime + Mobile1

一条数据的HBase之旅,简明HBase入门教程-Write全流程

RowKey Format 2

从上面两个表格可以看出来,不同的字段组合顺序设计,带来截然不同的排序结果,我们将RowKey中的第一个字段称之为“先导字段”。第一种设计,有利于查询”手机号码XXX的在某时间范围内的数据记录”,但不利于查询”某段时间范围内有哪些手机号码拨出了电话?”,而第二种设计却恰好相反。

上面是两种设计都是两个字段的直接组合,这种设计在实际应用中,会带来读写热点问题,难以保障数据读写请求在所有Regions之间的负载均衡。避免热点的常见方法有如下几种:


Reversing


如果先导字段本身会带来热点问题,但该字段尾部的信息却具备良好的随机性,此时,可以考虑将先导字段做反转处理,将尾部几位直接提前到前面,或者直接将整个字段完全反转。

先导字段Mobile1翻转后,就具备非常好的随机性。

例如:

13400001111^201803010800

将先导字段Mobile1反转后的RowKey变为:

11110000431^201803010800


Salting


Salting的原理是在RowKey的前面添加固定长度的随机Bytes,随机Bytes能保障数据在所有Regions间的负载均衡。

一条数据的HBase之旅,简明HBase入门教程-Write全流程

RowKey With Salting

Salting能很好的保障写入时将数据均匀分散到各个Region中,但对于读取却是不友好的,例如,如果读取Mobile1为”13400001111″在20180301这一天的数据记录时,因为Salting Bytes信息是随机选择添加的,查询时并不知道前面添加的Salting Bytes是”A”,因此{“A”, “B”, “C”}所关联的Regions都得去查看一下。


Hashing


Hashing是将一个RowKey通过一个Hash函数生成一组固定长度的bytes,Hash函数能保障所生成的随机bytes具备良好的离散度,从而也能够均匀打散到各个Region中。Hashing既有利于随机写入,又利于基于知道RowKey各字段的确切信息之后的随机读取操作,但如果是基于RowKey范围的Scan或者是RowKey的模糊信息进行查询的话,就会带来显著的性能问题,因为原来在字典顺序相邻的RowKey列表,通过Hashing打散后导致这些数据被分散到了多个Region中。

因此,RowKey的设计,需要充分考虑业务的读写特点

本文内容假设RowKey设计:reversing(Mobile1) +StartTime

也就是说,RowKey由反转处理后的Mobile1与StartTime组成。对于我们所关注的这行数据:

一条数据的HBase之旅,简明HBase入门教程-Write全流程

关注的数据记录

RowKey应该为: 66660000431^201803011300

因为创建表时预设的Region与RowKey强相关,我们现在才可以给出本文样例所需要创建的表的”Region分割点“信息:

假设,Region分割点为“1,2,3,4,5,6,7,8,9”,基于这9个分割点,可以预先创建10个Region,这10个Region的StartKey和StopKey如下所示:

一条数据的HBase之旅,简明HBase入门教程-Write全流程

Region划分信息

  • 第一个Region的StartKey为空,最后一个Region的StopKey为空

  • 每一个Region区间,都包含StartKey本身,但不包含StopKey

  • 由于Mobile1字段的最后一位是0~9之间的随机数字,因此,可以均匀打散到这10个Region中

定义列


每一个列在HBase中体现为一个KeyValue,而每一个KeyValue拥有特定的组成结构,这一点在上一篇文章的数据模型章节已经提到过。

所谓的定义列,就是需要定义出每一个列要存放的列族(Column Family)以及列标识(Qualifier)信息。

我们假设,存放样例数据的这个表名称为”TelRecords” ,为了简单起见,仅仅设置了1个名为”I”的列族。

一条数据的HBase之旅,简明HBase入门教程-Write全流程

Column Family以及列标识定义

因为Mobile1与StartTime都已经被包含在RowKey中,所以,不需要再在列中存储一份。关于列族名称与列标识名称,建议应该简短一些,因为这些信息都会被包含在KeyValue里面,过长的名称会导致数据膨胀。

基于RowKey和列定义信息,就可以组建HBase的Put对象,一个Put对象用来描述待写入的一行数据,一个Put可以理解成与某个RowKey关联的1个或多个KeyValue的集合。

至此,这条数据已经转变成了Put对象,如下图所示:

一条数据的HBase之旅,简明HBase入门教程-Write全流程

Put


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。