`

Hbase建索引分析

 
阅读更多
1. Hbase的一个例子,IndexBuilde r.建索引.代码及解析如下:
/**
 * Copyright 2009 The Apache Software Foundation
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.frame.base.hbase.hadoop.hbase;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
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.util.Base64;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.util.GenericOptionsParser;

/**
 * 基本列值,创建索引.
 */

/**
 * Example map/reduce job to construct index tables that can be used to quickly
 * find a row based on the value of a column. It demonstrates:
 * [list]
 * <li>Using TableInputFormat and TableMapReduceUtil to use an HTable as input
 * to a map/reduce job.</li>
 * [*]Passing values from main method to children via the configuration.

 * <li>Using MultiTableOutputFormat to output to multiple tables from a
 * map/reduce job.</li>
 * [*]A real use case of building a secondary index over a table.

 * [/list]
 *
 * <h3>Usage</h3>
 *
 * 
 * Modify ${HADOOP_HOME}/conf/hadoop-env.sh to include the hbase jar, the
 * zookeeper jar, the examples output directory, and the hbase conf directory in
 * HADOOP_CLASSPATH, and then run
 * <tt>[b]bin/hadoop org.apache.hadoop.hbase.mapreduce.IndexBuilder TABLE_NAME COLUMN_FAMILY ATTR [ATTR ...][/b]</tt>
 * 

 *
 * 
 * To run with the sample data provided in index-builder-setup.rb, use the
 * arguments [b]<tt>people attributes name email phone</tt>[/b].
 * 

 *
 * 
 * This code was written against HBase 0.21 trunk.
 * 

 */
public class IndexBuilder {
  /** the column family containing the indexed row key */
  public static final byte[] INDEX_COLUMN = Bytes.toBytes("INDEX");
  /** the qualifier containing the indexed row key */
  public static final byte[] INDEX_QUALIFIER = Bytes.toBytes("ROW");

  /**
   * Internal Mapper to be run by Hadoop.
   */
  public static class Map extends
      Mapper<ImmutableBytesWritable, Result, ImmutableBytesWritable, Writable> {
    private byte[] family;
    private HashMap<byte[], ImmutableBytesWritable> indexes;

    @Override
    protected void map(ImmutableBytesWritable rowKey, Result result, Context context)
        throws IOException, InterruptedException {
      for(java.util.Map.Entry<byte[], ImmutableBytesWritable> index : indexes.entrySet()) {
        byte[] qualifier = index.getKey();
        ImmutableBytesWritable tableName = index.getValue();
        byte[] value = result.getValue(family, qualifier);
        if (value != null) {
          // original: row 123 attribute:phone 555-1212
          // index: row 555-1212 INDEX:ROW 123
          Put put = new Put(value);
          put.add(INDEX_COLUMN, INDEX_QUALIFIER, rowKey.get());
          context.write(tableName, put);
        }
      }
    }

    @Override
    protected void setup(Context context) throws IOException,
        InterruptedException {
      Configuration configuration = context.getConfiguration();
      String tableName = configuration.get("index.tablename");
      String[] fields = configuration.getStrings("index.fields");
      String familyName = configuration.get("index.familyname");
      family = Bytes.toBytes(familyName);
      indexes = new HashMap<byte[], ImmutableBytesWritable>();
      for(String field : fields) {
        // if the table is "people" and the field to index is "email", then the
        // index table will be called "people-email"
        indexes.put(Bytes.toBytes(field),
            new ImmutableBytesWritable(Bytes.toBytes(tableName + "-" + field)));
      }
    }
  }

  /**
   * Job configuration.
   */
  public static Job configureJob(Configuration conf, String [] args)
  throws IOException {
    String tableName = args[0];
    String columnFamily = args[1];
    System.out.println("****" + tableName);
    conf.set(TableInputFormat.SCAN, convertScanToString(new Scan()));
    conf.set(TableInputFormat.INPUT_TABLE, tableName);
    conf.set("index.tablename", tableName);
    conf.set("index.familyname", columnFamily);
    String[] fields = new String[args.length - 2];
    for(int i = 0; i < fields.length; i++) {
      fields[i] = args[i + 2];
    }
    conf.setStrings("index.fields", fields);
    //conf.set("index.familyname", "attributes");
    Job job = new Job(conf, tableName);
    job.setJarByClass(IndexBuilder.class);
    job.setMapperClass(Map.class);
    job.setNumReduceTasks(0);//mapred.reduce.tasks,设置为0表示不需要reduce.
    job.setInputFormatClass(TableInputFormat.class);
    job.setOutputFormatClass(MultiTableOutputFormat.class);
    return job;
  }

  /**
   * 把scan转为String类型
   * @param scan
   * @return
   * @throws IOException
   */
  private static String convertScanToString(Scan scan) throws IOException{
	  ByteArrayOutputStream out = new ByteArrayOutputStream();
	  DataOutputStream dos = new DataOutputStream(out);
	  scan.write(dos);
	  return Base64.encodeBytes(out.toByteArray());
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = HBaseConfiguration.create();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if(otherArgs.length < 3) {
      System.err.println("Only " + otherArgs.length + " arguments supplied, required: 3");
      System.err.println("Usage: IndexBuilder <TABLE_NAME> <COLUMN_FAMILY> <ATTR> [<ATTR> ...]");
      System.exit(-1);
    }
    Job job = configureJob(conf, otherArgs);
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

首先需要在Hbase里面建一张表,然后放入一点测试数据,数据结构如下:
/**
   原始表
 * table1
 *          family1:column1   family1:column2
 * key1          value1          value11
 * key2          value2          value22
 *
   索引表
 * table1-column1
 *
 *          INDEX:ROW
 * value1      key1
 * value2      key2
 *
 */

这是我们预想的,执行命令:
bin/hadoop IndexBuilder.jar IndexBuilder 'table1' 'family1' 'column1'

指定参数执行建立Hbase索引表,当然这是一对一的索引建立方法,如果column1可能为相同的,就不能这么建索引了。
不过可以采用:
  value1_key1  empty
  value2_key2  empty

采用前缀的方式,这样Hbase进行搜索的时候,先根据value1得到他的key列表,然后再通过key列表搜索值.



  • 大小: 51.4 KB
1
3
分享到:
评论
9 楼 wubo2qml 2014-02-20  
长见识了,原来这就是给hbase建立索引啊!
8 楼 a123159521 2013-10-30  
shenxiaoming77 写道
指定参数执行建立Hbase索引表,当然这是一对一的索引建立方法,如果column1可能为相同的,就不能这么建索引了。
不过可以采用:

1.value1_key1  empty 
2.value2_key2  empty 


你好, 请问下 在colemn出现相同值得情况下 对该列建立索引表,不知道该怎么设置,上面的
1.value1_key1  empty 
2.value2_key2  empty
具体表示什么意思? 该怎么设置?  请指点一下,谢谢


好久没来了, 这个其实很简单,和HashMap的实现一致。
If key is unique, then <key, value> <key1,value1>
if key is not unique, them <key, valueList>

via key to get valueList, then scan the list to get value.

of cause, the key's generator is decide by your designer.
7 楼 shenxiaoming77 2013-08-09  
指定参数执行建立Hbase索引表,当然这是一对一的索引建立方法,如果column1可能为相同的,就不能这么建索引了。
不过可以采用:

1.value1_key1  empty 
2.value2_key2  empty 


你好, 请问下 在colemn出现相同值得情况下 对该列建立索引表,不知道该怎么设置,上面的
1.value1_key1  empty 
2.value2_key2  empty
具体表示什么意思? 该怎么设置?  请指点一下,谢谢
6 楼 dinghongkai123 2013-06-05  
你好,索引表建立完,怎么查询??
5 楼 571023881 2013-05-18  
a123159521 写道
571023881 写道
你好,这个索引在运行以后显示的结果难道只有显示一个表名么?怎么确切知道索引已经建好了


索引表建好后,有表名,表内还有索引数据


在eclipse里运行后输出一个表名,那么表内的索引数据怎么看到?在终端里使用shell命令倒是可以看到索引表的全部数据,终端可以显示“列族属性+索引的rowkey”
4 楼 a123159521 2013-05-15  
571023881 写道
你好,这个索引在运行以后显示的结果难道只有显示一个表名么?怎么确切知道索引已经建好了


索引表建好后,有表名,表内还有索引数据
3 楼 571023881 2013-05-10  
你好,这个索引在运行以后显示的结果难道只有显示一个表名么?怎么确切知道索引已经建好了
2 楼 a123159521 2011-11-17  
when you run this job,you should be create table first. or right,you will be get error below
anbo724 写道
你好 为什么我使用你的代码在运行的时候,出现问题。

11/11/17 15:01:19 WARN client.HConnectionManager$HConnectionImplementation: Encountered problems when prefetch META table: org.apache.hadoop.hbase.TableNotFoundException: Cannot find row in .META. for table: hero-name, row=hero-name,,99999999999999at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:136)at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:95)at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.prefetchRegionCache(HConnectionManager.java:648)at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegionInMeta(HConnectionManager.java:702)at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegion(HConnectionManager.java:593)at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegion(HConnectionManager.java:558)at org.apache.hadoop.hbase.client.HTable.<init>(HTable.java:172)at org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat$MultiTableRecordWriter.getTable(MultiTableOutputFormat.java:101)at org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat$MultiTableRecordWriter.write(MultiTableOutputFormat.java:127)at org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat$MultiTableRecordWriter.write(MultiTableOutputFormat.java:68)at org.apache.hadoop.mapred.MapTask$NewDirectOutputCollector.write(MapTask.java:498)at org.apache.hadoop.mapreduce.TaskInputOutputContext.write(TaskInputOutputContext.java:80)at an.index.hbase.IndexBuilder$Map.map(IndexBuilder.java:107)at an.index.hbase.IndexBuilder$Map.map(IndexBuilder.java:1)at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144)at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:621)at org.apache.hadoop.mapred.MapTask.run(MapTask.java:305)at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:177)

其中hero是表名 name是对应要建立的索引的列

1 楼 anbo724 2011-11-17  
你好 为什么我使用你的代码在运行的时候,出现问题。

11/11/17 15:01:19 WARN client.HConnectionManager$HConnectionImplementation: Encountered problems when prefetch META table: org.apache.hadoop.hbase.TableNotFoundException: Cannot find row in .META. for table: hero-name, row=hero-name,,99999999999999at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:136)at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:95)at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.prefetchRegionCache(HConnectionManager.java:648)at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegionInMeta(HConnectionManager.java:702)at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegion(HConnectionManager.java:593)at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegion(HConnectionManager.java:558)at org.apache.hadoop.hbase.client.HTable.<init>(HTable.java:172)at org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat$MultiTableRecordWriter.getTable(MultiTableOutputFormat.java:101)at org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat$MultiTableRecordWriter.write(MultiTableOutputFormat.java:127)at org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat$MultiTableRecordWriter.write(MultiTableOutputFormat.java:68)at org.apache.hadoop.mapred.MapTask$NewDirectOutputCollector.write(MapTask.java:498)at org.apache.hadoop.mapreduce.TaskInputOutputContext.write(TaskInputOutputContext.java:80)at an.index.hbase.IndexBuilder$Map.map(IndexBuilder.java:107)at an.index.hbase.IndexBuilder$Map.map(IndexBuilder.java:1)at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144)at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:621)at org.apache.hadoop.mapred.MapTask.run(MapTask.java:305)at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:177)

其中hero是表名 name是对应要建立的索引的列

相关推荐

    HBase二级索引

    第二步,结合索引定义和 DataTable Region 的 StartKey 信息,调用 HBaseAdmin 的 createTable(final HTableDescriptor desc, byte[][] splitKeys) 方法创建索引表。 知识点三:IndexTable RowKey 的设计 Index...

    hbase二级索引

    二级索引的基本思想是创建一个或多个额外的表(也称为索引表),这些表存储了原始数据表的部分信息,通常是需要频繁查询的列。当执行非RowKey查询时,我们先在索引表中查找,找到对应的RowKey,然后再去主表中获取...

    藏经阁-云HBaseSQL及分析.pdf

    Phoenix是一种基于HBase的SQL引擎,提供了索引创建、同步和异步两种方式,并支持检查主表和索引表数据一致性工具。Phoenix也支持GLOBAL INDEX和LOCAL INDEX两种索引方式。 Spark on HBase是Spark提供的一种OLAP解决...

    奇虎360 HBASE 二级索引的设计与实践

    文档中未提供具体的实践内容,但可以想象在实践中会涉及到HBASE集群的搭建、索引的创建和测试、性能的监控和调优,以及对上述设计的有效性进行验证。 结合上文提供的部分内容,我们可以看出奇虎360在设计和实践...

    360HBASE二级索引的设计与实践

    ### 360HBASE二级索引的设计与实践 ...综上所述,360公司在HBase上实施的二级索引方案不仅解决了传统查询方式存在的局限性,还极大地提升了数据处理能力和业务灵活性,为后续的大数据分析工作奠定了坚实的基础。

    云HBaseSQL及分析PhoenixSpark.pdf

    Phoenix允许用户在HBase中创建二级索引,从而快速访问数据,它支持局部索引(Local Index)和全局索引(Global Index)。全局索引适用于写少读多的场景,它将索引数据存储在另一个HBase表中。局部索引则适用于写多读...

    hbase数据可视化系统

    在大数据领域,HBase作为一款分布式列式数据库,因其高并发、低延迟和大规模存储的特点,被广泛应用在实时数据处理和分析中。然而,对于非技术人员来说,直接操作HBase命令行进行数据管理可能会显得较为复杂。因此,...

    hbase用于查询客户端工具

    7. **HBase MapReduce**:MapReduce是Hadoop处理大数据的主要工具,HBase与MapReduce结合可以进行批量数据处理和分析。通过编写MapReduce作业,可以对HBase表进行大规模的数据导入和导出,或者执行复杂的数据分析...

    hbase-2.4.17-bin 安装包

    这个“hbase-2.4.17-bin”安装包提供了HBase的最新稳定版本2.4.17,适用于大数据处理和分析场景。下面将详细介绍HBase的核心概念、安装步骤以及配置和管理。 一、HBase核心概念 1. 表(Table):HBase中的表是由行...

    基于协处理器的HBase分类二级索引设计.pdf

    在IT领域,尤其是在大数据存储和检索的环境下,HBase作为一种分布式、面向列的NoSQL数据库,因其高效的数据处理能力...然而,正确设计和管理二级索引需要深入理解HBase的内部工作原理,以及对数据访问模式的细致分析。

    Hadoop+HBase+Hive+lucene分布式搜索引擎分析系统

    Lucene是一个全文搜索引擎库,它提供文本分析、索引创建和搜索功能。在分布式环境中,可以与其他组件(如Hadoop和HBase)配合,构建高效的搜索引擎。Lucene可以处理大量文本数据,生成倒排索引,从而实现快速的全文...

    HBase:The Definition Guide,HBase权威指南完全版

    此外,还涵盖了HBase的索引机制,如Bloom Filters和二级索引,它们对于优化查询性能至关重要。 在实际应用部分,书中通过一个名为Hush的示例项目,展示了如何构建一个URL缩短服务。Hush演示了HBase在实时数据处理和...

    hbase安装与hbase架构说明

    HBase中的多个HMaster通过Zookeeper的Master Election机制来确定主HMaster,主HMaster负责管理表和Region的生命周期,包括表的创建、删除、分区以及Region的迁移等。 HRegionServer是HBase的核心组件,它们直接处理...

    phoenix-hbase-2.4-5.1.2

    例如,合理创建覆盖索引可以减少HBase的扫描操作,而恰当的分区策略则可以平衡数据分布,避免热点问题。 6. **监控与故障排查** 对于生产环境,监控和故障排查同样重要。Phoenix提供了丰富的JMX指标,可以帮助...

    HBase大数据.zip

    - **实时数据分析**:HBase常用于实时分析,如日志分析、用户行为追踪等。 - **物联网(IoT)**:在物联网场景下,HBase能快速存储和查询大量设备产生的数据。 - **搜索引擎索引**:构建搜索索引,实现快速查询。 ...

    hbase+phoenix 本机测试文档

    在实际测试中,我们可以使用`CREATE INDEX`语句创建索引,然后通过`EXPLAIN`命令查看查询计划,分析索引的使用情况。通过对比有无索引的查询速度,可以直观地了解索引的效果。例如,在“hbase+phoenix测试文档及查询...

    geomesa-hbase安装包

    1. 创建表:使用Geomesa-HBase的工具创建一个或多个数据表,用于存储地理空间数据。 2. 导入数据:使用`geomesa-hbase import`命令将GeoJSON或其他格式的数据导入HBase。 3. 查询数据:通过Geomesa-HBase的命令行...

    hbase-indexer

    2. **索引创建和管理**:允许用户定义索引模式,选择需要索引的列族和列,以及如何映射到Solr字段。 3. **优化的性能**:通过批量处理和并行化索引构建,提高索引效率,减少对HBase和Solr的压力。 4. **查询接口**:...

    HBase@不睡觉书副本.rar

    此外,还讨论了HBase的索引、过滤器、MapReduce与HBase的集成、HBase的数据备份和恢复等高级主题,以满足不同层次读者的需求。 书中还特别强调了HBase在实际项目中的应用案例,例如在互联网日志分析、物联网数据...

Global site tag (gtag.js) - Google Analytics