Hbase的协处理器(Coprocessor的两种实现observer 和 endpoint,加载卸载方式,二级索引)

1、协处理器—Coprocessor

1、 起源

HBase 作为列族数据库最经常被人诟病的特性包括:无法轻易建立“二级索引”,难以执行求和、计数、排序等操作。比如,在旧版本的(<0.92) HBase 中,统计数据表的总行数,需要使用 Counter 方法,执行一次 MapReduce Job 才能得到。
虽然 HBase 在数据存储层中集成了 MapReduce,能够有效用于数据表的分布式计算。然而在很多情况下,做一些简单的相加或者聚合计算的时候,如果直接将计算过程放置在 server 端,能够减少通讯开销,从而获得很好的性能提升。
于是,HBase 在 0.92 之后引入了协处理器(coprocessors),实现一些激动人心的新特性:能够轻易建立二次索引、复杂过滤器(谓词下推)以及访问控制等

2、协处理器有两种:observer 和 endpoint
3、Observer

类似于传统数据库中的触发器,当发生某些事件的时候这类协处理器会被 Server 端调用
Observer Coprocessor 就是一些散布在 HBase Server 端代码中的 hook 钩子,在固定的事件发生时被调用。比如:put 操作之前有钩子函数 prePut,该函数在 put 操作执行前会被 Region Server 调用;在 put 操作之后则有 postPut 钩子函数

以 HBase0.92 版本为例,它提供了三种观察者接口:

● RegionObserver:提供客户端的数据操纵事件钩子:Get、Put、Delete、Scan 等。
● WALObserver:提供 WAL 相关操作钩子。
● MasterObserver:提供 DDL-类型的操作钩子。如创建、删除、修改数据表等。

到 0.96 版本又新增一个 RegionServerObserver
其实到现在的 hbase-1.2.6 版本中:Observer 的种类已经很多了:
Hbase的协处理器(Coprocessor的两种实现observer 和 endpoint,加载卸载方式,二级索引)_第1张图片
下图是以 RegionObserver 为例子讲解 Observer 这种协处理器的原理
Hbase的协处理器(Coprocessor的两种实现observer 和 endpoint,加载卸载方式,二级索引)_第2张图片

1、客户端发出 put 请求
2、该请求被分派给合适的 RegionServer 和 region
3、coprocessorHost 拦截该请求,然后在该表上登记的每个 RegionObserver 上调用 prePut()
4、如果没有被 prePut()拦截,该请求继续送到 region,然后进行处理
5、region 产生的结果再次被 CoprocessorHost 拦截,调用 postPut()
6、假如没有 postPut()拦截该响应,最终结果被返回给客户端
4、Endpoint

协处理器类似传统数据库中的存储过程,客户端可以调用这些 Endpoint 协处理器执行一段Server 端代码,并将 Server 端代码的结果返回给客户端进一步处理,最常见的用法就是进行聚集操作。如果没有协处理器,当用户需要找出一张表中的最大数据,即 max 聚合操作,就必须进行全表扫描,在客户端代码内遍历扫描结果,并执行求最大值的操作。这样的方法无法利用底层集群的并发能力,而将所有计算都集中到 Client 端统一执行,势必效率低下。利用 Coprocessor,用户可以将求最大值的代码部署到 HBase Server端,HBase 将利用底层cluster 的多个节点并发执行求最大值的操作。即在每个 Region 范围内执行求最大值的代码,将每个 Region 的最大值在 Region Server 端计算出,仅仅将该 max 值返回给客户端。在客户端进一步将多个 Region 的最大值进一步处理而找到其中的最大值。这整体的执行效率就会提高很多
下图是 EndPoint 的工作原理
Hbase的协处理器(Coprocessor的两种实现observer 和 endpoint,加载卸载方式,二级索引)_第3张图片

5、总结
  1. Observer 允许集群在正常的客户端操作过程中可以有不同的行为表现
    Endpoint 允许扩展集群的能力,对客户端应用开放新的运算命令
  2. observer 类似于 RDBMS 中的触发器,主要在服务端工作
    endpoint 类似于 RDBMS 中的存储过程,主要在服务端工作
  3. observer 可以实现权限管理、优先级设置、监控、ddl 控制、二级索引等功能
    endpoint 可以实现 min、max、avg、sum、distinct、group by 等功能

2、协处理加载方式

协处理器的加载方式有两种,我们称之为静态加载方式(Static Load)和动态加载方式(Dynamic Load)。静态加载的协处理器称之为 System Coprocessor,动态加载的协处理器称之为 Table Coprocessor

1、 静态加载

通过修改 hbase-site.xml 这个文件来实现,启动全局 aggregation,能过操纵所有的表上的数据。只需要添加如下代码:


	hbase.coprocessor.user.region.classes
	org.apache.hadoop.hbase.coprocessor.AggregateImplementation

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

2、 动态加载

启用表 aggregation,只对特定的表生效。通过 HBase Shell 来实现。

◆disable 指定表

hbase> disable 'mytable'

◆添加 aggregation

hbase> alter 'mytable', METHOD => 'table_att','coprocessor'=>'|org.apache.Hadoop.hbase.coprocessor.AggregateImplementation||'

◆重启指定表

hbase> enable 'mytable'

3、 协处理器卸载

只需要三步即可:

disable 'mytable'
alter 'mytable',METHOD=>'table_att_unset',NAME=>'coprocessor$1'
enable 'mytable

4.二级索引

由于 HBase 本身没有二级索引(Secondary Index)机制,基于索引检索数据只能单纯地依靠RowKey,为了能支持多条件查询,开发者需要将所有可能作为查询条件的字段一一拼接到RowKey 中,这是 HBase 开发中极为常见的做法
二级索引的本质就是建立各列值与行键之间的映射关系

在社交类应用中,经常需要快速检索各用户的关注列表 guanzhu,同时,又需要反向检索各种户的粉丝列表 fensi,为了实现这个需求,最佳实践是建立两张互为反向的表

一个表为正向索引关注表:“guanzhu”:
Rowkey: a
f1:from b

另一个表为反向索引粉丝表:“fensi“:
Rowkey: b
f1:from a

建表语句:
create 'guanzhu','cf1'
create 'fensi','cf1'

实现效果:
往 guanzhu 表插入一条数据
put 'guanzhu','a','cf1:from','b'
就会自动往 fensi 表插入一条数据
put 'fensi','b','cf1:from','a'

插入一条关注信息时,为了减轻应用端维护反向索引表的负担,可用 Observer 协处理器实现
Hbase的协处理器(Coprocessor的两种实现observer 和 endpoint,加载卸载方式,二级索引)_第4张图片

实现步骤
1、 编写 TestCoprocessor 代码

package com.ghgj.mazh.hbase.coprocessor;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;

public class TestCoprocessor extends BaseRegionObserver {
	static Configuration config = HBaseConfiguration.create();
	static HTable table = null;
	static {
		config.set("hbase.zookeeper.quorum", "hadoop02:2181,hadoop03:2181,hadoop04:2181,hadoop05:2181");
		try {
			table = new HTable(config, "guanzhu");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException {
		// super.prePut(e, put, edit, durability);
		byte[] row = put.getRow();
		Cell cell = put.get("f1".getBytes(), "from".getBytes()).get(0);
		Put putIndex = new Put(cell.getValueArray(), cell.getValueOffset(), 
		cell.getValueLength());
		putIndex.addColumn("f1".getBytes(), "from".getBytes(), row);
		table.put(putIndex);
		table.close();
		}
	}

2、 打成 jar 包(cppp.jar),上传到 hdfs 中的 hbasecp 目录下

[hadoop@hadoop02 soft]# hadoop fs -mkdir -p /hbasecp
[hadoop@hadoop02 soft]# hadoop fs -put cppp.jar /hbasecp

3、 建 hbase 表,请按以下顺序操作

hbase(main):036:0> create 'guanzhu','f1'
hbase(main):036:0> create 'fensi','f1'
hbase(main):036:0> disable 'fensi'
hbase(main):036:0> alter 'fensi',METHOD => 'table_att','coprocessor' => 
'hdfs://myha01/hbasecp/cppp.jar|com.ghgj.mazh.hbase.coprocessor.TestCoprocessor|1001	|'

#理解 coprocessor 的四个参数,分别用'|'隔开的
1、 你的协处理器 jar 包所在 hdfs 上的路径
2、 协处理器类全限定名
3、 协处理器加载顺序
4、 传参

hbase(main):036:0> enable 'fensi'

4、 现在插入数据进行验证,命令行和代码都可以
在这里插入图片描述
Hbase的协处理器(Coprocessor的两种实现observer 和 endpoint,加载卸载方式,二级索引)_第5张图片

5、 结果演示
Hbase的协处理器(Coprocessor的两种实现observer 和 endpoint,加载卸载方式,二级索引)_第6张图片
二级索引好文推荐
HBase二级索引方案

你可能感兴趣的:(大数据学习)