secondary index for hbase

  最近因为业务需求的原因,需要开始研究hbase中的secondary index。

  业务模型有点类似于rmdb中的select  from table where xx=xx,这里的xx无法做成rowkey,因此需要secondary index,否则只能全表扫描。尽管hbase的全表扫描是优势,但是在线应用也接受不了相应的延迟。

  在早期的hbase中(0.20.x)曾经出现过secondary index,但后来因为无法解决的blocker级别issue而在0.89以上的版本中取消了。

  目前0.90.x版本的hbase中有IndexBuilder类,用于离线地创建secondary index,用法是hadoop org.apache.hadoop.hbase.mapreduce.IndexBuilder TABLE_NAME COLUMN_FAMILY ATTR [ATTR ...],如果应用的类型是一次写入或者每天定时写入,那这是个相当不错的选择。

  但是如果想在线地写入index,事情就变得相当有趣了。目前的模型通常如下:
  1. 创建主表的wal edits对象
  2. 创建index表的wal edits对象,该对象特殊标注下,以便在恢复log时不会处理该对象
  3. sync这两个对象到hlog中
  4. 写主表的memstore,写完后执行commit
  5. 收到commit时,将index的写请求放入后台共享作业队列中,离线处理
  6. 返回给client


  可见hbase由于无法解决多行一致性问题,因此让index的写入滞后于数据的写入,然后通过日志来保障最终一致性,这样产生了以下问题:
  1. 如何保证两个对象能够sync到hlog中?
  2. 如何保证failover后,能够知道哪些index队列中的请求还未执行的?
  3. 当发生failover后一段时间后,master的淘汰hlog机制启动后,如何能够知道哪些index  hlog 是没有处理的?由于淘汰机制是检查hlog与storefile中的timestamp来进行的,很可能发生删除还没有处理index hlog的问题
  4. 如何自动地创建index表?目前只支持提前手工建好
  5. 读的api如何实现?如果索引不到数据,就直接返回null?还是需要到请求队列中去merge一次?
  6. index如何加载到内存中


  这些问题非常有趣,留待后文慢慢细说。如果大家有思路,或者有其它问题,欢迎一起讨论。

猜你喜欢

转载自koven2049.iteye.com/blog/1036140