項目要求實現php讀寫hbase,調查發現中間件爲thrift,參考了文章http://www.cnblogs.com/scotoma/archive/2013/05/16/3081236.html,老實講幫助很大,總算按時完成了這些任務。
本地安裝了php和hbase,網上很多教程安裝thrift,安裝後將thrift目錄下./lib/php目錄複製到web目錄下,我的web目錄是/usr/local/apache2/htdocs,接着生成thrift和hbase的接口文件,這裏產生了很大的誤區,開始參考以爲Hbase.thrift是通過命令生成的文件,走了很多彎路。後面其實是--gen命令利用Hbase.thrift生成目錄文件,具體可以參考到官方網站上https://thrift.apache.org/tutorial/php,這也給我提了很大的醒,還是要多關注官方網站的寫法。這次虛擬機是直接拷貝的別人,裏面沒有Hbase.thrift文件,思考之後因爲hbase安裝使用的是二進制安裝,最後在hbase源碼裏找到了Hbase.thrift文件。
thrift -r --gen php Hbase.thrift
生成的Hbase目錄文件裏會有Hbase.php和Types.php文件,後面會用到。
查看都hbase啓動成功,便開始了代碼測試,路徑都要每一個對準,檢查每一個class文件是否對應成功。
<?php
use Thrift\Transport\TSocket;
use Thrift\Transport\TSocketPool;
use Thrift\Transport\TFramedTransport;
use Thrift\Transport\TBufferedTransport;
use Thrift\Protocol\TBinaryProtocol;
use HBase\HBaseClient;
ini_set('display_errors', E_ALL);
$GLOBALS['THRIFT_ROOT'] = './php/src/Thrift';
require_once( $GLOBALS['THRIFT_ROOT'] . '/Thrift.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/transport/TSocket.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/transport/TTransport.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/transport/TBufferedTransport.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/protocol/TProtocol.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/protocol/TBinaryProtocol.php' );
//require_once( $GLOBALS['THRIFT_ROOT'] . '/packages/Hbase/Hbase.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/Type/TMessageType.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/Factory/TStringFuncFactory.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/StringFunc/TStringFunc.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/StringFunc/Core.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/Type/TType.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/Exception/TException.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/Exception/TTransportException.php' );
require_once( $GLOBALS['THRIFT_ROOT'] . '/Exception/TProtocolException.php' );
require_once $GLOBALS['THRIFT_ROOT'].'/Types.php';
require_once $GLOBALS['THRIFT_ROOT'].'/Hbase.php';
$socket = new TSocket('localhost', '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();
echo nl2br( "listing tables...\n" );
$tables = $client->getTableNames();
sort($tables);
foreach ($tables as $name) {
echo( " found: {$name}\n" );
}
$columns = array(
new \Hbase\ColumnDescriptor(array(
'name' => 'id:',
'maxVersions' => 10
)),
new \Hbase\ColumnDescriptor(array(
'name' => 'name:'
)),
new \Hbase\ColumnDescriptor(array(
'name' => 'score:'
)),
);
$tableName = "student";
/*
try {
$client->createTable($tableName, $columns);
} catch (AlreadyExists $ae) {
echo( "WARN: {$ae->message}\n" );
}
*/
$descriptors = $client->getColumnDescriptors($tableName);
asort($descriptors);
foreach ($descriptors as $col) {
echo( " column: {$col->name}, maxVer: {$col->maxVersions}\n" );
}
$time = time();
var_dump($time);
$row = '2';
$valid = "foobar-".$time;
$mutations = array(
new \Hbase\Mutation(array(
'column' => 'score',
'value' => $valid
)),
);
$mutations1 = array(
new \Hbase\Mutation(array(
'column' => 'score:a',
'value' => $time,
)),
);
$attributes = array (
);
$row1 = $time;
$client->mutateRow($tableName, $row1, $mutations1, $attributes);
echo "-------write row $row1 ---\r\n";
$client->mutateRow($tableName, $row, $mutations, $attributes);
$row_name = $time;
$fam_col_name = 'score:a';
$arr = $client->get($tableName, $row_name, $fam_col_name, $attributes);
foreach ($arr as $k => $v) {
// $k = TCell
echo " ------ get one : value = {$v->value} , <br> ";
echo " ------ get one : timestamp = {$v->timestamp} <br>";
}
echo "----------\r\n";
$arr = $client->getRow($tableName, $row_name, $attributes);
// $client->getRow return a array
foreach ($arr as $k => $TRowResult) {
// $k = 0 ; non-use
// $TRowResult = TRowResult
var_dump($TRowResult);
}
echo "----------\r\n";
echo "----scanner get ------\r\n";
$startRow = '1';
$columns = array ('column' => 'score', );
//
$scan = $client->scannerOpen($tableName, $startRow, $columns, $attributes);
$nbRows = 1000;
$arr = $client->scannerGetList($scan, $nbRows);
var_dump('count of result :'.count($arr));
foreach ($arr as $k => $TRowResult) {
// code...
//var_dump($TRowResult);
}
$client->scannerClose($scan);
$transport->close();
?>
效果如下圖所示
此時php讀寫hbase成功,個人覺得其中的問題主要出在命名空間上,需要很注意namespace和use的使用,不能漏掉任何一個可用的。