zoukankan      html  css  js  c++  java
  • 【hadoop摸索系列】记录使用libhdfs访问hdfs的关键问题

    hadoop官方的二进制发布版本一直是32位平台编译的,对于java来说跨平台不影响使用,但是为了在c/c++程序中操作hdfs就做不到了,因为libhdfs.so是二进制不兼容的。

    我使用的是stable版本的hadoop 2.20,直接从官方下载了二进制发布版本,在目录lib/native下有操作hadoop的c/c++库(.a和.so),但由于服务器是64位的原因无法链接。

    解决方法就是下载hadoop的src源码,自行编译生成so,这个过程如果没有Yum会比较繁琐,因为依赖很多,在编译过程中会遇到若干错误,后续会将编译步骤完善起来,这里只说明libhdfs.so如何编译生成一个可运行的程序。

    libhfds是基于libjvm运行的,也就是创造了一个java虚拟机然后直接调用hadoop的java jar包实现hdfs系统的访问,所以在编译程序时一定要注意以下几点要素:

    1, 如果你是64位系统,必须自行编译hadoop生成64位版本的libhfds.so,如果你是32位系统那就不必了,可以直接使用目录下的lib/native里的so。

    2, 编译时一定要链接libjvm.so,这个so在jdk/jre/lib/amd64/server/下面,其中amd64目录代表我是64位系统,你需要根据你的系统选择特定目录下的libjvm.so。

    3, 由于libhdfs直接基于jvm加载jar包,而jvm是依靠系统环境变量CLASSPATH寻找jar包的,所以你一定要export导出CLASSPATH环境变量,保证它包含了java jdk和jre的所有jar包以及hadoop/shared/hadoop内的所有jar包,这样运行时jvm才能正确的load到jar包,否则会抛出java异常令程序终止。

    4,由于程序依赖so动态库,为了运行时能够找到so,还需要导出libhdfs.so和libjvm.so的路径到LD_LIBRARY_PATH变量中去。

    下面是一段简单的示例代码,打开一个hdfs文件并向文件写入了hello hdfs,之后关闭文件,重点关注其编译命令:

    #include "hdfs.h"
    
    int main(int argc, char **argv)
    {
        hdfsFS fs = hdfsConnect("10.46.120.32", 8010);
        if (!fs) {
            fprintf(stderr, "connect fail
    ");
            return -1; 
        }   
        hdfsFile writeFile = hdfsOpenFile(fs, "/first.txt", O_WRONLY, 4096, 0, 0); 
        if (!writeFile) {
            fprintf(stderr, "openfile fali
    ");
            return -1; 
        }   
        hdfsWrite(fs, writeFile, "hello hdfs", 10);
        hdfsCloseFile(fs, writeFile);
        hdfsDisconnect(fs);
        return 0;
    }

    编译命令如下:

    gcc -o hdfs hdfs.c -L /hadoop/lib/native -lhdfs -I /hadoop/include -L /jdk/jre/lib/amd64/server/ -ljvm

    下面的代码足以完成所有环境变量的初始化,不需要再做额外的任何工作,建议填好后放到.bashrc中,这里假设hadoop安装在/hadoop中,jdk安装在/jdk中,libhdfs在hadoop默认路径下:

    export JAVA_HOME=/jdk  #jdk安装路径

    export JRE_HOME=${JAVA_HOME}/jre #jre路径

    export LD_LIBRARY_PATH=/jdk/jre/lib/amd64/server:/hadoop/lib/native # libjvm.so目录和libhdfs.so目录

    CLASSPATH=${JAVA_HOME}/lib:${JRE_HOME}/lib # jdk与jre的jar

    HADOOP_HOME=/hadoop #hadoop安装路径

    CLASSPATH=${CLASSPATH}":"`find ${HADOOP_HOME}/share/hadoop | awk '{path=path":"$0}END{print path}'` # hadoop的jar
    export CLASSPATH

  • 相关阅读:
    显示/隐藏Mac下的隐藏文件
    遍历指定文件下所有文件,删除指定后缀文件
    ssh公钥
    设置状态栏(statusbar)的样式
    Silverlight上传下载三种方法解析(三)
    Silverlight上传下载三种方式解析(二)
    Silverlight 上传下载之三种方式解析
    一个简单的存储过程代码生成器
    .net 程序发生了一个不可捕获的异常
    n取的r的组合数问题
  • 原文地址:https://www.cnblogs.com/qq120848369/p/3666757.html
Copyright © 2011-2022 走看看