Hbase表设计

2017-07-15

来源:http://blog.csdn.net/yfkiss/article/details/26380467

背景知识

HBase基本类型定义:
Table:表
RowKey:行健,主键
Column Family:列族,包含一个或者多个相关列
Column:属于某一个columnfamily,familyName:columnName,每条记录可动态添加
timestamp:每次操作对应的时间戳,支持用户自定义,默认为当前时间的毫秒值
value:值,和timestamp一起支持多version的概念

通过HBase Shell可以拿到一条数据,如下:
hbase(main):007:0> scan ‘bi.dpdim_imei_dpid_mapping’,{LIMIT=>1}
ROW                                                COLUMN+CELL
352784041181135                            column=dim:dpid, timestamp=1400657685457, value=4369382019346202985
对应内容:
352784041181135 =》 RowKey
dim =》 Column Family
column =》 dpid
timestamp => 1400657685457
4369382019346202985  => value

HBase存储结构:
1.HBase以表(HTable)的形式存储数据
2.HTable包括很多行,每行通过RowKey唯一标记,行按照RowKey的字典序排列,表在行的方向上分割为多个HRegion
3.每行包括一个RowKey和多个Column Family,数据按照Column Family进行物理切割,即不同Column Family的数据放在不同的Store中,一个Column Family放在一个Strore中
4. HRegion由多个Store组成。一个Store由物理上存在的一个MemStrore(内存中)和多个StoreFile(HFile)中

设计

从应用角度,有两点比较重要:
1. HBase中RowKey是按照字典序排列的
2. 不同Column Family的数据,在物理上是分开的

在做table设计的时候,主要围绕上述两点做文章。
RowKey的设计需要根据请求数据特点:
1.单个查询,需要尽量缩小Key的长度
2.范围查询,根据RowKey按字典序排列的特点,针对查询需求设计rowkey,保证范围查询的rowkey在物理上存放在一起
Column Family的设计需遵循:尽量避免一次请求需要拿到的Column分布在不同的Column Family中

实例

对于基于RowKey的范围查询设计,我们来看一个实例
1. 给出userid,返回这个userid最近插入的N条数据
2. 给出userid,及一个时间区间,返回这个时间区间的N条数据

针对需求,Key设计如下:
Userid_DataTime_InertTime
Userid:即userid
DataTime:数据所属时间(ms),定义为:Long.MAX_VALUE – dataTime.getTime(),由于RowKey字典序排列,可以使最近插入的数据排在前面,支持“最近插入的N条数据”的需求
InsertTime:数据入库时间(ns),取nanotime(InsertTime的存在是由于在这个应用中,Userid+DataTime不能唯一定位一条数据)
Key生成代码如下:

//生成RowKey

private String buildPutRowKey(int userId, Date addTime) {

String key = userId + “_” + getRowKeyTimestamp(addTime) + “_” + System.nanoTime();

return key;

}

//构建DataTime

private long getRowKeyTimestamp(Date addTime) {

return Long.MAX_VALUE – addTime.getTime();

}

没有评论

发表评论

电子邮件地址不会被公开。