`
lookqlp
  • 浏览: 341004 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

HBase数据查询之Coprocessor

阅读更多
二级索引方案   

协处理器的概念、作用和类型不介绍,可以参看:http://www.cnblogs.com/ventlam/archive/2012/10/30/2747024.html,官方blog:https://blogs.apache.org/hbase/entry/coprocessor_introduction

    协处理器其中的一个作用是使用Observer创建二级索引。先举个实际例子:

    我们要查询指定店铺指定客户购买的订单,首先有一张订单详情表,它以被处理后的订单id作为rowkey;其次有一张以客户nick为rowkey的索引表,结构如下:

rowkey family
dp_id+buy_nick1 tid1:null tid2:null ...
dp_id+buy_nick2 tid3:null
...
该表可以通过Coprocessor来构建,实例代码:

public class TestCoprocessor extends BaseRegionObserver {
    @Override
     public void prePut(final ObserverContext<RegionCoprocessorEnvironment> e,
     final Put put, final WALEdit edit, final boolean writeToWAL)
     throws IOException {
         Configuration conf = new Configuration();
         HTable table = new HTable(conf, "index_table");
         List<KeyValue> kv = put.get("data".getBytes(), "name".getBytes());
         Iterator<KeyValue> kvItor = kv.iterator();
         while (kvItor.hasNext()) {
             KeyValue tmp = kvItor.next();
             Put indexPut = new Put(tmp.getValue());
             indexPut.add("index".getBytes(), tmp.getRow(), Bytes.toBytes(System.currentTimeMillis()));
             table.put(indexPut);
         }
         table.close();
     }
}
即继承BaseRegionObserver类,实现prePut方法,在插入订单详情表之前,向索引表插入索引数据。



索引表的使用

先在索引表get索引表,获取tids,然后根据tids查询订单详情表。

当有多个查询条件(多张索引表),根据逻辑运算符(and 、or)确定tids。



使用时注意

1.索引表是一张普通的hbase表,为安全考虑需要开启Hlog记录日志。

2.索引表的rowkey最好是不可变量,避免索引表中产生大量的脏数据。

3.如上例子,column是横向扩展的(宽表),rowkey设计除了要考虑region均衡,也要考虑column数量,即表不要太宽。建议不超过3位数。

4.如上代码,一个put操作其实是先后向两张表put数据,为保证一致性,需要考虑异常处理,建议异常时重试。



效率情况

put操作效率不高,如上代码,每插入一条数据需要创建一个新的索引表连接(可以使用htablepool优化),向索引表插入数据。即耗时是双倍的,对hbase的集群的压力也是双倍的。当索引表有多个时,压力会更大。

查询效率比filter高,毫秒级别,因为都是rowkey的查询。

如上是估计的效率情况,需要根据实际业务场景和集群情况而定,最好做预先测试。



Coprocessor二级索引方案优劣

优点:在put压力不大、索引region均衡的情况下,查询很快。

缺点:业务性比较强,若有多个字段的查询,需要建立多张索引表,需要保证多张表的数据一致性,且在hbase的存储和内存上都会有更高的要求。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics