Hbase多版本使用技巧
Hbase数据导入是在日常工作中经常要处理的问题,在数据量超大时,有事会成为一个非常棘手的问题。
通常我们选用BulkImport的方式完成数据的批量导入:
一般其情况下这是非常高效的处理方式:这种方式在预处理(即生成HFile)时不需要对HBase本身做IO操作,导入方式是一个mv操作,并可以实现多线程导入
然而在处理依赖原数据的插入操作时,生成HFile时需要一次get操作,尽管在mapreduce中,将靠近的rowkey放在一个reduce中处理,但是get操作任然会受到
各种不可预知的因素影响,例如regionserver本身的问题等,这使得生成HFile的时间成为不可预知的因素。
针对这类问题,我们可以考虑使用版本控制的方式完成bulkimprt
典型问题:C_time和M_time导入
例如笔者的url表,有两个属性 创建时间和最后修改时间
attr:ctime 和 attr:mtime
对于ctime 我们希望存储的是创建时间,按照hbase的排序,ts最大的cell将排在最前:
因此在创建cell时将ts设置为 (Long.Max_Value - input_time),这样最早的时间将排在最前
例如
hbase(main):020:0> get 'url_attr','http://cn.sh.jt.www/',{COLUMN => [ 'attr'],VERSIONS => 100}
COLUMN CELL
attr:ctime timestamp=9223351916224582068, value=20120630193739
attr:ctime timestamp=9223351916224573175, value=20120630202632
attr:ctime timestamp=9223351916224561790, value=20120630214017
hbase(main):022:0> get 'url_attr','http://cn.sh.jt.www/',{COLUMN => [ 'attr']}
COLUMN CELL
attr:ctime timestamp=9223351916224582068, value=20120630193739
这样使用get时返回的是最早时间 20120630193739
同理: m_time的ts设置为input_time
这样import失败的可能只可能是由于mapreduce程序失败或mv操作失败,和region的性能无关
*需要注意的是hbase中ts的上限是 Long.Max_Value -1
如果将Ts设置为Long.Max_Value 系统将会将当前时间作为时间戳输入
eg:
attr:filterid timestamp=9223372036854775806, value=0
attr:filterid timestamp=1357880364931, value=0
如果输入的ts大于Long的最大值则会报错
put 'url_attr','http://cn.sh.jt.www/','attr:filterid','0',9223372036854775809
ERROR: bignum too big to convert into `long'
这种方式在简单表结构中是非常管用的,但是对于一些复杂操作,例如需要和历史数据做算术操作,就必须又一次get或scan操作。利用hbase提供的mr接口可以尽可能的
将相近的rowKey做在一个reduce中,但还是有导入失败的可能(regionServer失效或延时)