天天看點

手把手教你通過Thrift 通路ApsaraDB for HBase

Thrift 多語言接入

​ 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的存儲服務來做資料的讀以及寫操作.大概架構圖如下:

手把手教你通過Thrift 通路ApsaraDB for HBase

​ 要通過thrift 多語言通路HBase需要以下幾步:

一、開通HBase thriftserver服務:

​ 在使用者自己管控頁面點選這裡參考開通thriftserver服務化(高可用版本thriftserver),會得到一個host:port的通路入口;或者自己可以選擇ECS自建thriftserver方法,參考

這裡

,最終自建ECS的ip (host)以及預設的話9090端口作為通路入口。

手把手教你通過Thrift 通路ApsaraDB for HBase
二、使用者Thrift client通路:

​ 一般客戶常見的通路方式是python的通路方式以及php的通路方式 ,這裡我們先一步步給出php的通路方式;

2.1 . 以php走thrift通路HBase:

​ 2.1.1 . 安裝thrift 編譯環境;

​ 我們雲HBase的thrift環境是0.9.0,是以建議客戶自己建立自己的thrift環境也是0.9.0,這裡可以從

下載下傳thrift的0.9.0 版本,下載下傳的源碼包我們後面會用到,這裡需要先安裝thrift編譯環境,對于源碼安裝可以參考

thrift官網

通過如下指令可以看出安裝thrift的版本資訊;

thrift --version           

​ 2.1.2. 生成thrift通路client的通路檔案;

​ 我們從

下載下傳出我們雲HBase的Hbase.thrift檔案,這裡我們雲HBase使用的是thrift1協定,具體可以參考檔案看出使用格式,下載下傳完成以後執行thrift指令進行編譯;

​ 編譯指令如下:

thrift --gen <language> Hbase.thrift            

​ 上述是語言的縮寫,那麼常見的有如下:

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           

​ 此外我們在2.1.1得到thrift的源碼封包件将下載下傳到的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           

​ 2.1.3. php通路代碼編寫;

​ 這個時候,我們來編寫我們的client.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);
?>           

​ 代碼執行結果如下:

[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 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,
  print


transport = TSocket.TSocket('hb-bp12pt6alr1788y35-001.hbase.rds.aliyuncs.com', 9099)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(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----           
三、通路HBase thriftserver

​ 3.1、通路機器開通白名單

​ 将通路的機器的ip加入HBase叢集的白名單,然後就可以正常執行代碼;

手把手教你通過Thrift 通路ApsaraDB for HBase