首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言訪問 HDFS 實戰:Hadoop C API 編譯運行踩坑全記錄

     編輯:關於C語言

環境背景

Ubuntu + Hadoop 單機偽分佈模式,使用 libhdfs (JNI 封裝) 從 C 程式讀寫 HDFS。編譯命令:

gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
    -I$HADOOP_HOME/include -L$HADOOP_HOME/lib/native \
    -lhdfs -o test test.c

問題 1:權限不足 - Mkdirs failed

現象:./test 拋出 java.io.IOException: Mkdirs failed to create /my。
原因:HDFS 默認用戶 hadoop 無 /my 寫權限。
解決:sudo ./test 或 hdfs dfs -mkdir -p /my && hdfs dfs -chmod 777 /my。生產環境應配置 Kerberos/ACL 而非 sudo。

問題 2:sudo 丟失環境變量 CLASSPATH

現象:sudo ./test 提示 Environment variable CLASSPATH not set!。
原因:sudo 默認重置環境變量(env_reset),~/.bashrc 中的 CLASSPATH 不繼承。
解決:
1. sudo -E ./test 保留環境(需 sudoers 允許)。
2. 編輯 /etc/sudoers(用 visudo):Defaults env_keep += "CLASSPATH JAVA_HOME HADOOP_HOME"。
3. 代碼中調用 hdfsBuilderSetConf 顯式指定配置路徑,不依賴環境變量。

問題 3:誤修改 sudoers 權限導致 sudo 失效

操作:chmod 777 /etc/sudoers 後無法 sudo,報錯 mode 0777, should be 0440。
修復:切換 root 用戶修復:
su root → chmod 440 /etc/sudoers → chown root:root /etc/sudoers。
教訓:絕不直接 chmod 系統關鍵文件,務必用 visudo 編輯 sudoers。

最佳實踐總結

  1. 編譯鏈接:確保 JAVA_HOME、HADOOP_HOME、LD_LIBRARY_PATH 包含 libjvm.so 和 libhdfs.so 目錄。
  2. 配置隔離:使用 hdfsBuilder API 程式化設定 fs.defaultFS、hadoop.conf.dir,避免依賴環境變量。
  3. 錯誤處理:檢查 hdfsConnect 返回值,調用 hdfsGetLastError() 獲取詳細 JNI 異常信息。
  4. 權限模型:開發環境用戶映射(core-site.xml hadoop.proxyuser.*.hosts/groups),生產用 Kerberos + ACL。
  5. 替代方案:考慮 libhdfs3 (純 C 實現,無 JVM 依賴) 或 WebHDFS REST API (curl + JSON)。

簡易測試代碼片段

#include <hdfs.h>
#include <stdio.h>

int main() {
    struct hdfsBuilder *bld = hdfsNewBuilder();
    hdfsBuilderSetNameNode(bld, "localhost");
    hdfsBuilderSetNameNodePort(bld, 9000);
    hdfsFS fs = hdfsBuilderConnect(bld);
    if (!fs) { fprintf(stderr, "Connect failed: %s\n", hdfsGetLastError()); return 1; }

    hdfsFile f = hdfsOpenFile(fs, "/my/t.txt", O_WRONLY|O_CREAT, 0, 0, 0);
    if (!f) { fprintf(stderr, "Open failed: %s\n", hdfsGetLastError()); return 1; }

    const char *buf = "Hello HDFS from C!\n";
    tSize n = hdfsWrite(fs, f, buf, strlen(buf));
    if (n < 0) fprintf(stderr, "Write failed\n");
    hdfsCloseFile(fs, f);
    hdfsDisconnect(fs);
    return 0;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved