假定主機上已經安裝了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