{{{ #!html
hadoop + Hbase + thrift + php
程式碼解析
}}} [[PageOutline]] = 零、前言 = * thrift 是透過非java的其他程式語言,直接對hbase 進行存取的中介函式庫 * ''''' 此篇介紹的是如何用php透過 thrift 對 hbase 操作 ''''' * 程式安裝測試方法已紀錄於: [wiki:waue/2010/0401 安裝編譯及測試 ] * 因此目錄結構為 || 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 尚在執行 = 一、php引用thrift lib = {{{ #!php 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(); ?> ........ 其他html 碼 ....... close(); ?> }}} * 所有的程式碼都必須包含這些引入函式庫、開啟關閉socket 的敘述 = 二、各種對hbase的操作 = == 2.1 列出hbase 裡的所有 table == {{{ #!php getTableNames(); sort( $tables ); foreach ( $tables as $name ) { echo( " found: {$name}\n" ); } } ?> }}} == 2.2 刪除table == {{{ #!php isTableEnabled( $name )) { echo( " disabling table: {$name}\n"); $client->disableTable( $name ); } echo( " deleting table: {$name}\n" ); $client->deleteTable( $name ); } ?> }}} == 2.3 新增table == * 我們先定義columns 的物件結構如下 {{{ #!php 'entry:', 'maxVersions' => 10 ) ), new ColumnDescriptor( array( 'name' => 'unused:' ) ) ); ?> }}} * 將剛剛的column 放到table 內 {{{ #!php createTable( $t, $columns ); } catch ( AlreadyExists $ae ) { echo( "WARN: {$ae->message}\n" ); } ?> }}} == 2.4 列出 table內的家族成員 family == {{{ #!php getColumnDescriptors( $t ); asort( $descriptors ); foreach ( $descriptors as $col ) { echo( " column: {$col->name}, maxVer: {$col->maxVersions}\n" ); } ?> }}} == 2.5 寫入資料 == {{{ #!php 'entry:foo', 'value' => $valid ) ), ); $client->mutateRow( $t, $row, $mutations ); ?> }}} == 2.6 讀取資料 == === get 取得一個 column value === * get 取得一個 column value 的用法 {{{ #!php get($table_name, $row_name , $fam_col_name); // $arr = array foreach ( $arr as $k=>$v ) { // $k = TCell echo ("value = {$v->value} ,
"); echo ("timestamp = {$v->timestamp}
"); } } ?> }}} === getRow 取得一整個row === * getRow($tableName, $row) 用法 {{{ #!php getRow($table_name, $row_name); // $client->getRow return a array foreach ( $arr as $k=>$TRowResult ) { // $k = 0 ; non-use // $TRowResult = TRowResult printTRowResult($TRowResult); } ?> }}} === scan 一整個table === {{{ #!php scannerOpen( $table_name, $start_row , $family ); // $scanner 是一個遞增數字 for open socket // scannerGet() 一次只抓一row,因此要用while迴圈不斷地抓 while (true ){ $get_arr = $client->scannerGet( $scanner ); // get_arr is an array if($get_arr == null) break; // 沒有回傳值代表已經沒有資料可抓,跳脫此無限迴圈 foreach ( $get_arr as $TRowResult ){ // $TRowResult = TRowResult echo (" row = {$TRowResult->row} ;
"); $column = $TRowResult->columns; foreach ($column as $family_column=>$Tcell){ echo ("family:column = $family_column "); // $family_column = family_column // $Tcell = Tcell echo (" value = {$Tcell->value} "); echo (" timestamp = {$Tcell->timestamp}
"); } } } echo( "
----------------- " ); echo( "
Scanner finished
" ); $client->scannerClose( $scanner ); ?> }}} = 補充 = == TCell == {{{ #!php array( 'var' => 'value', 'type' => TType::STRING, ), 2 => array( 'var' => 'timestamp', 'type' => TType::I64, ), ); } if (is_array($vals)) { if (isset($vals['value'])) { $this->value = $vals['value']; } if (isset($vals['timestamp'])) { $this->timestamp = $vals['timestamp']; } } } } ?> }}} == TRowResult == {{{ #!php array( 'var' => 'row', 'type' => TType::STRING, ), 2 => array( 'var' => 'columns', 'type' => TType::MAP, 'ktype' => TType::STRING, 'vtype' => TType::STRUCT, 'key' => array( 'type' => TType::STRING, ), 'val' => array( 'type' => TType::STRUCT, 'class' => 'TCell', ), ), ); } if (is_array($vals)) { if (isset($vals['row'])) { $this->row = $vals['row']; } if (isset($vals['columns'])) { $this->columns = $vals['columns']; } } } } ?> }}}