Coprocessor 主要有两大功能点
一、Observer ,有点象拦截器或spring中的通知等,直白的描述就是在一个函数do() 执行前加predo()执行后加 postdo()
通过下面序列图我们看一下Observer怎么和其它组件一起工作的
二、Endpoint,最容易理解的就是当我们要在做count的时候,我们需要将所有计算count的值都返回,然后在客户端再循环做count,但是这样有一个小缺陷就是数据量很大的情况下网络io占用大,这时我们就需要在服务端写一个类然后在这个类中写好具体实现,客户端就直接调用就行了。
上面的两种情况实现的都是Coprocessor ,此类中有两个方法start(CoprocessorEnvironment env) 和 stop(CoprocessorEnvironment env),下面我们先看一下coprocessor的实现。
通过上面的图我们知道大类是endpoint 和 oberver ,observer又分为 master 、 regionserver 、 region 和wal
其中 regionserver 和 wal最简单
regionserver就一个方法preStopRegionServer 就是关闭regionserver之前的拦截操作
wal中有两个方法一个是preWALWrite 一个是postWALWrite 即对日志写之前之后的操作
正对上面的介绍我们知道了它的大体框架,如果我们想要实现自己的Coprocessor ,可以集成下面这三个类
然后在里面实现自己的逻辑。
下面是一个扩展RegionObserver接口的例子,它演示增加一个简单的控制功能,该coprocessor 通过在prexxx方法里植入代码检查给定用户的权限,如果用户不允许则抛出访问异常,访问异常意味着该客户请求将不被处理,客户端将收到异常提示。
package org.apache.hadoop.hbase.coprocessor;
import java.util.List;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Get;
// Sample access-control coprocessor. It utilizes RegionObserver
// and intercept preXXX() method to check user privilege for the given table
// and column family.
public class AccessControlCoprocessor extends BaseRegionObserver {
@Override
public void preGet(final ObserverContext<RegionCoprocessorEnvironment> c,
final Get get, final List<KeyValue> result) throws IOException
throws IOException {
// check permissions..
if (!permissionGranted()) {
throw new AccessDeniedException("User is not allowed to access.");
}
}
// override prePut(), preDelete(), etc.
}
通过上面我们可以扩展自己的Observe ,接下来讲一下扩展Endpoint
Endpoint 有点像数据库的存储过程,可以在任何时候被客户端触发,Endpoint实现将在远程的region上执行,并将结果返回给客户端。
Endpoint 是动态RPC的一个扩展,endpoint的实现被安装在服务端,通过hbase RPC调用,客户端类提供方便的执行方法,所以如果想扩展Endpoint需要以下工作:
1、定义一个继承CoprocessorProtocol的新接口并被实现
2、实现Endpoint接口,该实现将在region context中被加载并执行
3、继承抽象类BaseEndpointCoprocessor
4、在客户端,Endpoint 可以通过两种方式被调用
在单region上执行:
-
HTableInterface.coprocessorProxy(Class<T> protocol, byte[] row)
在多个region上执行
-
HTableInterface.coprocessorExec(Class<T> protocol, byte[] startKey, byte[] endKey, Batch.Call<T,R> callable)
示例:
class AggregateImplementation extends BaseEndpointCoprocessor implements AggregateProtocol
部署Coprocessor主要分为两种情况
1、从配置文件中加载
当一个region被打开的时候尝试去读取coprocessor关联类
- hbase.coprocessor.region.classes: for RegionObservers and Endpoints
- hbase.coprocessor.master.classes: for MasterObservers
- hbase.coprocessor.wal.classes: for WALObservers
Hers is an example of the hbase-site.xml where one RegionObserver is configured for all the HBase tables:
<property>
<name>hbase.coprocessor.region.classes</name>
<value>org.apache.hadoop.hbase.coprocessor.AggregateImplementation</value>
</property>
如果多个类的话用逗号分隔,包含该类的jar包必须放到服务端的Hbase classpath中,也就是可能需要配置hbase env 中的 classpath
2、从表配置中加载
从表配置加载主要针对该表、而上面的形式是针对多表全局的设置
hbase(main):005:0> alter 't1', METHOD => 'table_att',
'coprocessor'=>'hdfs:///foo.jar|com.foo.FooRegionObserver|1001|arg1=1,arg2=2'
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 1.0730 seconds
hbase(main):006:0> describe 't1'
DESCRIPTION ENABLED
{NAME => 't1', coprocessor$1 => 'hdfs:///foo.jar|com.foo.FooRegio false
nObserver|1001|arg1=1,arg2=2', FAMILIES => [{NAME => 'c1', DATA_B
LOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE
=> '0', VERSIONS => '3', COMPRESSION => 'NONE', MIN_VERSIONS =>
'0', TTL => '2147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZ
E => '65536', IN_MEMORY => 'false', ENCODE_ON_DISK => 'true', BLO
CKCACHE => 'true'}, {NAME => 'f1', DATA_BLOCK_ENCODING => 'NONE',
BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '3'
, COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647'
, KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY
=> 'false', ENCODE_ON_DISK => 'true', BLOCKCACHE => 'true'}]}
1 row(s) in 0.0190 seconds
coprocessor 主要有四个值分别用“|”分隔开
1、文件路径
2、类名
3、优先级
4、传给该coprocessor的变量
通过命令查看Coprocessor Status
hbase(main):018:0> alter 't1', METHOD => 'table_att',
'coprocessor'=>'|org.apache.hadoop.hbase.coprocessor.AggregateImplementation|1001|arg1=1,arg2=2'
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 1.1060 seconds
hbase(main):019:0> enable 't1'
0 row(s) in 2.0620 seconds
hbase(main):020:0> status 'detailed'
version 0.92-tm-6
0 regionsInTransition
master coprocessors: []
1 live servers
localhost:52761 1328082515520
requestsPerSecond=3, numberOfOnlineRegions=3, usedHeapMB=32, maxHeapMB=995
-ROOT-,,0
numberOfStores=1, numberOfStorefiles=1, storefileUncompressedSizeMB=0, storefileSizeMB=0, memstoreSizeMB=0,
storefileIndexSizeMB=0, readRequestsCount=54, writeRequestsCount=1, rootIndexSizeKB=0, totalStaticIndexSizeKB=0,
totalStaticBloomSizeKB=0, totalCompactingKVs=0, currentCompactedKVs=0, compactionProgressPct=NaN, coprocessors=[]
.META.,,1
numberOfStores=1, numberOfStorefiles=0, storefileUncompressedSizeMB=0, storefileSizeMB=0, memstoreSizeMB=0,
storefileIndexSizeMB=0, readRequestsCount=97, writeRequestsCount=4, rootIndexSizeKB=0, totalStaticIndexSizeKB=0,
totalStaticBloomSizeKB=0, totalCompactingKVs=0, currentCompactedKVs=0, compactionProgressPct=NaN, coprocessors=[]
t1,,1328082575190.c0491168a27620ffe653ec6c04c9b4d1.
numberOfStores=2, numberOfStorefiles=1, storefileUncompressedSizeMB=0, storefileSizeMB=0, memstoreSizeMB=0,
storefileIndexSizeMB=0, readRequestsCount=0, writeRequestsCount=0, rootIndexSizeKB=0, totalStaticIndexSizeKB=0,
totalStaticBloomSizeKB=0, totalCompactingKVs=0, currentCompactedKVs=0, compactionProgressPct=NaN,
coprocessors=[AggregateImplementation]
0 dead servers
如果没有发现红色字体部分则说明存在某些错误。