HBase & thrift & C++编程

简介: HBase & thrift & C++编程.pdf 目录 目录 1 1. 前言 1 2. 启动和停止thrift2 1 2.


img_e25d4fb2f8de1caf41a735ec53088516.pngHBase & thrift & C++编程.pdf

目录

目录 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-thrift\src\main\java\org\apache\hadoop\hbase\thrift2\ThriftServer.java

hbase-thrift\src\main\java\org\apache\hadoop\hbase\thrift2\ThriftHBaseServiceHandler.java


? 启动示例:

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

3. hbase.thrift

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

hbase-thrift\src\main\resources\org\apache\hadoop\hbase\thrift2\hbase.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 client(rpc_server_ip, rpc_server_port);

// try

// {

//     client.connect();

//     client->foo();

// }

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

// {

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

// }

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

// {

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

// }

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

// {

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

// }

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

// TBufferedTransport (TBufferTransports.h)

// THttpTransport

// TZlibTransport

// TFDTransport (TSimpleFileTransport)

//

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

// TCompactProtocol

// TJSONProtocol

// TDebugProtocol

template   thriftclient,

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

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

class CThriftClientHelper

5. 示例代码

// HBase thrift2 C++编程示例

#include "THBaseService.h"

#include  // PRIu64

#include 

#include 

#include 

 

// 请注意客户端使用的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\n", 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_client(hbase_ip, hbase_port);

 

    try

    {

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

        fprintf(stdout, "connect %s:%d ok\n", 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 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

        {

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

            fprintf(stdout, "family[%s]/qualifier[%s]/timestamp[%"PRIu64"]: %s\n", 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\n", ex.what());

    }

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

    {

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

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

    }

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

    {

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

    }

    catch (thrift::TException& ex)

    {

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

    }

 

    return 0;

}


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

Thrift: Fri Apr 22 17:30:41 2016 TSocket::write_partial() send() Connection reset by peer

Thrift: Fri Apr 22 17:30:41 2016 TSocket::write_partial() send() Connection reset by peer


相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
10天前
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
119 60
|
19天前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
34 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
5天前
|
安全 程序员 编译器
【实战经验】17个C++编程常见错误及其解决方案
想必不少程序员都有类似的经历:辛苦敲完项目代码,内心满是对作品品质的自信,然而当静态扫描工具登场时,却揭示出诸多隐藏的警告问题。为了让自己的编程之路更加顺畅,也为了持续精进技艺,我想借此机会汇总分享那些常被我们无意间忽视却又导致警告的编程小细节,以此作为对未来的自我警示和提升。
|
19天前
|
安全 程序员 编译器
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
70 11
|
19天前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
41 5
|
17天前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
29 0
C++入门6——模板(泛型编程、函数模板、类模板)
|
19天前
|
算法 编译器 C++
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
63 2
|
19天前
|
存储 编译器 C++
【C++篇】引领C++模板初体验:泛型编程的力量与妙用
【C++篇】引领C++模板初体验:泛型编程的力量与妙用
30 2
|
24天前
|
程序员 C++
C++编程:While与For循环的流程控制全解析
总结而言,`while`循环和 `for`循环各有千秋,它们在C++编程中扮演着重要的角色。选择哪一种循环结构应根据具体的应用场景、循环逻辑的复杂性以及个人的编程风格偏好来决定。理解这些循环结构的内在机制和它们之间的差异,对于编写高效、易于维护的代码至关重要。
29 1
|
19天前
|
自然语言处理 编译器 Linux
【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器
【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器