假定主机上已经安装了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.youkuaiyun.com/guxch/article/details/12163519http://blog.youkuaiyun.com/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.youkuaiyun.com/gs_zhaoyang/article/details/13503527