thrift api 使用: PHP

上一篇文章中, 提及thrift server的建立與存取,
在這一篇文章中, 將介紹如何透過thrift存取hbase資料,
類似的內容, waue0920已經寫下詳細的紀錄,
因此, 我們將跟隨相同的架構, 並補充一些內容,

我們安裝的目錄結構為:
hadoop                     /opt/hadoop
hbase                        /opt/hbase
網頁根目錄             /var/www/
hbase的php目錄 /var/www/hbase
thrift php                  /var/www/hbase/thrift

測試程式之前,請先確定hbase , hadoop 都有正常運作中
$ bin/hbase thrift start 尚在執行

以下是這次範例程式(example.php)
<?php

$GLOBALS['THRIFT_ROOT'] = '/var/www/hbase/thrift';

require_once( $GLOBALS['THRIFT_ROOT'].'/Thrift.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/packages/Hbase/Hbase.php' );

$socket = new TSocket('192.168.2.14',9090);

$socket->setSendTimeout( 10000 ); // Ten seconds (too long for production, but this is just a demo ;)
$socket->setRecvTimeout( 20000 ); // Twenty seconds

$transport = new TBufferedTransport( $socket );
$protocol = new TBinaryProtocol( $transport );
$client = new HbaseClient( $protocol );
$transport->open();
$js_arr;

$table_name = 'UserTable';
$start_row = "";
//$family = array("[Column Name1]","[Column Name2]","[Column Name3]");
$family = array('RSSIFromAP','x','y');

$attributes = array();
$scanner = $client->scannerOpen($table_name,$start_row,$family,$attributes);

while(true)
{
    $get_arr = $client->scannerGet($scanner);
    if($get_arr == null)break;
    $name = null;
    $X_loc = null;
    $Y_loc = null;

    foreach($get_arr as $TRowResult)
    {
        $row = $TRowResult->row;
        $name = $row;
        $column = $TRowResult->columns;
        foreach($column as $k=>$v)
        {
            switch($k)
            {
            case "x:":
                $X_loc = $v->value;
                break;
            case "y:":
                $Y_loc = $v->value;
                break;
            default:
                break;
            }
        }
    }
    $tmp[] = array("User"=>$name,"Xlocation"=>$X_loc,"Ylocation"=>$Y_loc);
}
$json_str = json_encode($tmp);
echo "$json_str";

$client->scannerClose($scanner);
$transport->close();
?>



以下, 我們以example.php作為PHP讀取thrift的範例, 並說明部分內容,
在example.php中, 讀取hbase中一個名為UserTable的表格,
UserTable有以下4個欄位:  'x', 'y', 'associatedAP', 'RSSIFromAP'

在PHP的一開始, 先宣告hbase thrift的相關位置:

 $GLOBALS['THRIFT_ROOT'] = '/var/www/hbase/thrift';

 require_once( $GLOBALS['THRIFT_ROOT'].'/Thrift.php' );
 require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php' );
 require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php' );
 require_once( $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php' );
 require_once( $GLOBALS['THRIFT_ROOT'].'/packages/Hbase/Hbase.php' );

接著, 設定socket的變數,
注意, 此socket所指的就是象thrift通訊的連線,
因此我們填入thrift server的位址(192.168.144.14)以及thrift的通訊埠(9090),
以及通訊的timeout時間,

$socket = new TSocket('192.168.2.14',9090);

$socket->setSendTimeout( 10000 ); // Ten seconds (too long for production, but this is just a demo ;)
$socket->setRecvTimeout( 20000 ); // Twenty seconds

完成後, 開啟thrift socket,

$transport = new TBufferedTransport( $socket );
$protocol = new TBinaryProtocol( $transport );
$client = new HbaseClient( $protocol );
$transport->open();
$js_arr;

接著定義要存取的hbase table名稱,
以及要讀取的欄位(column family), 在這裡, 不必列出table所有的欄位,
只要讀取有興趣的部分就好了,

$table_name = 'UserTable';
$start_row = "";
//$family = array("[Column Name1]","[Column Name2]","[Column Name3]");
$family = array('RSSIFromAP','x','y');

開啟一個scanner, 讀取hbase table中的所有數值,

$attributes = array();
$scanner = $client->scannerOpen($table_name,$start_row,$family,$attributes);

使用一個WHILE迴圈讀取UserTable中的數值,
並根據所讀回的欄位數值, 決定存放至 $X_loc 或是 $Y_loc 變數,
在這裡, 如果所讀取的欄位不只包含column, 而有qualifier的數值,
則判斷的標準變成: case: "column:qualifier" 的格式,
關於qualifier的定義, 可以參考這裡, 簡單來說, 就想像成子欄位吧!

while(true)
{
    $get_arr = $client->scannerGet($scanner);
    if($get_arr == null)break;
    $name = null;
    $X_loc = null;
    $Y_loc = null;

    foreach($get_arr as $TRowResult)
    {
        $row = $TRowResult->row;
        $name = $row;
        $column = $TRowResult->columns;
        foreach($column as $k=>$v)
        {
            switch($k)
            {
            case "x:":
                $X_loc = $v->value;
                break;
            case "y:":
                $Y_loc = $v->value;
                break;
            default:
                break;
            }
        }
    }
    $tmp[] = array("User"=>$name,"Xlocation"=>$X_loc,"Ylocation"=>$Y_loc);
}

讀取完hbase的資料, 將結果compile成JSON的格式,
交給前方的HTML進行處理. 並且關閉scanner,

$json_str = json_encode($tmp);
echo "$json_str";

$client->scannerClose($scanner);
$transport->close();


在網業伺服器的環境中,
我們可以使用php的指令確定example.php的執行結果,
若是正確, 將會顯示compile完成的JSON檔案,
指令和結果如下:

$ php example.php
[{"User":"3C:E0:72:B6:29:B9","Xlocation":"-1.6371960645819712","Ylocation":"-0.6972200627495914"},{"User":"5C:FF:35:77:43:F4","Xlocation":"55.018162315153376","Ylocation":"38.813627069491766"},{"User":"B8:B4:2E:32:54:2D","Xlocation":"4.5085225496644235","Ylocation":"7.778994967910233"},{"User":"C4:43:8F:F3:EB:D6","Xlocation":"52.80050407884881","Ylocation":"23.093696604459726"},{"User":"DC:C7:93:DA:2B:7C","Xlocation":"9.865865062060452","Ylocation":"26.721484611594647"}]

在下一篇文章中, 我們將介紹如何透過HTML程式讀取PHP,
並且進一步獲得hbase中的資料,

留言

熱門文章

LTE筆記: RSRP, RSSI and RSRQ

[WiFi] WiFi 網路的識別: BSS, ESS, SSID, ESSID, BSSID

LTE筆記: 波束成型 (beamforming) 和天線陣列