Hbase-之Coprocessor实现implements & 加载load

Hbase-之Coprocessor实现implements与加载load

1 Coprocessor简介

小伙伴们,如果需要了解更多协处理器相关的原理

请参阅:赖明杰的博客(早期)

还请参阅:怎么使用hbase-协处理器

这里面有好多好多的东西,很全面。

Hbase的协处理器是继Goolgle的Bigtable的协处理器之后衍生出来的一个模型;协处理器允许将用户的自定义代码直接运行在RegionServer上,从而对Hbase中的数据进行访问与管理。

虽然对于开发者来说,coprocessor有着良好的特性,但是使用Coprocessor的时候会存在以下风险,因为它是直接运行在RegionServer上而且能直接访问数据

  • 中间人对数据库的攻击
  • 恶意的数据访问
  • 目前为止还无法预防coprocessor访问数据出错
  • 而且Coprocessor目前是没有与hbase的集群进行资源隔离的,所以一个用意良好但是操作不当的coprocessor能直接降低集群的性能以及稳定性!

Hbase的coprocessor的Get\Scan操作类似于RDBM中的Select操作,而Hbase的Filter就类似于RDBM中的Where操作,当获取到数据之后,你需要在Client本地内存中存储数据从而进行计算操作,当fetch的数据小的时候(几千行,几列)那是没什么问题的,但是假如你需要计算的数据是基于(十亿行,百万列),那么你本地就hold不住了,而且需要大量的网络开销。所以只能将计算操作从客户端迁移到服务端,那么协处理器在这就有很强的实用性了。

2 Coprocessor类比

  • Trigger & 存储过程

Observer协处理器提供了不同的回调函数,类似于关系型数据库中的触发器,比如:可以在Get、Put、Delete、Scan前后作相应的回调操作

Endpoint协处理器就类似于存储过程,它允许你直接将代码交给RegionServer执行,将本来需要在客户端进行的计算迁移到服务端,而不是直接将数据全盘从服务端拉取到Client再在本地作计算。

  • Mapreduce

Mapreduce基于这样一个原则,将计算代码移动到数据所在的位置进行计算,然后output结果,coprocessor也是基于同样的原则。

  • AOP

coprocessor优点类似于Spring中的AOP(Aspect Oriented Programming),我们可以把Coprocessor操作当作请求到达目的地之前(甚至可以更改目的地)拦截请求,然后执行一些其它的自定义代码。

  • https://hbase.apache.org/2.2/book.html#_dynamic_unloading)

3 Coprocessor协处理器分类

3.1 Observer Coprocessors

Observer协处理器是一种hbase时间发生前后的触发器,pre前缀的钩子函数在事件之前执行,post在之后执行

3.1.1 Observer Coprocessors使用场景

Observer Coprocessors协处理器有以下使用场景

  • 安全校验
  • 二级索引
  • 关联字段插入(实现RDBM中的join字段插入)
3.1.2 Observer Coprocessors分类

3.2 Endpoint Coprocessors

Endpoint与Observer不同的是,Observer是触发操作,代码是透明的,而Endpoint是将代码移动到数据所在的进行计算操作,必须明确调用CoprocessorService()方法,这个方法适用于Htable或Table,Endpoint适用于count\sum\avg等大型跨区域海量数据统计操作的场景。

具体操作可以参阅:Endpoint

4 如何实现自定义Coprocessor并加载到hbase

4.1 代码实现

import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.coprocessor.RegionObserver;

public class TestCoprocessor01 implements RegionObserver, Coprocessor {
  //override the mothod like prePut/postPut and so on.
}

我们只需要implements以下任意一个接口,即可以自定义Coprocessor。

  • Coprocessor
  • RegionObserver
  • CoprocessorService(标记为过时版本)

定义开发完之后,我们需要将coprocessor代码并加载到cluster,Hbase支持2种加载方式:静态加载和动态加载

4.2 加载coprocessor

4.2.1 静态加载

静态加载必须重启Hbase集群,具体静态加载的流程如下:

  • hbase.coprocessor.region.classes for RegionObservers and Endpoints.
  • hbase.coprocessor.wal.classes for WALObservers.
  • hbase.coprocessor.master.classes for MasterObservers.

1、我们需要在hbase-site.xml中配置以上的配置选项

<property>
    <name>hbase.coprocessor.region.classes</name>
    <value>org.myname.hbase.coprocessor.endpoint.SumEndPoint,...,...</value>
</property>

记住:如果我们需要同时加载多个协处理器的类,记得用逗号分开,同时必须保证协处理器类所在的Jar包在Hbase的类路径下能被找到。

通过静态加载的协处理器被称为系统协处理器,它们对于Hbase中所有的表中的所有的Region都是可用的。对于同时加载多个Coprocessor类,第一个优先级最高Coprocessor.Priority.SYSTEM,随着逗号的推移,优先级值+=1,值越高,优先级越低。

2、将打包的代码放在hbase的classpath下

将代码放在${HBASE_HOME}/lib目录下

3、重启hbase集群

注意:如果我们需要将静态的协处理器卸载,只需要将hbase-site.xml相关的配置参数干掉,将jar包干掉,重启hbase集群,ojbk。

4.2.2 动态加载

动态加载不需要重启hbase集群,看似比静态加载更加灵活方便,但是动态加载的coprocessor只能针对某个指定的table加载,而且只对该表生效,因此通过动态加载的协处理器被称为Table 协处理器

而且动态加载协处理器相当于对一个Table的schema作修改,我们必须先disable该table,这里有3中方式动态加载协处理器。

在加载之前我们需要保证以下前提:

  • A JAR called coprocessor.jar contains the Coprocessor implementation along with all of its dependencies.
  • The JAR is available in HDFS in some location like hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar.

加载方式如下:

  • hbase shell方式加载

    #offline该表
    hbase> disable 'users'
    
    #加载协处理器
    #1、hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar 为文件路径
    #2、org.myname.hbase.Coprocessor.RegionObserverExample 为协处理器主类
    #3、1073741823为优先级,类型为Integer
    #4、arg1=1,arg2=2为参数,传递给RegionObserverExample,为可选项
    bin/hbase alter 'users', METHOD => 'table_att', 'Coprocessor'=>'hdfs://<namenode>:<port>/
    user/<hadoop-user>/coprocessor.jar| org.myname.hbase.Coprocessor.RegionObserverExample|1073741823|
    arg1=1,arg2=2'
    
    #online该表
    hbase(main):003:0> enable 'users'
    
    #校验协处理器是否加载成功
    hbase(main):04:0> describe 'users'
    
  • Java API的方式加载(所有版本适用)

    TableName tableName = TableName.valueOf("users");
    String path = "hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar";
    Configuration conf = HBaseConfiguration.create();
    Connection connection = ConnectionFactory.createConnection(conf);
    Admin admin = connection.getAdmin();
    admin.disableTable(tableName);
    HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
    HColumnDescriptor columnFamily1 = new HColumnDescriptor("personalDet");
    columnFamily1.setMaxVersions(3);
    hTableDescriptor.addFamily(columnFamily1);
    HColumnDescriptor columnFamily2 = new HColumnDescriptor("salaryDet");
    columnFamily2.setMaxVersions(3);
    hTableDescriptor.addFamily(columnFamily2);
    //以配置的方式动态加载协处理器
    hTableDescriptor.setValue("COPROCESSOR$1", path + "|"
    + RegionObserverExample.class.getCanonicalName() + "|"
    + Coprocessor.PRIORITY_USER);
    admin.modifyTable(tableName, hTableDescriptor);
    admin.enableTable(tableName);
    
  • Java API的方式加载(只适用于hbase-0.96+ only)

    该版本只适用于hbase-0.96以及更新的版本,HTableDescriptor提供了更简单的APIaddCoprocessor()去动态加载协处理器。

    TableName tableName = TableName.valueOf("users");
    Path path = new Path("hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar");
    Configuration conf = HBaseConfiguration.create();
    Connection connection = ConnectionFactory.createConnection(conf);
    Admin admin = connection.getAdmin();
    //disable
    admin.disableTable(tableName);
    HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
    HColumnDescriptor columnFamily1 = new HColumnDescriptor("personalDet");
    columnFamily1.setMaxVersions(3);
    hTableDescriptor.addFamily(columnFamily1);
    HColumnDescriptor columnFamily2 = new HColumnDescriptor("salaryDet");
    columnFamily2.setMaxVersions(3);
    hTableDescriptor.addFamily(columnFamily2);
    //动态加载协处理器
    hTableDescriptor.addCoprocessor(RegionObserverExample.class.getCanonicalName(), path,
    Coprocessor.PRIORITY_USER, null);
    //修改
    admin.modifyTable(tableName, hTableDescriptor);
    //enable
    admin.enableTable(tableName);
    

    如何动态卸载协处理器:卸载动态加载的table coprocessor

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值