Observer协处理器通常在一个特定的事件(诸如Get
或Put
)之前或之后发生,相当于RDBMS中的触发器。Endpoint协处理器则类似于RDBMS中的存储过程,因为它可以让你在RegionServer上对数据执行自定义计算,而不是在客户端上执行计算。
本文是以上两者的简单实例,使用的环境:环境 jdk1.8 hadoop2.6.5 hbase1.2.4。
1、Endpoint实例
1> 编写适用于protobuf的proto文件,如下,尽量不要带注释,因为编译时可能出现乱码
option java_package = "com.endpoint.test";
option java_outer_classname = "Sum";
option java_generic_services = true;
option java_generate_equals_and_hash = true;
option optimize_for = SPEED;
message SumRequest {
required string family = 1;
required string column = 2;
}
message SumResponse {
required int64 sum = 1 [default = 0];
}
service SumService {
rpc getSum(SumRequest)
returns (SumResponse);
}
2> 编译上面的proto文件
使用protoc程序进行编译,linux下或者windows均可,protoc程序可以直接从github下载:Releases · protocolbuffers/protobuf · GitHub,也可以自己编译生成,参见protobuf的编译安装
注意,编译的版本要与hadoop以及hbase使用的版本相同,或者略高,但最好不要过高,hadoop2.6.5 hbase1.2.4使用的都是protobuf2.5.0的版本,写此篇文章时的最新版为3.1.0
(高版本必须指定syntax,例如proto3的syntax在第一行非空白非注释行,必须写:syntax = "proto3",字段规则移除了 “required”,并把 “optional” 改名为 “singular”,移除了 default 选项。可搜索Protobuf 的 proto3 与 proto2 的区别进行了解。)下载的话选择带win或linux的版本,这是编译好的版本。有很多带具体语言的版本,是一些具体某种语言的发行版源码包。为了与hbase以及hadoop统一起来,此处用的是protoc-2.5.0-win32.zip。
解压文件:
使用windows命令行进入上面的目录,执行以下命令即可:
protoc.exe sum1.proto --java_out=./
高版本有编译好的适用于linux下的protoc程序文件,低版本没有。在linux下执行以下命令:
protoc sum.proto --java_out=./
结果都一样,生成的代码参见折叠部分,有很多,因为上面文件中指定java_outer_classname = "Sum",所以会生成Sum类,将这个类引入到项目中,注意项目的包名称与上面文件中指定(option java_package = "com.endpoint.test")的名称要一致。
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: sumcode.proto
package com.endpoint.test;
public final class Sum {
private Sum() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
}
public interface SumRequestOrBuilder
extends com.google.protobuf.MessageOrBuilder {
// required string family = 1;
/**
* <code>required string family = 1;</code>
*/
boolean hasFamily();
/**
* <code>required string family = 1;</code>
*/
java.lang.String getFamily();
/**
* <code>required string family = 1;</code>
*/
com.google.protobuf.ByteString
getFamilyBytes();
// required string column = 2;
/**
* <code>required string column = 2;</code>
*/
boolean hasColumn();
/**
* <code>required string column = 2;</code>
*/
java.lang.String getColumn();
/**
* <code>required string column = 2;</code>
*/
com.google.protobuf.ByteString
getColumnBytes();
}
/**
* Protobuf type {@code SumRequest}
*/
public static final class SumRequest extends
com.google.protobuf.GeneratedMessage
implements SumRequestOrBuilder {
// Use SumRequest.newBuilder() to construct.
private SumRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
super(builder);
this.unknownFields = builder.getUnknownFields();
}
private SumRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
private static final SumRequest defaultInstance;
public static SumRequest getDefaultInstance() {
return defaultInstance;
}
public SumRequest getDefaultInstanceForType() {
return defaultInstance;
}
private final com.google.protobuf.UnknownFieldSet unknownFields;
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private SumRequest(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
initFields();
int mutable_bitField0_ = 0;
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
default: {
if (!parseUnknownField(input, unknownFields,
extensionRegistry, tag)) {
done = true;
}
break;
}
case 10: {
bitField0_ |= 0x00000001;
family_ = input.readBytes();
break;
}
case 18: {
bitField0_ |= 0x00000002;
column_ = input.readBytes();
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e.getMessage()).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return com.endpoint.test.Sum.internal_static_SumRequest_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
return com.endpoint.test.Sum.internal_static_SumRequest_fieldAccessorTable
.ensureFieldAccessorsInitialized(
com.endpoint.test.Sum.SumRequest.class, com.endpoint.test.Sum.SumRequest.Builder.class);
}
public static com.google.protobuf.Parser<SumRequest> PARSER =
new com.google.protobuf.AbstractParser<SumRequest>() {
public SumRequest parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new SumRequest(input, extensionRegistry);
}
};
@java.lang.Override
public com.google.protobuf.Parser<SumRequest> getParserForType() {
return PARSER;
}
private int bitField0_;
// required string family = 1;
public static final int FAMILY_FIELD_NUMBER = 1;
private java.lang.Object family_;
/**
* <code>required string family = 1;</code>
*/
public boolean hasFamily() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>required string family = 1;</code>
*/
public java.lang.String getFamily() {
java.lang.Object ref = family_;
if (ref instanceof java.lang.String) {
return (java.lang.String) ref;
} else {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
family_ = s;
}
return s;
}
}
/**
* <code>required string family = 1;</code>
*/
public com.google.protobuf.ByteString
getFamilyBytes() {
java.lang.Object ref = family_;
if (ref instanceof java.lang.String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
family_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
// required string column = 2;
public static final int COLUMN_FIELD_NUMBER = 2;
private java.lang.Object column_;
/**
* <code>required string column = 2;</code>
*/
public boolean hasColumn() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>required string column = 2;</code>
*/
public java.lang.String getColumn() {
java.lang.Object ref = column_;
if (ref instanceof java.lang.String) {
return (java.lang.String) ref;
} else {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
column_ = s;
}
return s;
}
}
/**
* <code>required string column = 2;</code>
*/
public com.google.protobuf.ByteString
getColumnBytes() {
java.lang.Object ref = column_;
if (ref instanceof java.lang.String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
column_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
private void initFields() {
family_ = "";
column_ = "";
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized != -1) return isInitialized == 1;
if (!hasFamily()) {
memoizedIsInitialized = 0;
return false;
}
if (!hasColumn()) {
memoizedIsInitialized = 0;
return false;
}
memoizedIsInitialized = 1;
return true;
}
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeBytes(1, getFamilyBytes());
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeBytes(2, getColumnBytes());
}
getUnknownFields().writeTo(output);
}
private int memoizedSerializedSize = -1;
public int getSerializedSize() {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
if (((bitField0_ & 0x00000001) == 0x00000001)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(1, getFamilyBytes());
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(2, getColumnBytes());
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
}
private static final long serialVersionUID = 0L;
@java.lang.Override
protected java.lang.Object writeReplace()
throws java.io.ObjectStreamException {
return super.writeReplace();
}
@java.lang.Override
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof com.endpoint.test.Sum.SumRequest)) {
return super.equals(obj);
}
com.endpoint.test.Sum.SumRequest other = (com.endpoint.test.Sum.SumRequest) obj;
boolean result = true;
result = result && (hasFamily() == other.hasFamily());
if (hasFamily()) {
result = result && getFamily()
.equals(other.getFamily());
}
result = result && (hasColumn() == other.hasColumn());
if (hasColumn()) {
result = result && getColumn()
.equals(other.getColumn());
}
result = result &&
getUnknownFields().equals(other.getUnknownFields());
return result;
}
private int memoizedHashCode = 0;
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}