HBase建立二级索引的一些解决方式

HBase的一级索引就是rowkey,我们仅仅能通过rowkey进行检索。

假设我们相对hbase里面列族的列列进行一些组合查询。就须要采用HBase的二级索引方案来进行多条件的查询。 
常见的二级索引方案有下面几种: 
1.MapReduce方案 
2.ITHBASE方案 
3.IHBASE方案 
4.Coprocessor方案 
5.Solr+hbase方案

MapReduce方案

IndexBuilder:利用MR的方式构建Index 
长处:并发批量构建Index 
缺点:不能实时构建Index

举例: 
原表:

row  1      f1:name  zhangsan
row  2      f1:name  lisi
row  3      f1:name  wangwu

索引表:

row     zhangsan    f1:id   1
row     lisi        f1:id   2
row     wangwu      f1:id   3

Demo:

package IndexDouble;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;import org.apache.commons.collections.map.HashedMap;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HConnectionManager;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat;
import org.apache.hadoop.hbase.mapreduce.TableInputFormat;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.util.GenericOptionsParser;public class IndexBuilder {private String rootDir;private String zkServer;private String port;private Configuration conf; private HConnection hConn = null;private IndexBuilder(String rootDir,String zkServer,String port) throws IOException{this.rootDir = rootDir;this.zkServer = zkServer;this.port = port;conf = HBaseConfiguration.create();conf.set("hbase.rootdir", rootDir);conf.set("hbase.zookeeper.quorum", zkServer);conf.set("hbase.zookeeper.property.clientPort", port);hConn = HConnectionManager.createConnection(conf);  }static class MyMapper extends TableMapper<ImmutableBytesWritable, Put>{//记录了要进行索引的列private Map<byte[], ImmutableBytesWritable> indexes = new HashMap<byte[], ImmutableBytesWritable>();private String familyName;@Overrideprotected void map(ImmutableBytesWritable key, Result value,Context context) throws IOException, InterruptedException {//原始表列Set<byte[]> keys = indexes.keySet();//索引表的rowkey是原始表的列。索引表的列是原始表的rowkeyfor (byte[] k : keys){//获得新建索引表的表名ImmutableBytesWritable indexTableName = indexes.get(k);//Result存放的是原始表的数据//查找到内容             依据列族 和 列 得到原始表的值byte[] val = value.getValue(Bytes.toBytes(familyName), k);if (val != null) {//索引表Put put = new Put(val);//索引表行键//列族  列   原始表的行键put.add(Bytes.toBytes("f1"),Bytes.toBytes("id"),key.get());context.write(indexTableName, put);}}}//真正运行Map之前运行一些处理。

@Override protected void setup(Context context) throws IOException, InterruptedException { //通过上下文得到配置 Configuration conf = context.getConfiguration(); //获得表名 String tableName = conf.get("tableName"); //String family = conf.get("familyName"); //获得列族 familyName = conf.get("columnFamily"); //获得列 String[] qualifiers = conf.getStrings("qualifiers"); for (String qualifier : qualifiers) { //建立一个映射,为每个列创建一个表,表的名字tableName+"-"+qualifier //原始表的列 索引表新建表名 indexes.put(Bytes.toBytes(qualifier), new ImmutableBytesWritable(Bytes.toBytes(tableName+"-"+qualifier))); } } } public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { String rootDir = "hdfs://hadoop1:8020/hbase"; String zkServer = "hadoop1"; String port = "2181"; IndexBuilder conn = new IndexBuilder(rootDir,zkServer,port); String[] otherArgs = new GenericOptionsParser(conn.conf, args).getRemainingArgs(); //IndexBuilder: TableName,ColumnFamily,Qualifier if(otherArgs.length<3){ System.exit(-1); } //表名 String tableName = otherArgs[0]; //列族 String columnFamily = otherArgs[1]; conn.conf.set("tableName", tableName); conn.conf.set("columnFamily", columnFamily); //列 可能存在多个列 String[] qualifiers = new String[otherArgs.length-2]; for (int i = 0; i < qualifiers.length; i++) { qualifiers[i] = otherArgs[i+2]; } //设置列 conn.conf.setStrings("qualifiers", qualifiers); @SuppressWarnings("deprecation") Job job = new Job(conn.conf,tableName); job.setJarByClass(IndexBuilder.class); job.setMapperClass(MyMapper.class); job.setNumReduceTasks(0);//因为不须要运行reduce阶段 job.setInputFormatClass(TableInputFormat.class); job.setOutputFormatClass(MultiTableOutputFormat.class); Scan scan = new Scan(); TableMapReduceUtil.initTableMapperJob(tableName,scan, MyMapper.class, ImmutableBytesWritable.class, Put.class, job); job.waitForCompletion(true); } }

创建原始表
hbase(main):002:0> create 'studentinfo','f1'
0 row(s) in 0.6520 seconds=> Hbase::Table - studentinfohbase(main):003:0> put 'studentinfo','1','f1:name','zhangsan'
0 row(s) in 0.1640 secondshbase(main):004:0> put 'studentinfo','2','f1:name','lisi'
0 row(s) in 0.0240 secondshbase(main):005:0> put 'studentinfo','3','f1:name','wangwu'
0 row(s) in 0.0290 secondshbase(main):006:0> scan 'studentinfo'
ROW                      COLUMN+CELL1                       column=f1:name, timestamp=1436262175823, value=zhangsan2                       column=f1:name, timestamp=1436262183922, value=lisi3                       column=f1:name, timestamp=1436262189250, value=wangwu
3 row(s) in 0.0530 seconds
创建索引表hbase(main):007:0> create 'studentinfo-name','f1'
0 row(s) in 0.7740 seconds=> Hbase::Table - studentinfo-name

运行结果

ITHBASE方案

长处:ITHBase(Indexed Transactional HBase)是HBase的一个事物型的带索引的扩展。 
缺点:须要重构hbase,几年没有更新。 
http://github.com/hbase-trx/hbase-transactional-tableindexed

IHBASE方案

**长处:**IHBase(Indexed HBase)是HBase的一个扩展。用干支持更快的扫描。 
缺点:须要重构hbase。 
原理:在Memstore满了以后刷磁盘时。IHBase会进行拦截请求,并为这个memstore的数据构建索引。索引还有一个CF的方式存储在表内。scan的时候,IHBase会结合索引列中的标记。来加速scan。 
http://github.com/ykulbak/ihbase

Coprocessor方案

HIndex–来自华为的HBase二级索引 
http://github.com/Huawei-Hadoop/hindex

The solution is 100% Java, compatible with Apache HBase 0.94.8, and is open sourced under ASL.

Following capabilities are supported currently. 
1.multiple indexes on table, 
2.multi column index, 
3.index based on part of a column value, 
4.equals and range condition scans using index, and 
5.bulk loading data to indexed table (Indexing done with bulk load).

Solr+hbase方案

Solr是一个独立的企业级搜索应用server,它对并提供相似干Web-service的API接口。用户能够通过http请求,向搜索引擎server提交一定格式的XML文件,生成索引。也能够通过Http Get操作提出查找请求,并得到XML格式的返回结果。

Solr是一个高性能。採用Java5开发。基干Lucene的全文搜索server。同一时候对其进行了扩展。提供了比Lucene更为丰富的查询语言,同一时候实现了可配置、可扩展并对查询性能进行了优化,而且提供了一个完好的功能节理界面。是一款非常优秀的全文搜索引擎。

HBase无可置疑拥有其优势,但其本身仅仅对rowkey支持毫秒级的高速检索,对于多字段的组合查询却无能为力。 
基于Solr的HBase多条件查询原理非常easy。将HBase表中涉及条件过滤的字段和rowkey在Solr中建立索引,通过Solr的多条件查询高速获得符合过滤条件的rowkey值,拿到这些rowkey之后在HBASE中通过指定rowkey进行查询。 

hbase二级索引解决方案相关推荐

  1. hbase组合rowkey_「从零单排HBase 11」HBase二级索引解决方案

    HBase一个令人惋惜的地方,就是不支持二级索引.因此,社区有了很多补充方案来填补HBase的二级索引能力的缺陷. 今天,我们就来看看有哪些二级索引方案,通过对比各个方案的优缺点,并结合我们的具体场景 ...

  2. 使用solr构建hbase二级索引

    使用solr构建hbase二级索引 @(HBASE)[hbase, solr] 使用solr构建hbase二级索引 一概述 一业务场景描述 二技术方案 1技术方案一 2技术方案二 3关于索引的建议 二 ...

  3. CDH 6 安装 Hbase 二级索引 Solr + Key-Value Store Indexer

    目录 一.集群安装Solr +  Key-Value Store Indexer 二.创建Hbase二级索引 1.更改表结构,允许复制 2.创建相应的SolrCloud集合 3.创建 collecti ...

  4. 基于Solr的Hbase二级索引

    关于Hbase二级索引 HBase 是一个列存数据库,每行数据只有一个主键RowKey,无法依据指定列的数据进行检索.查询时需要通过RowKey进行检索,然后查看指定列的数据是什么,效率低下.在实际应 ...

  5. 基于ES的HBase二级索引方案

    HBase不支持多条件查询,不提供二级索引,难以满足用户对检索功能多样性和高效率两方面的需求.由索引模块的需求分析可知,本文解决通过,提出数据与索引的分离,利用HBase数据库的存储模式灵活多变,容纳 ...

  6. 华为HBase 二级索引调研

    1.Overall Solution 解决思想: 一个user table对应一个index table index的创建与更新全部在RS端的cp-processor里实现 核心思想:一个actual ...

  7. (转)HBase二级索引与Join

    二级索引与索引Join是Online业务系统要求存储引擎提供的基本特性.RDBMS支持得比较好,NOSQL阵营也在摸索着符合自身特点的最佳解决方案. 这篇文章会以HBase做为对象来探讨如何基于Hba ...

  8. Hbase二级索引入门

    本节的标题也可能是"如果我的表行键看起来像这样,但我也想像这样查询我的表该怎么办". 列表上的一个常见示例是其中rowkey的格式为" user-timestamp&qu ...

  9. 阿里云EMR异步构建云HBase二级索引

    一.非HA EMR构建二级索引 云HBase借助Phoenix实现二级索引功能,对于Phoenix二级索引的详细介绍可参考https://yq.aliyun.com/articles/536850?s ...

  10. Hbase 二级索引 Solr int字段排序问题 can not sort on multivalued field

    Hbase Solr 同步二级索引后,进行int字段排序时报错 报错如下 {"responseHeader":{"zkConnected":true," ...

最新文章

  1. R语言将dataframe数据从宽表(wide)变为长表(long)实战:tidyr包的gather函数、cdata包的unpivot_to_blocks函数、data.table使用melt函数
  2. 招青年博士,年薪70-80万,200万以上补贴,直聘博导!苏州大学
  3. Python编程基础:第十一节 for循环For Loops
  4. 超详细!各种内部排序算法的比较
  5. 推荐 12 个学习前端必备的神仙级工具类项目与网站
  6. 基于Http替补新闻WebService数据交换
  7. 线性代数四之动态DP(广义矩阵加速)——Can you answer these queries III,保卫王国
  8. Spring Boot中的高级配置文件管理
  9. 2013应届毕业生“东方通”校招应聘总结
  10. Mac下安装atari_py报错Exception: ROM is missing for pong
  11. 页面定时跳转的js和php的代码实现和页面定时刷新
  12. Java通过代理服务器访问外部网络
  13. 2021-05-21
  14. 路径太深 无法删除文件夹 之解决办法
  15. Google Code 中使用svn工具说明
  16. AG-DST论文笔记
  17. SAP License Keys申请和导入
  18. POI word 内容提取 Strict OOXML isn‘t currently supported, please see bug #57699
  19. 如何使用 AVIF 图片格式
  20. 故障恢复控制台应用指南

热门文章

  1. 一网打尽车载以太网之SOMEIP(上)
  2. 基于支付场景下的微服务改造与性能优化
  3. cad2020打印样式放在哪个文件夹_CAD图形打印相关问题!
  4. 三连杆机械臂正运动学python模拟——运动学学习(一)
  5. Delphi微信公众号开发
  6. WIN10完全卸载anaconda
  7. 老饼教你深入浅出理解-《牛顿法求极值》
  8. matlab里的计算符号,Matlab符号运算总结
  9. 华为荣耀笔记本linux怎么下载软件,华为magic book笔记本怎么下载软件
  10. Python绘图 \ 数据可视化