Hbase简介

HBASE是在hadoop之上构建非关系型,面向列存储的开源分布式结构化数据存储系统。

HBase表分区与索引管理

•将Table中的数据根据rowKey字段划分为多个HRegion

•HRegion分配给RegionServer管理

HBase系统架构

HBase的局限性

HBase本身只提供基于行键和全表扫描的查询,而行键索引单一,对于多维度的查询困难。

常见的二级索引方案

HBase的一级索引就是rowkey,我们只能通过rowkey进行检索。如果我们相对hbase里面列族的列列进行一些组合查询,就需要采用HBase的二级索引方案来进行多条件的查询。

1. MapReduce方案 
2. ITHBASE(Indexed-Transanctional HBase)方案 
3. IHBASE(Index HBase)方案 
4. Hbase Coprocessor(协处理器)方案 
5. Solr+hbase方案

6. CCIndex(complementalclustering index)方案

HBase二级索引种类

2.1创建单列索引

2.2同时创建多个单列索引

2.3创建联合索引(最多同时支持3个列)

2.4只根据rowkey创建索引

建立全局二级索引

1. 全局建立索引,可以修改hbase-site.xml文件

为所有table加载了一个cp class,可以用”,”分割加载多个class

<property>

<name>hbase.coprocessor.region.classes</name>

<value>org.apache.hadoop.hbase.coprocessor.AggregateImplementation</value>

</property>

单表建立二级索引

2. 单个表建立索引

1.首先disable ‘表名’
2.然后修改表

alter 'LogTable',METHOD=>'table_att','coprocessor'=>'hdfs:///test.jar|www.aboutyun.com.hbase.HbaseCoprocessor|1001'

3. enable '表名'

卸载二级索引

3. 卸载索引

alter 'LogTable', METHOD => 'table_att_unset', NAME => 'coprocessor$1‘

二级索引的设计

设计思路:

图1

二级索引的本质就是建立各列值与行键之间的映射关系

如上图1,当要对F:C1这列建立索引时,只需要建立F:C1各列值到其对应行键的映射关系,如C11->RK1等,这样就完成了对F:C1列值的二级索引的构建,当要查询符合F:C1=C11对应的F:C2的列值时(即根据C1=C11来查询C2的值,图1青色部分)

其查询步骤如下:

1. 根据C1=C11到索引数据中查找其对应的RK,查询得到其对应的RK=RK1

2. 得到RK1后就自然能根据RK1来查询C2的值了 这是构建二级索引大概思路,其他组合查询的联合索引的建立也类似。

 

MapReduce方式创建二级索引

使用整合MapReduce的方式创建hbase索引。主要的流程如下:

1.1扫描输入表,使用hbase继承类TableMapper

1.2获取rowkey和指定字段名称和字段值

1.3创建Put实例, value=rowkey, rowkey=columnName +"_" +columnValue

1.4使用IdentityTableReducer将数据写入索引表

继承TableMapper

GenerateIndexMapper继承TableMapper类

LoadIndexMapper类数据批量导入hbase

SecondIndexMain是驱动类

实例

  1. import org.apache.hadoop.conf.Configuration;
  2. import org.apache.hadoop.hbase.HBaseConfiguration;
  3. import org.apache.hadoop.hbase.client.Put;
  4. import org.apache.hadoop.hbase.client.Result;
  5. import org.apache.hadoop.hbase.client.Scan;
  6. import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
  7. import org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat;
  8. import org.apache.hadoop.hbase.mapreduce.TableInputFormat;
  9. import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
  10. import org.apache.hadoop.hbase.mapreduce.TableMapper;
  11. import org.apache.hadoop.hbase.util.Bytes;
  12. import org.apache.hadoop.mapreduce.Job;
  13. import org.apache.hadoop.util.GenericOptionsParser;
  14. import java.io.IOException;
  15. import java.util.HashMap;
  16. import java.util.Map;
  17. import java.util.Set;
  18. /**
  19. * @Description:Mapreduce构建hbase二级索引
  20. */
  21. public class MyIndexBuilder {
  22. private class MyIndexMapper extends TableMapper<ImmutableBytesWritable, Put> {
  23. //create the map object
  24. private Map<byte[], ImmutableBytesWritable> indexes = new HashMap<byte[], ImmutableBytesWritable>();
  25. //make the cloumnfamily
  26. private String columnFamily;
  27. /**
  28. * Called once for each key/value pair in the input split. Most applications
  29. * should override this, but the default is the identity function.
  30. */
  31. @Override
  32. protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException {
  33. Set<byte[]> keys = indexes.keySet();
  34. for (byte[] k : keys) {
  35. ImmutableBytesWritable indexTableName = indexes.get(k);
  36. byte[] val = value.getValue(Bytes.toBytes(columnFamily), k);
  37. // 索引表的rowkey为原始表的值
  38. Put put = new Put(val);
  39. // 索引表的内容为原始表的rowkey
  40. put.add(Bytes.toBytes("f1"), Bytes.toBytes("id"), key.get());
  41. //context write
  42. context.write(indexTableName, put);
  43. }
  44. // super.map(key, value, context);
  45. }
  46. /**
  47. * Called once at the beginning of the task.
  48. */
  49. @Override
  50. protected void setup(Context context) throws IOException, InterruptedException {
  51. Configuration conf = context.getConfiguration();
  52. String tableName = conf.get("tableName");
  53. columnFamily = conf.get("columnFamily");
  54. String[] qualifiers = conf.getStrings("qualifiers");
  55. // indexes的key为列名,value为索引表名
  56. for (String q : qualifiers) {
  57. indexes.put(
  58. Bytes.toBytes(q),
  59. new ImmutableBytesWritable(Bytes.toBytes(tableName
  60. + "-" + q)));
  61. }
  62. }
  63. // super.setup(context);
  64. }
  65. public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
  66. Configuration conf = HBaseConfiguration.create();
  67. String[] otherargs = new GenericOptionsParser(conf, args)
  68. .getRemainingArgs();// 去除掉没有用的命令行参数
  69. // 输入参数:表名,列族名,列名
  70. if (otherargs.length < 3) {
  71. System.exit(-1);
  72. }
  73. String tableName = otherargs[0];
  74. String columnFamily = otherargs[1];
  75. conf.set("tableName", tableName);
  76. conf.set("columnFamily", columnFamily);
  77. String[] qualifiers = new String[otherargs.length - 2];
  78. for (int i = 0; i < qualifiers.length; i++) {
  79. qualifiers[i] = otherargs[i + 2];
  80. }
  81. conf.setStrings("qualifiers", qualifiers);
  82. Job job = new Job(conf, tableName);
  83. job.setJarByClass(MyIndexBuilder.class);
  84. job.setMapperClass(MyIndexMapper.class);
  85. job.setNumReduceTasks(0);
  86. job.setInputFormatClass(TableInputFormat.class);
  87. // 可以输出多张表
  88. job.setOutputFormatClass(MultiTableOutputFormat.class);
  89. Scan scan = new Scan();
  90. scan.setCaching(1000);
  91. TableMapReduceUtil.initTableMapperJob(tableName, scan, MyIndexMapper.class,
  92. ImmutableBytesWritable.class, Put.class, job);
  93. job.waitForCompletion(true);
  94. }
  95. }

HBase 协处理器(coprocessor)实现二级索引

HBase在0.92之后引入了coprocessors,提供了一系列的钩子,让我们能够轻易实现访问控制和二级索引的特性。

HBase Coprocessor简介

•HBase Coprocessor受启发于Google的Jeff Dean在LADIS’09 上的报告

–Google BigTable的Coprocessor特点

•在每个表服务器的任何tablet上均可执行用户代码

•提供客户端调用接口 (coprocessor客户端lib将可定位每个row/range的位置;多行读写将自

动分片为多个并行的RPC调用)

•提供可构建分布式服务的灵活的编程模型

•可以自动扩展,负载均衡等

–与Google Bigtable Coprocessor相比

•Bigtable coprocessor 以独立的进程执行,可以更好的控制CP计算所需资源

•HBase coprocessor是一个在Master/RegionServer进程内的框架,通过在运行时执行用户的代码,在HBase内实现灵活的分布式数据处理功能

•HBase Coprocessor的主要应用场景

–secondary indexing

–complex filtering

–access control

HBase Coprocessor 的实现类型

•HBase Coprocessor的实现分为Observer和Endpoint两种

–Observer类似于触发器,工作在服务器端。可以实现权限管理、监控等

–Endpoint类似于存储过程,工作在服务器端和客户端。可以实现min/max等计算

•Coprocessor的作用范围

–System coprocessor: 对所有table的所有region

–Table coprocessor:对某个table的所有region

•RegionObserver:提供表数据操作事件的钩子函数:Get、Put、Scan等的pre/post处理。

•WALObserver:提供WAL相关操作钩子。

•MasterObserver:提供DDL类型的操作钩子。如创建、删除、修改数据表等。

Endpoint:只适用于RegionServer, 对应于每个table 的Region的处理。

想要更详细的介绍请查阅:

https://blogs.apache.org/hbase/entry/coprocessor_introduction

observers分为三种:

RegionObserver:提供数据操作事件钩子;

WALObserver:提供WAL(write ahead log)相关操作事件钩子;

MasterObserver:提供DDL操作事件钩子。

实例

该例子使用RegionObserver实现在写主表之前将索引数据先写到另外一个表

  1. import org.apache.hadoop.conf.Configuration;
  2. import org.apache.hadoop.hbase.Cell;
  3. import org.apache.hadoop.hbase.KeyValue;
  4. import org.apache.hadoop.hbase.client.Durability;
  5. import org.apache.hadoop.hbase.client.HTable;
  6. import org.apache.hadoop.hbase.client.Put;
  7. import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
  8. import org.apache.hadoop.hbase.coprocessor.ObserverContext;
  9. import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
  10. import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
  11. import java.io.IOException;
  12. import java.util.Iterator;
  13. import java.util.List;
  14. public class IndexHBaseCoprocessor extends BaseRegionObserver {
  15. @Override
  16. public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException {
  17. //set configuration
  18. Configuration conf = new Configuration();
  19. //need conf.set...
  20. HTable table = new HTable(conf, "indexTableName");
  21. List<Cell> kv = put.get("familyName".getBytes(), "columnName".getBytes());
  22. Iterator<Cell> kvItor = kv.iterator();
  23. while (kvItor.hasNext()) {
  24. Cell tmp = kvItor.next();
  25. final byte[] value = tmp.getValue();
  26. Put indexPut = new Put(value);
  27. indexPut.add("familyName".getBytes(), "columnName".getBytes(), tmp.getRow());
  28. table.put(indexPut);
  29. }
  30. table.close();
  31. // super.prePut(e, put, edit, durability);
  32. }
  33. }
  34. 这是类之间的继承关系和实现里面的方法:
  35. public class IndexHBaseCoprocessor extends BaseRegionObserver {
  36. public class BaseRegionObserver implements RegionObserver {
  37. public interface RegionObserver extends Coprocessor {
  38. void prePut(ObserverContext<RegionCoprocessorEnvironment> var1, Put var2, WALEdit var3, Durability var4) throws IOException;
  39. }

写完后要加载到table里面去,先把该文件打包indexTest.jar并上传到hdfs的/hbase-test路径下,然后操作如下:

进入hbase shell ,执行一下命令行:

1. disable ‘testTable’

2.alter ‘testTable’,

METHOD=>’table_att’,’coprocessor’=>’hdfs:///hbase-test/indexTest.jar|com.hbase

.IndexHBaseCoprocessor|1001′

enable ‘testTable’

然后往testTable里面插数据就会自动往indexTableName写数据了。

这就是用coprocessor实现二级索引的例子。

HBase  IndexBuilder.java源码

链接:https://pan.baidu.com/s/140ZTLE-pFJZXeMRo6QQuNg  密码:ql9d

参考博文:

1.http://www.aboutyun.com/forum.php?mod=viewthread&tid=8857&highlight=hbase%2B%B6%FE%BC%B6

2.https://www.cnblogs.com/MOBIN/p/5579088.html

 

HBase二级索引实现方案相关推荐

  1. 基于Solr的Hbase二级索引

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

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

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

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

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

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

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

  5. 华为hbase二级索引(secondary index)细节分析

    转载自:http://ju.outofmemory.cn/entry/50610 华为在HBTC 2012上由其高级技术经理Anoop Sam John透露了其二级索引方案,这在业界引起极大的反响,甚 ...

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

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

  7. 华为HBase 二级索引调研

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

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

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

  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. 将公平注入AI:机器学习模型即使在不公平数据上训练也能产生公平输出
  2. hadoop配置安装
  3. php判断版本根据版本调用不同,C#_C#自动判断Excel版本使用不同的连接字符串,用OLEDB通过设置连接字符串可 - phpStudy...
  4. 题目1183:守形数
  5. 详解SQL Server连接(内连接、外连接、交叉连接)
  6. Ceph 存储集群7-故障排除
  7. Android华容道之一步一步实现-5-图像块移动算法实现
  8. 程序员江湖鄙视链大全,看看你处于链条的哪一级?
  9. 简述java在安卓开发中的应用_Java 自定义注解在安卓开发中的简单运用
  10. Oracle技术之ASM上恢复STANDBY数据库出现ORA-15173错误
  11. Linux 安装 MySQL 数据库
  12. linux信号(一)--unix环境高级编程读书笔记
  13. UILabel「行距,首行缩进」
  14. mysql站内搜索_纯php+mysql打造的站内搜索
  15. 自动驾驶 2-2 硬件配置设计 Hardware Configuration Design
  16. 前端优秀框架jQuery weui推荐
  17. 2021西工大计算机专硕,计算机专硕2021考研形势分析,考研小白戳
  18. 13.1.X:ByteScout PDF Extractor SDK
  19. 打开office报错提示向程序发送命令时出现问题
  20. c语言开发ios应用程序,马上着手开发iOS应用程序:三、应用开发基础

热门文章

  1. Linux下关闭udhcpc客户端时,通知服务器释放租约
  2. 小工具-悬浮窗LogViewer在android手机上查看数据日志
  3. python脚本的编写_python脚本编写与执行
  4. Qt编写linux上视频流播放器(支持海康大华宇视等各种网络摄像机)
  5. 程序员-这有一份520表白秘笈送给你
  6. ArcGIS基本操作
  7. boost LNK2005 重定义错误
  8. SDN技术的十个关键因素
  9. mysql 完整卸载教程_彻底卸载MySQL数据库教程
  10. java调用打印机打印