关于使用hbase进行多维度条件实时查询的方案调研。

  1.MapReduce方案

  优点:并发批量构建Index

  缺点:不能实时构建Index

  2.ITHBASE方案

  缺点:需要重构hbase,几年没有更新。

  3.IHBASE方案

  缺点:需要重构hbase。

  4.Coprocessor方案

  华为的HBase二级索引采用此方案(hindex代码开源)。

  1)、索引和数据分别放在不同表里;

  2)、所有的运算逻辑全都放在服务端;

  3)、需要修改HBase源码,侵入性大

  4)、 查询时无需指定,即可自动使用最优索引

  缺点:代码很复杂,代码量非常多。一下子要弄明白原理可能比较困难。hindex和公司的HBase版本不兼容性

  5.Solr+hbase方案

  缺点:对Solr不熟悉

  6.CCIndex

  缺点: 如存储开销比较大,尤其是当索引列比较多的时候,空间开销会更大;索引更新代价比较高,会影响系统的吞吐量;索引创建以后,不能够动态增加或修改。

  7.360的hbase二级索引

  360二级索引的特点如下:

  1)、索引和Rowkey在同一个表里;

  2)、支持多范围与操作优化;

  3)、支持索引重建

  缺点:没有开源,需要按照他的思想去实现,原理不是太清楚,只明白一点点,按照这个思想来重新搭建也可能非常耗时间。

  8.phoenix的二级索引

  好处:开源,自带二级索引。

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

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

  •HRegion分配给RegionServer管理

  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)方案

  2.1创建单列索引

  2.2同时创建多个单列索引

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

  2.4只根据rowkey创建索引

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

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

  property

  namehbase.coprocessor.region.classes/name

  valueorg.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的方式创建hbase索引。主要的流程如下:

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

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

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

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

  GenerateIndexMapper继承TableMapper类

  LoadIndexMapper类数据批量导入hbase

  SecondIndexMain是驱动类

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

  •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的实现分为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实现在写主表之前将索引数据先写到另外一个表

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

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

  

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

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