多语言支持(thrift)
1、 产品支持
Thrift 提供多语言访问HBase的能力,支持的语言包从Thrift官网看括: C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml , Delphi 以及别的语言。主要流程是用户thrift Client 通过Thrift协议访问HBase的thriftserver,thriftserver请求转发给HBase的存储服务.大概架构图如下:
注意:如果您使用的是HBase增强版集群,请参照增强版的多语言访问帮助文档
开通HBase thriftserver服务:
管控页面点击 开通thriftserver服务化(高可用版本thriftserver)
,会得到一个 host:port的访问入口;
2、使用说明
2.1 用户Thrift client访问:
一般客户常见的访问方式是python及php ,这里给出php的访问方式;
2.1.1 以php走thrift访问HBase:
我们云HBase的thrift环境是0.9.0,所以建议客户客户端的版本也为 0.9.0,可以从这里下载thrift的0.9.0 版本,下载的源码包我们后面会用到,这里需要先安装thrift编译环境,对于源码安装可以参考thrift官网;
通过如下命令可以看出安装thrift的版本信息;
thrift --version
2.1.2. 生成thrift访问client的访问文件;
我们从这里下载云HBase的Hbase.thrift文件,云HBase使用的是thrift1协议
编译命令如下:
thrift --gen <language> Hbase.thrift
上述 language 是语言的缩写,常见的有如下:
thrift --gen php Hbase.thrift
thrift --gen cpp Hbase.thrift
thrift --gen py Hbase.thrift
执行thrift —gen php Hbase.thrift ,在目录下得到gen-php ,这个是需要的函数包文件;
thrift git:(last_dev) ✗ ll
total 56
-rw-r--r-- 1 xuanling.gc staff 24K 3 5 15:06 Hbase.thrift
drwxr-xr-x 3 xuanling.gc staff 96B 8 1 16:03 gen-php
将下载到的Thrift源码文件夹下的/lib/php/lib下面的Thrift文件夹以及gen-php一起放在我们的业务逻辑代码一个src目录下面,加上我们自己的client.php的代码,目录结果如下所示:
[root@xxxxxxxxxxx thrift_client]# ll
total 12
-rw-r--r-- 1 zookeeper games 2743 Aug 2 11:16 client.php
drwxr-xr-x 3 zookeeper games 4096 Aug 2 01:22 gen-php
drwxr-xr-x 12 zookeeper games 4096 Aug 2 01:22 Thrift
php访问代码编写;
上述的Thrift文件夹以及gen-php文件夹,可以随自己项目以及个人风格命名,这里方便大家搞清目录结构,就保留原来风格;下面贴出php的代码,下面的程序是在HBase 建了一张表”new”:
<?php
ini_set('display_errors', E_ALL);
$GLOBALS['THRIFT_ROOT'] = "/root/thrift_client";
/* Dependencies. In the proper order. */
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Transport/TTransport.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Transport/TSocket.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Protocol/TProtocol.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Protocol/TBinaryProtocol.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Protocol/TBinaryProtocolAccelerated.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Transport/TBufferedTransport.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Type/TMessageType.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Factory/TStringFuncFactory.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/StringFunc/TStringFunc.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/StringFunc/Core.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Type/TType.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Exception/TException.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Exception/TTransportException.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift/Exception/TProtocolException.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/gen-php/Hbase/Types.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/gen-php/Hbase/Hbase.php';
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TBufferedTransport;
use Thrift\Transport\TSocket;
use Hbase\HbaseClient;
use Hbase\ColumnDescriptor;
use Hbase\Mutation;
$host='hb-bp12pt6alr1788y35-001.hbase.rds.aliyuncs.com';
$port=9099;
$socket = new TSocket($host, $port);
$socket->setSendTimeout(10000); // 发送超时,单位毫秒
$socket->setRecvTimeout(20000); // 接收超时,单位毫秒
$transport = new TBufferedTransport($socket);
$protocol = new TBinaryProtocol($transport);
$client = new HbaseClient($protocol);
$transport->open();
####列出表####
echo "----list tables----\n";
$tables = $client->getTableNames();
foreach ($tables as $name) {
var_dump($tables);
}
$tablename='new';
####写数据####
echo "----write data----\n";
$row = 'key';
$value = 'value';
$atrribute = array();
$mutations = array(
new Mutation(array(
'column' => 'info:cn1',
'value' => $value
)),
);
try {
$client->mutateRow($tablename, $row, $mutations, $atrribute);
} catch (Exception $e) {
var_dump($e);//这里自己打log
}
###读数据####
echo "---read data---\n";
$result = $client->getRow($tablename, $row, $atrribute);
var_dump($result);
###删数据####
echo "---delete data---\n";
$client->deleteAllRow($tablename, $row, $atrribute);
echo "---get data---\n";
$result = $client->getRow($tablename, $row, $atrribute);
var_dump($result);
###扫描数据###
$row = 'ID1';
$value = 'v1';
$mutations = array(
new Mutation(array(
'column' => 'info:c1',
'value' => $value
)),
);
try {
$client->mutateRow($tablename, $row, $mutations, $atrribute);
} catch (Exception $e) {
var_dump($e);
}
$row = 'ID2';
$value = 'v2';
$mutations = array(
new Mutation(array(
'column' => 'info:c1',
'value' => $value
)),
);
try {
$client->mutateRow($tablename, $row, $mutations, $atrribute);
} catch (Exception $e) {
var_dump($e);
}
$row = 'ID3';
$value = 'v3';
$mutations = array(
new Mutation(array(
'column' => 'info:c1',
'value' => $value
)),
);
try {
$client->mutateRow($tablename, $row, $mutations, $atrribute);
} catch (Exception $e) {
var_dump($e);
}
echo 'prefix scan';
$scan = $client->scannerOpenWithPrefix($tablename, 'ID', null, null);
$nbRows = 100;
$arr = $client->scannerGetList($scan, $nbRows);
echo 'count of result :'.count($arr)."\n";
var_dump($arr);
foreach ($arr as $k => $TRowResult) {
echo "\trow:$TRowResult->row\tcolumns(array):";
foreach ($TRowResult->columns as $key => $value) {
echo "key:$key\tvalue:$value->value\ttimestamp:$value->timestamp\n";
}
}
echo 'range scan';
$scan = $client->scannerOpenWithStop($tablename, 'ID0', 'ID2', null, null);
$nbRows = 100;
$arr = $client->scannerGetList($scan, $nbRows);
echo 'count of result :'.count($arr)."\n";
var_dump($arr);
foreach ($arr as $k => $TRowResult) {
echo "\trow:$TRowResult->row\tcolumns(array):";
foreach ($TRowResult->columns as $key => $value) {
echo "key:$key\tvalue:$value->value\ttimestamp:$value->timestamp\n";
}
}
###Increment 操作###
echo "do increment on a new row";
$row = 'ID4';
try {
$newCount = $client->atomicIncrement($tablename, $row, 'info:c1', 1234);
} catch (Exception $e) {
var_dump($e);
}
echo "new count $newCount\n";
###读写 long型数据到hbase###
$row = 'ID5';
$value = pack("J", 4567);
$mutations = array(
new Mutation(array(
'column' => 'info:c1',
'value' => $value
)),
);
try {
$client->mutateRow($tablename, $row, $mutations, null);
} catch (Exception $e) {
var_dump($e);
}
echo "---read data and print it as long ---\n";
$result = $client->getRow($tablename, $row, null);
foreach ($result[0]->columns as $key => $value) {
$count = unpack("J*mycount", $value->value);
var_dump($count);
}
?>
代码执行结果如下:
[root@xxxxxxxxxxx thrift_client]# php client.php
----list tables----
array(1) {
[0]=>
string(3) "new"
}
----write data----
---read data---
array(1) {
[0]=>
object(Hbase\TRowResult)#8 (3) {
["row"]=>
string(3) "key"
["columns"]=>
array(1) {
["info:cn1"]=>
object(Hbase\TCell)#10 (2) {
["value"]=>
string(5) "value"
["timestamp"]=>
int(1533179795969)
}
}
["sortedColumns"]=>
NULL
}
}
---delete data---
---get data---
array(0) {
}
2.2.python访问流程;
此外还有常见的python的客户,对于python的话,有happybase这种python的第三方包含thrift的库,我们见过一些客户使用Happybase进行访问HBase thrift,参见文章;此外,python 有丰富的库,我们通过pip可以安装thrift,以及访问HBase的thrift库;执行流程如下,假设用户已经安装python以及pip:
pip install thrift //安装thrift默认最新版本
pip install hbase-thrift //安装hbase thrift接口库
上面2步执行完成以后,既可以编写访问HBase的代码:
import sys
import time
import os
from thrift import Thrift
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol
from thrift.protocol.TBinaryProtocol import TBinaryProtocolAccelerated
from hbase import ttypes
from hbase.Hbase import Client, ColumnDescriptor, Mutation
def printRow(entry):
print "row: " + entry.row + ", cols:",
for k in sorted(entry.columns):
print k + " => " + entry.columns[k].value,
transport = TSocket.TSocket('hb-bp12pt6alr1788y35-001.hbase.rds.aliyuncs.com', 9099)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)
client = Client(protocol)
transport.open()
print "---list table--"
print client.getTableNames()
table="new"
row="key"
print "---write data---"
mutations = [Mutation(column="info:cn1", value="value")]
client.mutateRow(table, row, mutations)
print "---get data----"
printRow(client.getRow(table, row)[0])
print "---delete data---"
client.deleteAllRow(table, row)
print "---end----"
transport.close()
对应上述的程序执行的结果如下:
[root@Test ~]# python Hbase_client.py
---list table--
['new']
---write data---
---get data----
row: key, cols: info:cn1 => value
---delete data---
---end----
Go语言访问HBase
下载优化后的thrift访问压缩包(也可以从https://github.com/sdming/goh 下载原始版本),解压后放到$GOPATH/src下
wget http://public-hbase.oss-cn-hangzhou.aliyuncs.com/thrift/goh.tar.gz
tar -xvzf goh.tar.gz
mv github.com $GOPATH/src
示例代码请参考 $GOPATH/src/github.com/sdming/goh/demo/client.go 包含了DDL以及数据读写的代码示例
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
评论