【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\n");
        return -1; 
    }   
    hdfsFile writeFile = hdfsOpenFile(fs, "/first.txt", O_WRONLY, 4096, 0, 0); 
    if (!writeFile) {
        fprintf(stderr, "openfile fali\n");
        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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM