Endpoint Coprocessor 允許在 RegionServer 端部署自定義 RPC 服務,客戶端通過 coprocessorProxy 直接調用,實現「計算下推、數據不出節點」,大幅減少網絡傳輸與客戶端聚合開銷。典型場景:行計數、聚合統計、二級索引維護、分布式鎖。
package ict.wde.test;
import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.ipc.CoprocessorProtocol;
import org.apache.hadoop.hbase.filter.Filter;
import java.io.IOException;
public interface RowCountProtocol extends Coprocessor, CoprocessorProtocol {
long getRowCount() throws IOException;
long getRowCount(Filter filter) throws IOException;
String getStr() throws IOException;
}
public class RowCountServer implements RowCountProtocol {
@Override
public void start(CoprocessorEnvironment env) throws IOException { }
@Override
public void stop(CoprocessorEnvironment env) throws IOException { }
@Override
public ProtocolSignature getProtocolSignature(String protocol, long clientVersion, int clientMethodsHash) {
return new ProtocolSignature(3, null); // 版本 3
}
@Override
public long getProtocolVersion(String protocol, long clientVersion) {
return 3;
}
@Override
public long getRowCount() throws IOException {
return getRowCount(new FirstKeyOnlyFilter()); // 只掃描第一個 KeyValue,極致性能
}
@Override
public long getRowCount(Filter filter) throws IOException {
Scan scan = new Scan();
scan.setMaxVersions(1);
if (filter != null) scan.setFilter(filter);
// 實際掃描邏輯:RegionScanner 遍歷統計
return 1; // 示例簡化
}
@Override
public String getStr() throws IOException {
return "Hello Doctor Michael Zhang, again!";
}
}
$HBASE_HOME/lib/。hbase.coprocessor.abortonerror=false 且版本支持)。static {
HTableDescriptor desc = new HTableDescriptor("epTest");
HColumnDescriptor family = new HColumnDescriptor("_tis".getBytes());
family.setInMemory(true);
family.setMaxVersions(1);
desc.addFamily(family);
desc.addCoprocessor("ict.wde.test.RowCountServer"); // 全限定類名
}
Configuration conf = new Configuration();
conf.set("hbase.zookeeper.quorum", "ccf04:2181");
HTable table = new HTable(conf, "epTest");
// 獲取代理對象,按行鍵路由到目標 Region
RowCountProtocol proxy = table.coprocessorProxy(RowCountProtocol.class, "0".getBytes());
// 遠程調用
String result = proxy.getStr();
long count = proxy.getRowCount();
| 現象 | 原因 | 解決 |
|---|---|---|
No matching handler for protocol | JAR 未加載、類名錯誤、未重啟 HBase | 重啟 HBase、驗證 JAR 路徑、核對 addCoprocessor 類名 |
| 代理調用超時 | RegionServer 端邏輯耗時過長、死鎖 | 邏輯異步化、設置 rpc.timeout、避免全表掃描 |
| 序列化異常 | 返回對象未實現 Writable、含非序列化字段 | 返回基本類型/String/自定義 Writable,避免 POJO |
| 版本不匹配 | 客戶端/服務端協議版本號不一致 | 雙端 getProtocolVersion 返回相同版本號 |
FirstKeyOnlyFilter、ColumnPaginationFilter、限制 setMaxVersions(1)、僅選擇所需列族。hbase.regionserver.handler.count 配合業務隔離隊列。lib/ 且版本一致addCoprocessor 類名準確Coprocessor + CoprocessorProtocolEndpoint Coprocessor 是 HBase 服務端編程的核心能力,善用「計算下推」思想,能讓 HBase 從純存儲進化為具備輕量計算能力的分布式數據平台。