一:介紹
把一部分計(jì)算也移動(dòng)到數(shù)據(jù)的存放端;允許用戶(hù)執(zhí)行region級(jí)的操作;可以動(dòng)態(tài)加載。
二:使用場(chǎng)景:
1、使用鉤子來(lái)關(guān)聯(lián)行修改操作來(lái)維護(hù)輔助索引,或維護(hù)一些數(shù)據(jù)間的引用完整性。
2.權(quán)限控制
三:coprocessor兩大類(lèi):observer和endpoint介紹
3.1Observer
與觸發(fā)器類(lèi)似;
regionobserver處理數(shù)據(jù)修改事件,表region聯(lián)系緊密;
MasterObserver集群級(jí)事件操作,管理或DDL類(lèi)型操作;
WALObserver控制WAL。
3.2Endpoint
用戶(hù)自定義操作添加到服務(wù)端添加一些遠(yuǎn)程過(guò)程調(diào)用動(dòng)態(tài)拓展RPC協(xié)議;與RDBMS存儲(chǔ)類(lèi)似;
3.3Coprocessor類(lèi)
所有的協(xié)處理器都必須實(shí)現(xiàn)這個(gè)接口,定義了協(xié)處理器的基本約定。
兩個(gè)被應(yīng)用于框架的枚舉類(lèi):priority與state。
3.3.1Coprocessor.priority
定義的優(yōu)先級(jí)
SYSTEM 最先被執(zhí)行的協(xié)處理器;
USER 其他協(xié)處理器,按順序執(zhí)行;
3.3.2Coprocessor類(lèi)接口提供的方法:
void start(CoprocessorEnviroment env)throws IOException;
void stop(CoprocessorEnviroment env)throws IOException;
3.3.3CoprocessorEnviroment
(協(xié)處理器實(shí)例一直保存在提供的環(huán)境中)
3.3.4Coprocessor.state
定義的狀態(tài);
uninstalled:協(xié)處理器最初的狀態(tài)
installed:實(shí)例裝載了他的環(huán)境參數(shù)
starting:開(kāi)始工作
active:start方法調(diào)用,處于active狀態(tài)
stopping:stop方法被調(diào)用之前stopped:
stop方法將控制權(quán)交給框架
3.3.5CoprocessorHost類(lèi):
維護(hù)協(xié)處理實(shí)例和他們專(zhuān)用環(huán)境
Coprocessor,CoprocessorEnviroment,CoprocessorHost形成協(xié)處理器類(lèi)基礎(chǔ)。
四:協(xié)處理器的加載:
1.從配置文件中加載(hbase-site.xml)
2.表描述符中加載HTableDescriptor.setValue()
五:RegionObserver類(lèi)
region級(jí)別操作發(fā)生,會(huì)觸發(fā)鉤子函數(shù)
分為兩類(lèi)操作:region生命周期變化;客戶(hù)端api調(diào)用
5.1RegionCoprocessorEnviroment
RegionObserver類(lèi)的協(xié)處理器環(huán)境的實(shí)例;實(shí)現(xiàn)了CoprocessorEnviroment接口;
5.2ObserverContext類(lèi)
特殊的上下文:提供訪(fǎng)問(wèn)當(dāng)前系統(tǒng)環(huán)境入口;提供關(guān)鍵功能通知協(xié)處理器在毀掉函數(shù)完成時(shí)需要做什么;
5.3BaseRegionObserver類(lèi)
所有用戶(hù)實(shí)現(xiàn)監(jiān)聽(tīng)類(lèi)型協(xié)處理器基類(lèi),可以重載自己感興趣的方法實(shí)現(xiàn)自己功能
六:MasterObserver類(lèi)
處理master服務(wù)器的所有回調(diào)函數(shù)
6.1MasterCoprocessorEnviroment類(lèi)
封裝了一個(gè)masterobserver實(shí)例;實(shí)現(xiàn)了CoprocessorEnviroment接口;
6.2BaseMasterObserver類(lèi)
擴(kuò)展此類(lèi),實(shí)現(xiàn)自己功能;選擇對(duì)應(yīng)的pre.post方法;
七:endpoint:
hbase0.98之前:實(shí)現(xiàn)一個(gè)endpoint兩個(gè)步驟:
1.拓展CoprocessorProtocol接口
給客戶(hù)端提供自定義的rpc協(xié)議;
定義了客戶(hù)端服務(wù)端的通信協(xié)議
2.拓展BaseEndpointCoprocessor類(lèi)
hbase 0.98以上版本對(duì)endpoint的版本作了修改,修改后的使用:
(1)創(chuàng)建通信協(xié)議:
一個(gè)proto文件,使用protoc工具來(lái)生成協(xié)議類(lèi)文件。這個(gè)文件需要在服務(wù)端及客戶(hù)端存在。
proto文件:
option java_package = "org.myname.hbase.coprocessor.autogenerated";
option java_outer_classname = "Sum";
message SumRequest {
? required string family = 1;
}
message SumResponse {
? required int64 sum = 1 [default = 0];
}
service SumService {
? rpc getSum(SumRequest)
? ? ? returns (SumResponse);
}
生成協(xié)議類(lèi)文件:
$ protoc --java_out=src ./sum.proto
(2)創(chuàng)建一個(gè)Service類(lèi),實(shí)現(xiàn)具體的業(yè)務(wù)邏輯
例如官網(wǎng)例子:
public class SumEndPoint extends Sum.SumService implements Coprocessor, CoprocessorService {
@Override
public Service getService() {
? ? ? ? ? ? ? ? return this;
}
@Override
public void start(CoprocessorEnvironment env) throws IOException {
? ? ? ? ? ? ? ?if (env instanceof RegionCoprocessorEnvironment) {
? ? ? ? ? ? ? ? ? ? .................
}
@Override
public void stop(CoprocessorEnvironment env) throws IOException {
? ? ? ?// do nothing
}
@Override
public void getSum(RpcController controller, Sum.SumRequest request, RpcCallback done) {
? ? ? ? ? ? Scan scan = new Scan();
? ? ? ? ? ? .............
? ? ? ? ? try {
? ? ? ? ? ? ?............
}
(3)創(chuàng)建表時(shí)指定使用這個(gè)EndPoint,或者是全局配置。
(4)創(chuàng)建一個(gè)Client類(lèi),調(diào)用這個(gè)RPC方法。
例如:
try{
? ? ? ? ? Map results = table.coprocessorService(? ? ? ??
? ? ? ? ? ? ? ? ? ? Sum.SumService.class,
? ? ? ? ? ? ? ? ? ? ?null,?/* start key */?
? ? ? ? ? ? ? ? ? ? ? null,/* end? key */
? ? ? ? ? ? ? ? ? ? ? ?newBatch.Call() {
? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? ? publicLongcall(Sum.SumService aggregate)throwsIOException{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BlockingRpcCallback rpcCallback =newBlockingRpcCallback<>();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? aggregate.getSum(null, request, rpcCallback);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Sum.SumResponse response = rpcCallback.get();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? returnresponse.hasSum() ? response.getSum() :0L;?
? ? ? ? ?} ? ? ??
?}? ? );