php使用thrift操作hdfs

假定主機上已經安裝了LAMP環境


1. 安裝所需的依賴包

  也可以參考thift官網來安裝 http://thrift.apache.org/docs/install/centos

  #yum install automake libtool flex bison pkgconfig gcc-c++ boost-devel libevent-devel zlib-devel python-devel ruby-devel php php-devel

2. 從http://thrift.apache.org/download/下載thrift源碼包

3. 安裝thrift

    ./configure --with-lua=no –prefix=/usr/local/thrift

(可能出現的錯誤  bison版本不夠,升級bison2.5.*)

    make && make install

4. 安裝php擴展

    cd /path/to/thrift-0.8.0/lib/php/src/ext/thrift_protocol

    phpize

    ./configure -enable-thrift_protocol -with-php-config=/usr/bin/php

    make

    make install

    修改php.ini,添加extension=thrift_protocol.so

5. 從http://hadoop.apache.org/releases.html#Download下載hadoop源碼包

6. 解壓並編譯hadoop(注意必須先安裝好java編譯器,ant編譯環境,以及libtool, autoconf等工具)

    tar zxvf hadoop-1.0.4.tar.gz

    cd hadoop-1.0.4

    ant compile

7. 啓動hdfs以及thrift代理(hdfs集羣配置請參考官方文檔,不再累述)

    cd /path/to/hadoop-1.0.4

    bin/start-dfs.sh

     cd /path/to/hadoop-1.0.4/src/contrib/thriftfs/scripts/

     ./start_thrift_server.sh [port] (如果port爲空,則隨機一個port)

8. 準備php依賴庫

    cp -r /path/to/thrift-0.8.0/lib/php  /usr/local/thrift/lib

    mkdir -p /usr/local/thrift/lib/php/src/packages

    cp -r /path/to/hadoop-1.0.4/src/contrib/thriftfs/gen-php/ /usr/local/thrift/lib/php/src/packages/hadoopfs/

9. php測試代碼

<?php

error_reporting(E_ALL);
ini_set('display_errors', 'on');

$GLOBALS['THRIFT_ROOT'] = '/usr/local/thrift/lib/php/src';
define('THRIFT_ROOT', $GLOBALS['THRIFT_ROOT']);

/**
 * Init Autloader
*/
require_once THRIFT_ROOT . '/Thrift.php';
require_once THRIFT_ROOT . '/transport/TSocket.php';
require_once THRIFT_ROOT . '/transport/TBufferedTransport.php';
require_once THRIFT_ROOT . '/protocol/TBinaryProtocol.php';

$socket = new TSocket('192.168.1.12', 11511);
$socket->setSendTimeout(10000);
$socket->setRecvTimeout(20000);
$transport = new TBufferedTransport($socket);
$protocol = new TBinaryProtocol($transport);

require_once $THRIFT_ROOT . '/packages/hadoopfs/ThriftHadoopFileSystem.php';
$client = new ThriftHadoopFileSystemClient($protocol);

$transport->open();
try{

#$pathname = new Pathname(array('pathname' => '/user/hadoop/dir4test'));

#$fp = $client->open($pathname);

#var_dump($client->stat($pathname));

#var_dump($client->read($fp, 0, 1024));



$pathname = new Pathname(array('pathname' => '/user/hadoop/thrift'));

if(!$client->exists($pathname)){


$client->mkdirs($pathname);


print("Created dir". $pathname->pathname);


var_dump($client->stat($pathname));

}
}
catch(Exception $ex){

print_r($ex);
}
$transport->close();
?> 

thrift接口文件位於/src/contrib/thriftfs/if/hadoopfs.thrift,啓動thrift服務的腳本位於/usr/local/hadoop/src/contrib/thriftfs/scripts/start_thrift_server.sh,PHP語言文件位於/usr/local/hadoop/src/contrib/thriftfs/gen-php,包括hadoopfs_types.php  ThriftHadoopFileSystem.php兩個文件。
hadoopfs.thrift,包括4個結構,2個異常,19個service函數。以下將分別介紹結構和函數。

開啓thrift sever的腳本如下(當然,首先應啓動hadoop):

啓動start_thrift_server.sh時可以指定啓動端口 eg:sh start_thrift_server.sh 48566  不指定則隨機分配

啓動start_thrift_server.sh時報錯爲hadoop環境配置錯誤
Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/ hadoop/conf/Configuration

解決方法,將Hadoop的classpath加到環境變量中,如:
export CLASSPATH=$HADOOP_HOME"hadoop-core-1.0.4.jar"

或者直接在/etc/profile裏面加上變量的路徑  然後執行source /etc/profile讓其修改生效

如果不寫端口,則偵聽端口是隨機的,無論哪種情況,注意一下啓動的輸出,其中有端口號。


補充:

單機狀態測試時 本機必須同時安裝hadoop環境和thrift

聯機狀態使用時 server機安裝hadoop環境和thrift  php項目所在的客戶機也要安裝thrift
server機啓動thrift服務 (sh start_thrift_server.sh 48566)
客戶端機器鏈接時  socket(ip=server機ip,port=48566,……)

聯機操作時自己遇見的問題,測試機執行時一切正常,但是聯機時卻老是報錯
exception 'TTransportException' with message 'TSocket read 0 bytes' in /root/thrift/lib/php/src/transport/TSocket.php:263
問題:最後發現是因爲客戶端機器是32位系統,文件句柄id較長,32位機器溢出,致使write時找不到正確的文件句柄
解決:遷移64位機器後一切正常

接口結構,如下:

  • ThriftHandle:這個東西相當於文件句柄
  • Pathname:文件路徑
  • FileStatus :實際上是文件的各種屬性,包括名稱、長度、文件/目錄、塊複製數、塊大小,權限屬性等。
  • BlockLocation :文件塊的屬性,包括位置屬性,該塊在文件中的偏移量,大小等。

接口service函數如下(本文thrift採用的是0.8.0):

  • setInactivityTimeoutPeriod:設置超時時間(s),如果超過此時間,服務器斷開。
  • shutdown:斷開與服務器的連接
  • create、createFile:這兩個是創建文件,並輸出文件句柄供寫入,後一個函數提供了更多的文件屬性參數來控制文件的創建。
  • open:以讀寫方式打開一個已存在的文件,輸出文件句柄供操作。
  • append:以添加方式打開一個已存在的文件,輸出爲文件句柄。
  • write:向已打開的文件寫入數據,返回是否成功。
  • read:向已打開的文件讀取數據,與通常文件讀取一樣,需指定讀取位置和讀取大小。
  • close:關閉文件
  • rm:刪除文件或目錄,可以指定是否遞歸刪除目錄
  • rename:重新命名文件或目錄
  • mkdirs:創建目錄
  • exists:檢查文件或目錄是否存在
  • stat:獲取文件或目錄的屬性,輸出的是FileStatus結構。
  • listStatus:如果輸入是一個目錄,則輸出是目錄下所有文件的FileStatus結構(數組)
  • chmod:設置文件/目錄的權限
  • chown:設置文件/目錄的組和所有者
  • setReplication:設置文件的複製因子(多少份)
  • getFileBlockLocations:得到文件的塊的信息,輸出是BlockLocation數組。

以上這些接口除了具有複製因子、塊等信息外,與通常的文件操作沒有什麼區別,因此對它們進行再次封裝似乎沒有必要,除非有特殊的要求。


php操作hdfs自己用的另外一種解決方案:

在項目所在機器裝hadoop的client,並且安裝jdk,把hadoop需要的jar包放到此機器上,php直接exec去調用java,通過java命令去執行jar包,jar包內部執行hdfs操作


參考文章:

http://blog.csdn.net/guxch/article/details/12163519
http://blog.csdn.net/jiangheng0535/article/details/12089023

http://dongxicheng.org/search-engine/scribe-installation/
http://www.thinksaas.cn/group/topic/234079/

http://www.docin.com/p-473359851.html

http://blog.csdn.net/gs_zhaoyang/article/details/13503527
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章