zoukankan      html  css  js  c++  java
  • HBase & thrift & C++编程

    目录

    目录 1

    1. 前言 1

    2. 启动和停止thrift2 1

    2.1. 启动thrift2 1

    2.2. 停止thrift2 1

    2.3. 启动参数 2

    3. hbase.thrift 2

    3.1. 编译hbase.thrift 2

    4. thrift_helper.h 3

    5. 示例代码 4

    1. 前言

    本文目的是介绍使用C++如何操作HBase。从HBase 0.94开始,HBase新增thrift2,本文只介绍和讨论thrift2相关的。hbase-1.1.2使用的thrift估计是thrift-0.9.0版本

    2. 启动和停止thrift2

    2.1. 启动thrift2

    登录HBase master机器,执行以下命令启动thrift2hbase-daemon.sh start thrift2。

    thrift默认的监听端口是9090,可以通过参数“-p”指定其它端口。默认使用的ServerTThreadPoolServer。默认使用的ProtocolTBinaryProtocol

    注意客户端使用的ProtocolTransport和服务端的要保持一致,否则客户端在调用时,可能遇到“EAGAIN (timed out)”等错误。

    2.2. 停止thrift2

    hbase-daemon.sh stop thrift2

    2.3. 启动参数

    使用“hbase-daemon.sh start thrift2”时,还可以带以下参数:

    参数名

    是否默认

    参数说明

    -h, --help

    显示帮助信息

    -b, --bind

    绑定指定地址,但不支持TNonblockingServerTHsHaServer,两者总是使用“0.0.0.0

    -p, --port

    9090

    绑室指定端口,默认为9090

    -f, --framed

    使用TFramedTransport

    -c, --compact

    使用TCompactProtocol,默认是TBinaryProtocol

    -threadpool

    使用TThreadPoolServer,为默认Server

    -nonblocking

    使用实现了FramedTransportTNonblockingServer

    -hsha

    使用实现了FramedTransportTHsHaServer

    客户端和hbase thrift2TransportProtocol保持一致,比如客户端为FramedTransport,则也需以“-f”启动hbase thrift2

    否则客户端在调用时,可能会遇到“EAGAIN (timed out)”等错误。

    启动参数信息来源于官网的页面:

    https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/thrift2/package-summary.html

    以上参数不是给hbase-daemon.sh使用,而是被hbase thrift2使用,可以浏览相关源代码了解细节:

    hbase-thriftsrcmainjavaorgapachehadoophbase hrift2ThriftServer.java

    hbase-thriftsrcmainjavaorgapachehadoophbase hrift2ThriftHBaseServiceHandler.java

    Ø 启动示例:

    hbase-daemon.sh start thrift2 --framed -nonblocking

    3. hbase.thrift

    hbaser.thrift文件在hbase源代码包(以hbase-1.1.2为例)中的位置:

    hbase-thriftsrcmain esourcesorgapachehadoophbase hrift2hbase.thrift

    3.1. 编译hbase.thrift

    保持机器上已安装好thrift(经测试hbase-1.1.2thrift-0.9.0兼容),然后使用下列命令编译:thrift --gen cpp -out . hbase.thrift,编译成功后,会在“-out”指定的目录下生成以下五个文件:

    THBaseService.h

    THBaseService.cpp

    hbase_types.h

    hbase_types.cpp

    hbase_constants.h

    hbase_constants.cpp

    其中供客户端使用的是位于文件THBaseService.h中的类THBaseServiceClient

    4. thrift_helper.h

    为了简化C++客户端的编程,可以使用thrift_helper.h

    https://github.com/eyjian/mooon/blob/master/common_library/include/mooon/net/thrift_helper.h,它可以帮助简化对HBase thrift2的调用:

    // thrift客户端辅助类

    //

    // 使用示例:

    // mooon::net::CThriftClientHelper<ExampleServiceClient> client(rpc_server_ip, rpc_server_port);

    // try

    // {

    //     client.connect();

    //     client->foo();

    // }

    // catch (apache::thrift::transport::TTransportException& ex)

    // {

    //     MYLOG_ERROR("thrift exception: (%d)%s ", ex.getType(), ex.what());

    // }

    // catch (apache::thrift::transport::TApplicationException& ex)

    // {

    //     MYLOG_ERROR("thrift exception: %s ", ex.what());

    // }

    // catch (apache::thrift::TException& ex)

    // {

    //     MYLOG_ERROR("thrift exception: %s ", ex.what());

    // }

    // Transport除默认的TFramedTransport (TBufferTransports.h),还可选择:

    // TBufferedTransport (TBufferTransports.h)

    // THttpTransport

    // TZlibTransport

    // TFDTransport (TSimpleFileTransport)

    //

    // Protocol除默认的apache::thrift::protocol::TBinaryProtocol,还可选择:

    // TCompactProtocol

    // TJSONProtocol

    // TDebugProtocol

    template <class ThriftClient,

              class Protocol=apache::thrift::protocol::TBinaryProtocol,

              class Transport=apache::thrift::transport::TFramedTransport>

    class CThriftClientHelper

    5. 示例代码

    // HBase thrift2 C++编程示例

    #include "THBaseService.h"

    #include <inttypes.h> // PRIu64

    #include <mooon/net/thrift_helper.h>

    #include <mooon/utils/args_parser.h>

    #include <vector>

    // 请注意客户端使用的thrift的Transport和Protocol要和hbase thrift2服务端保持一致,

    // 否则调用时,可能总是报超时,或其它错误!!!

    //

    // 运行之前,请通过HBase shell创建好表:create 'test','cf1','cf2'

    // 或指定版本数:create 'test',{NAME=>'cf1',VERSIONS=>2},{NAME=>'cf2',VERSIONS=>3}

    // 删除表,按顺序执行以下两条HBase shell命令:

    // disable 'test'

    // drop 'test'

    STRING_ARG_DEFINE(hbase_ip, "192.168.0.1", "hbase thrift ip");

    INTEGER_ARG_DEFINE(uint16_t, hbase_port, 9090, 1000, 50000, "hbase thrift port");

    int main(int argc, char* argv[])

    {

        std::string errmsg;

        if (!mooon::utils::parse_arguments(argc, argv, &errmsg))

        {

            fprintf(stderr, "parameter error: %s ", errmsg.c_str());

            exit(1);

        }

        using namespace apache;

        using namespace apache::hadoop;

        std::string hbase_ip = mooon::argument::hbase_ip->value();

        uint16_t hbase_port = mooon::argument::hbase_port->value();

        mooon::net::CThriftClientHelper<hbase::thrift2::THBaseServiceClient> hbase_client(hbase_ip, hbase_port);

        try

        {

            hbase_client.connect(); // 连接hbase thrift2 server

            fprintf(stdout, "connect %s:%d ok ", hbase_ip.c_str(), hbase_port);

            std::string tablename = "test";     // 表名,确保运行之前已创建好

            std::string rowkey = "row1";        // 行Key

            std::string family = "cf1";         // 例族名

            std::string columnname = "f1";      // 例名

            std::string columnvalue = "value1"; // 例值

            // 插入参数设置

            std::vector<hbase::thrift2::TColumnValue> columns_value(1);

            columns_value[0].__set_family(family);

            columns_value[0].__set_qualifier(columnname);

            columns_value[0].__set_value(columnvalue);

            hbase::thrift2::TPut put;

            put.__set_row(rowkey);

            put.__set_columnValues(columns_value);

            hbase_client->put(tablename, put); // 插入,出错抛异常hbase::thrift2::TIOError

            // 查询参数设置

            hbase::thrift2::TGet input;

            input.__set_row(rowkey);

            hbase::thrift2::TResult result; // 查询结果存放在这里

            hbase_client->get(result, tablename, input); // 查询,出错抛异常hbase::thrift2::TIOError

            // 显示查询结果

            for (int i=0; i<static_cast<int>(result.columnValues.size()); ++i)

            {

                const hbase::thrift2::TColumnValue& column_value_ref = result.columnValues[i];

                fprintf(stdout, "family[%s]/qualifier[%s]/timestamp[%"PRIu64"]: %s ", column_value_ref.family.c_str(),

                        column_value_ref.qualifier.c_str(),

                        column_value_ref.timestamp,

                        column_value_ref.value.c_str());

            }

        }

        catch (hbase::thrift2::TIOError& ex)

        {

            fprintf(stderr, "IOError: %s ", ex.what());

        }

        catch (apache::thrift::transport::TTransportException& ex)

        {

            // 如果和服务端的Transport和Protocol不同,这里的错误是“EAGAIN (timed out)”

            fprintf(stderr, "(%d)%s ", ex.getType(), ex.what());

        }

        catch (apache::thrift::TApplicationException& ex)

        {

            fprintf(stderr, "%s ", ex.what());

        }

        catch (thrift::TException& ex)

        {

            fprintf(stderr, "%s ", ex.what());

        }

        return 0;

    }

    如果thrift客户端报如下错误,有可能是因为一次写入的数据太多,导致包过大:

    Thrift: Fri Apr 22 17:30:41 2016 TSocket::write_partial() send() <Host: 10.143.136.208 Port: 9090>Connection reset by peer

    Thrift: Fri Apr 22 17:30:41 2016 TSocket::write_partial() send() <Host: 10.143.136.208 Port: 9090>Connection reset by peer

  • 相关阅读:
    什么是Service Mesh
    SQL Server 创建索引(index)
    RocketMQ在面试中那些常见问题及答案+汇总
    怎样用通俗的语言解释REST,以及RESTful?
    RPC和RestFul的区别是什么?
    Java 动态字节码生成技术 javassist
    热加载如此简单,手动写一个 Java 热加载
    Dubbo源码分析(十)同步调用与异步调用
    Dubbo源码分析(九)负载均衡算法
    Dubbo源码分析(八)集群容错机制
  • 原文地址:https://www.cnblogs.com/aquester/p/9891549.html
Copyright © 2011-2022 走看看