假定主機上已經安裝了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時報錯爲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/12163519http://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