Hadoop 如何使用libhdfs.so

Posted tokendeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop 如何使用libhdfs.so相关的知识,希望对你有一定的参考价值。

Hadoop提供了C接口,这样可以通过C语言直接操纵Hadoop文件系统,虽然功能没有Java版本的完备,但可以满足一些项目需要。有关C接口的介绍,请点击此处。


本文主要一步一步实验如何使用libhdfs.so共享库。

实践过程中参考如下链接:

记录使用libhdfs访问hdfs的关键问题 - 开心比什么都贵

用hadoop中的libhdfs和fuse-dfs构建快速云存储

libhdfs编译、安装、配置、使用


官方发行的本地库貌似只提供了32位的,如果在64位的平台,需要自己编译。

这里做如下假定:

已经部署了一个健康的Hadoop集群,对外的访问接口为:10.17.48.236:9000,具有写权限的用户为hadoop;

已经编译好了针对特定平台64位的so库:libhdfs.so,并且该库保存在/home/dcc/libhdfs/目录下;


第一:在/home/dcc/old/目录下新建一个名为“write.c”的C文件,内容如下:

#include "hdfs.h"

int main(int argc, char **argv)

	// 取得文件系统实例,10.17.48.236为NanmNode的IP,9000为端口,hadoop为指定用户;
        hdfsFS fs = hdfsConnectAsUser("10.17.48.236", 9000,"hadoop");
        if (!fs) 
                fprintf(stderr, "connect fail\\n");
                return -1; 
           
	// 以写方式(O_WRONLY)打开文件;
        hdfsFile writeFile = hdfsOpenFile(fs, "/first.txt", O_WRONLY, 4096, 0, 0); 
        if (!writeFile) 
                fprintf(stderr, "openfile fali\\n");
                return -1; 
           
	// 向刚才创立的文件中写入“hello hdfs”;
        hdfsWrite(fs, writeFile, "hello hdfs", 10);
	// 关闭文件并且断开连接;
        hdfsCloseFile(fs, writeFile);
        hdfsDisconnect(fs);
        return 0;
上面使用hdfs.h头文件,为了编译方便,把该文件拷贝到与write.c相同的目录下,也就是拷贝到/home/dcc/old/下

第二:编译write.c文件:

gcc -o write write.c -L /home/dcc/libhdfs -lhdfs -I $HADOOP_HOME/include -L $JAVA_HOME/jre/lib/amd64/server/ -ljvm
上面$HADOOP_HOME为Hadoop的安全目录,$JAVA_HOME为Java的安装目录,当然到这里也可以不设置这两个环境变量,直接用对应的目录替换。

上面的编译命令,加载了/home/dcc/libhdfs目录下的libhdfs.so共享库,还引入了$HADOOP_HOME/include目录下的一些头文件,同时由于是64位的,还加载了$JAVA_HOME/jre/lib/amd64/server/目录下的libjvm.so。

命令执行完成后,应该在相同目录下多了一个write文件,这个是可执行文件。

第三:执行write:

./write
执行后报错, 说缺少共享库,解决方法,点击此处

问题解决后,应该就能成功往HDFS集群上写入文件。


经过上面一路走下来, 也加深了对共享库(在Linux平台下叫共享库,一般为*.so文件,而在Windows平台下一般叫动态链接库,一般为*.dll文件)的理解:就是如果C/C++程序中调用了共享库,则编译期间期间应该加入共享库,否则编译不通过。编译完成后,当要真正执行时,应该在程序的运行时环境(Runtime Environment)载入需要的共享库。这有点类似我们在开发Java项目的Jar包,当我们在开发的工程中用到某个jar包,必须引入对应的jar包,而我们打包自己的工程,可以只打包自己的源码。当我们发布到目标系统运行时,由于我们的工程依赖了某些jar包,所以在目标系统部署时,在目标系统我们的工程必须能访问到那些依赖的jar包。这也就是所谓的“共享”和“动态”的概念来源吧。


当然为了开发方便,可以在/etc/profile文件下添加如下内容,完成大部分配置工作:

export JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/amd64/server:/home/dcc/libhdfs
export HADOOP_HOME=/home/dcc/hadoop-2.2.0
CLASSPATH=$CLASSPATH":"`find $HADOOP_HOME/share/hadoop | awk 'path=path":"$0ENDprint path'`  
export CLASSPATH



以上是关于Hadoop 如何使用libhdfs.so的主要内容,如果未能解决你的问题,请参考以下文章

CentOS下添加动态链接库的方法

CentOS下添加动态链接库的方法

通过Hadoop RPC框架学习NIO

Hadoop学习笔记—3.Hadoop RPC机制的使用

如何安装单节点的hadoop

Hadoop RPC通信