根据7位userid + 用户行为时间戳timestamp设计hbase rowkey
根据hbase特性,rowkey高位散列,防止数据热点,低位连续,利于查询
rowkey设计如下,用userid反转,放在高位,则rowkey第一位从0~9散列,用户行为时间timestamp放低位,用于连续
由于userid不规整,或=0,或缺位,则需要补齐,补齐规则如下
- 如果userid是正常7位,则直接反转,用类型1表示
- 如果userid=0 或null,取7位随机数,不反转,用类型2表示
- 如果userid少于7位但不等于0,则不反转,直接后面补0,用类型3表示
如下面从hive中查询数据导入hbase,对userid的处理逻辑
select userid
, a.starttime
, concat(case when length(userid) =7 then concat(reverse(userid),'-',1) -- 如果userid是正常7位,则直接反转,用类型1表示
when userid = 0 or userid is null then concat(substr(concat(ceil(rand()*10000000),'00000000'),0,7),'-',2) -- 如果userid=0 或null,取7位随机数,不反转,用类型2表示
else concat(substr(concat(userid,'0000000'),0,7),'-',3) end,'-',a.starttime) -- 如果userid少于7位但不等于0,则不反转,直接后面补0,用类型3表示
as rowkey,a.current_page
from dw_apppagelog a
对hbase表进行预分区:
若不进行预分区,rowkey前缀散列,如字符型0,1,2,3,4,5,6,7,8,9,数据写入时,进来的rowkey时随机的,首先只有一个region,内部数据按rowkey的字典顺序,如0xxx,1xxx,2xxxx,3xxxx,4xxxx…9xxxx,当达到region分裂条件时,取一个midkey,本例假设取5xxxx,分裂成两个region,接下来进来的数据,如果前缀<5,则往前一个region写,如果>=5则往后面的region写,内部还是字典排序,然后由regionserver维护每一个region的startrowkey和endrowkey
若进行了预分区,则每条数据进来按照分区前缀,写往相应的region,无需在数据写入过程中region split,提升了hbase的性能