hbase协处理器endpoint示例(求最值)


hbase协处理器endpoint示例(求最值)


废话不多说,hbase原理等知识点网上太多了,也可以参考官网,在这里笔者就不过多赘述了,以下是经笔者测试的一个案例:

create 'test2', 'f1'

向f1加入字段 PBRL

1. 创建一个count_max.proto的文件,添加如下内容:

syntax = "proto2";
option java_package = "com.endpoint.test.max";
option java_outer_classname = "maxProtocol";
option java_generic_services = true;
option java_generate_equals_and_hash = true;
option optimize_for = SPEED;

message maxRequest {
    required string family = 1;
    required string column = 2;
}
message maxResponse {
    required double max = 1 [default = 0];
   
}
service maxService {
  rpc getmax(maxRequest)
    returns (maxResponse);
}

`
2. 使用protoc生成类文件:
cmd进入proto文件的目录下,执行如下命令

protoc --java_out=./ count_max.proto

命令执行完成后会在当前目录下生产一个名称为maxProtocol的类,将这个类复制到项目的com.endpoint.test.max包下,这些是需要注意的地方:

  • maxRequest 内部类,表示请求信息
  • maxResponse 内部类,表示返回信息
  • maxService 内部类,表示所提供的服务,这个类还有一个内部接口,这个接口定义了 getmax()这个方法

3. 服务端代码

package com.endpoint.test.max;

import com.google.protobuf.RpcCallback;
import com.google.protobuf.RpcController;
import com.google.protobuf.Service;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.coprocessor.CoprocessorException;
import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.protobuf.ResponseConverter;
import org.apache.hadoop.hbase.regionserver.InternalScanner;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MaxServer extends maxProtocol.maxService implements Coprocessor,CoprocessorService{

    private RegionCoprocessorEnvironment env;   // 定义环境

    @Override
    public void getmax(RpcController controller, maxProtocol.maxRequest request, RpcCallback<maxProtocol.maxResponse> done) {
        String family = request.getFamily();
        if (null == family || "".equals(family)) {
            throw new NullPointerException("you need specify the family");
        }
        String column = request.getColumn();
        if (null == column || "".equals(column))
            throw new NullPointerException("you need specify the column");


        Scan scan = new Scan();

        // 设置扫描对象
        scan.addColumn(Bytes.toBytes(family), Bytes.toBytes(column));


        // 定义变量
        maxProtocol.maxResponse response = null;
        InternalScanner scanner = null;

        // 扫描每个region,取值后求和
        try {
            scanner = env.getRegion().getScanner(scan);
            List<Cell> results = new ArrayList<Cell>();
            boolean hasMore = false;
            Double max = null;
            do {
                hasMore = scanner.next(results);
                //for (Cell cell : results) {
                if (results.isEmpty()) {
                    continue;
                }
                Cell kv = results.get(0);
                try {
                    Double temp = Double.parseDouble(new String(CellUtil.cloneValue(kv)));
                    max = max != null && (temp == null || compare(temp, max) <= 0) ? max : temp;
                } catch (Exception e) {
                }


                results.clear();
                //sum += Long.parseLong(new String(CellUtil.cloneValue(cell)));

                //results.clear();
            } while (hasMore);
            // 设置返回结果
            response = maxProtocol.maxResponse.newBuilder().setMax((max!=null?max.doubleValue():Double.MAX_VALUE)).build();
        } catch (IOException e) {
            ResponseConverter.setControllerException(controller, e);
        } finally {
            if (scanner != null) {
                try {
                    scanner.close();
                } catch (IOException e) {
                    //e.printStackTrace();
                }
            }
        }
        // 将rpc结果返回给客户端
        done.run(response);

    }



    public static int compare(Double l1, Double l2) {
        if (l1 == null ^ l2 == null) {
            return l1 == null ? -1 : 1; // either of one is null.
        } else if (l1 == null)
            return 0; // both are null
        return l1.compareTo(l2); // natural ordering.
    }
    @Override
    public Service getService() {

        return this;
    }

    @Override
    public void start(CoprocessorEnvironment env) throws IOException {
        if (env instanceof RegionCoprocessorEnvironment) {
            this.env = (RegionCoprocessorEnvironment)env;
        } else {
            throw new CoprocessorException("no load region");
        }

    }

    @Override
    public void stop(CoprocessorEnvironment env) throws IOException {

    }

    /**
     * <code>rpc getmax(.maxRequest) returns (.maxResponse);</code>
     *
     * @param controller
     * @param request
     * @param done
     */

}

4. 动态部署coprocessor

进入hbase shell :

  • disable ‘test2’

  • alter ‘test2’, METHOD => ‘table_att’, ‘Coprocessor’=>‘hdfs://linux5:8020/tmp/coprosessor/CoprosessorServer-1.0-SNAPSHOT1.jar|com.endpoint.test.max.MinServer|’

  • enable ‘test2’

  • 卸载协处理器:

alter 'test2', METHOD => 'table_att_unset', NAME => 'coprocessor$1'

5. Client端代码

在idea中操作即可运行

package com.endpoint.test.max;


import com.endpoint.test.max.maxProtocol;
import com.google.protobuf.ServiceException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.Map;

public class maxClient {

   //设置参数
    private static final String TABLE_NAME = "test2";
    private static final String FAMILY = "f1";
    private static final String COLUMN = "PBRL";
    private static final byte[] STRAT_KEY = Bytes.toBytes("000");
    private static final byte[] END_KEY = Bytes.toBytes("100");

    public static void main(String[] args) throws Exception {



        // 配置HBse
        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", "linux3,linux4,linux5");
        conf.set("hbase.zookeeper.property.clientPort", "2181");
        conf.setLong("hbase.rpc.timeout", 600000);
        System.setProperty("hadoop.home.dir", "F:/ruanjian/hadoop-2.6.0-cdh5.14.0");

        // 建立一个连接
        Connection conn = ConnectionFactory.createConnection(conf);
        // 获取表
        HTable table = (HTable) conn.getTable(TableName.valueOf(TABLE_NAME));


        // 设置请求对象
        final maxProtocol.maxRequest request = maxProtocol.maxRequest.newBuilder().setFamily(FAMILY).setColumn(COLUMN).build();

        try {
            // 获得返回值
            Map<byte[], Double> result = table.coprocessorService(maxProtocol.maxService.class, STRAT_KEY,  END_KEY,
                    new Batch.Call<maxProtocol.maxService, Double>() {

                        @Override
                        public Double call(maxProtocol.maxService maxService) throws IOException {
                            BlockingRpcCallback<maxProtocol.maxResponse> rpcCallback = new BlockingRpcCallback<maxProtocol.maxResponse>();
                            maxService.getmax(null, request, rpcCallback);
                            maxProtocol.maxResponse response = rpcCallback.get();
                            return response.getMax();
                        }


                    });
            Double max = null;
            // 将返回值进行迭代相加
            for (Double temp : result.values()) {
                max = max != null && (temp == null || compare(temp, max) <= 0) ? max : temp;
            }
            // 结果输出
            System.out.println("max: " + max);

        } catch (ServiceException e) {
            e.printStackTrace();
        }catch (Throwable e) {
            e.printStackTrace();
        }
        table.close();
        conn.close();

    }

    public static int compare(Double l1, Double l2) {
        if (l1 == null ^ l2 == null) {
            return l1 == null ? -1 : 1; // either of one is null.
        } else if (l1 == null)
            return 0; // both are null
        return l1.compareTo(l2); // natural ordering.
    }

}

github代码参考:https://github.com/kaiqid/CoprosessorServer/tree/master/src/main/java/com/endpoint/test/max
https://github.com/kaiqid/CoprocessorClient/tree/master/src/main/java/com/endpoint/test/max
里面有maxProtocol类

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值