hbase自定义比较器的开发

hbase查询时内置功能较弱,如果需要自定义查询,则需要开发自定义的比较器。

hbase自定义查询原理是将我们自定义的java比较器通过rpc方式传给hbase服务器来执行,所以涉及到比较器代码的序列化反序列化过程。hbase使用的是google的protocal buf这个工具。

步骤如下:

1 下载protocolbuffers windows版

https://github.com/protocolbuffers/protobuf/releases/tag/v3.6.1

下载后解压

2 将protoc.exe安装到本地到maven仓库

在命令行执行 mvn install:install-file -DgroupId=io.grpc -DartifactId=protoc-gen-grpc-java -Dversion=3.6.1 -Dclassifier=windows-x86_64 -Dpackaging=exe -Dfile=D:\dev\protoc-3.6.1-win32\bin\protoc.exe

3 在intelij idea开发工具中,配置proto的支持

 

方式2: 直接命令行执行:

protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/MyCompartor.proto

实际使用中发现,方式1虽然高级,但是maven package总有问题,protobuf生成的源代码在target目录下,src下的java无法引用,而且pom.xml需要配置的项目较多。

 

采用方式2生成更为便捷,直接将生成的代码输出到源码工程的src目录下即可。

 

4、根据生成的代码书写自己的比较器,需要重载方法:

compareTo:具体执行比较的逻辑
toByteArray:当前类的属性序列化为byte数组的方法
parseFrom:从byte数组反序列化得到当前类实例的方法


下面是我实现的比较器,作用是根据rowkey的子串进行范围匹配比较,子串的start,end位置可以配置。如果rowkey的某个(start,end)之间的子字符串的值在(rangeStart,rangeEnd)范围内则匹配成功。

/**
 * 子字符串比较器
 */
public class SubstringRangeComparable extends ByteArrayComparable {
    private int start, end;
    private String rangeStart;
    private String rangeEnd;


    /**
     * 
     * @param rangeStart 子字符串的最小值
     * @param rangeEnd 子字符串的最大值
     * @param start 子字符串在rowkey中的起始index
     * @param end 子字符串在rowkey中的结束index
     */
    public SubstringRangeComparable(String rangeStart, String rangeEnd, int start, int end) {
        super(Bytes.toBytes(rangeStart + "#" + rangeEnd + "#" + start + "#" + end));
        this.rangeStart = rangeStart;
        this.rangeEnd = rangeEnd;
        this.start = start;
        this.end = end;
    }

    @Override
    public byte[] getValue() {
        return Bytes.toBytes(rangeStart + "#" + rangeEnd + "#" + start + "#" + end);
    }

    @Override
    public int compareTo(byte[] value, int offset, int length) {
        String fullstr = Bytes.toString(value, offset, length);
        if (fullstr.length() < end) {
            return -1;
        }

        String substr = fullstr.substring(start, end);
        boolean inRange = substr.compareTo(rangeStart) >= 0 && substr.compareTo(rangeEnd) <= 0;
        return inRange ? 0 : 1;
    }

    @Override
    public byte[] toByteArray() {
        SubstringRangeProtos.SubstringRangeComparable.Builder builder =
                SubstringRangeProtos.SubstringRangeComparable.newBuilder();
        builder.setRangeStart(rangeStart);
        builder.setRangeEnd(rangeEnd);
        builder.setStart(start);
        builder.setEnd(end);
        return builder.build().toByteArray();
    }

    public static SubstringRangeComparable parseFrom(final byte[] pbBytes)
            throws DeserializationException {
        SubstringRangeProtos.SubstringRangeComparable proto;
        try {
            proto = SubstringRangeProtos.SubstringRangeComparable.parseFrom(pbBytes);
        } catch (InvalidProtocolBufferException e) {
            System.err.println("InvalidProtocolBufferException happened.");
            e.printStackTrace();
            throw new DeserializationException(e);
        }
        return new SubstringRangeComparable(proto.getRangeStart(), proto.getRangeEnd(), proto.getStart(), proto.getEnd());
    }

}
自定义比较器建议专门做个工程开发,完成后打包成jar,发布到hbase的 /lib目录下,重启hbase即可,否则运行时会提示ClassNotFoundException。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值