背景
在開發(fā)系統(tǒng)的時候献丑,我們可能會有把數(shù)據(jù)備份到HDFS的需求。如果我們自身的系統(tǒng)是用Java開發(fā)的咐熙,那么直接用HDFS的Java API就可以了挺举;而如果系統(tǒng)本身采用的是C++杀赢,那么使用HDFS的C接口就有些頭疼了。主要原因在于HDFS的C接口是基于jni的湘纵,這意味著我們在部署的時候會不那么的直觀脂崔。
在這種情況下,用Linux Fuse的功能將HDFS掛在到本地的文件系統(tǒng)下會是一個非常好的選擇梧喷。在掛載成功后砌左,我們就可以用原生的文件API來訪問HDFS了。
此外铺敌,webhdfs和httpfs也提供了http的方式來訪問hdfs汇歹,但我覺得從易用性的角度而言,fuse仍舊應(yīng)該是最好的選擇偿凭。
如何部署使用fuse
首先产弹,我們在本地起一個hdfs服務(wù),然后用fuse對其進(jìn)行掛載弯囊。
先下載hadoop的預(yù)編譯包痰哨。我選取的是2.8.4,大家可以按照自己的需求選擇其他版本匾嘱。
然后可以參考Apache Hadoop的官方教程斤斧,在本地起一個簡單的HDFS服務(wù)。
如果想利用fuse掛在該hdfs服務(wù)霎烙,我們需要先編譯hdfs fuse的代碼:
- 下載hadoop的源代碼包撬讽,為了和剛才選擇的預(yù)編譯包保持一致蕊连,我也選擇了2.8.4
- 解壓后,按照解壓根目錄下的BUILDING.txt來安裝編譯環(huán)境锐秦。主要包括jdk, maven, protobuf-compiler, fuse
- 編譯
mvn clean package -Pnative -DskipTests
- 編譯好之后,fuse所用到的幾個文件散落在幾個不同的地方盗忱,需要手動把他們放到一起酱床,這樣方便使用:
mkdir output
cp hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/fuse-dfs/fuse_dfs_wrapper.sh output
cp hadoop-hdfs-project/hadoop-hdfs-native-client/target/native/target/usr/local/lib/libhdfs.so* output
cp hadoop-hdfs-project/hadoop-hdfs-native-client/target/main/native/fuse-dfs/fuse_dfs output
- 把fuse編譯好之后,就可以使用上面提到的fuse_dfs_wrapper.sh來進(jìn)行掛載了趟佃,命令方式為:
./fuse_dfs_wrapper.sh dfs://127.0.0.1:9000 /mnt/hdfs
腳本的主要作用是設(shè)置一些jar包和動態(tài)鏈接庫的加載路徑扇谣,然后調(diào)用fuse_dfs的可執(zhí)行程序。該腳本在使用上有幾個點需要注意:
- 要把編譯hadoop時生成的jar包都放到j(luò)ava的CLASSPATH中闲昭。更簡單的做法罐寨,是把前面下載的預(yù)編譯hadoop包中的jar包加進(jìn)去。
- fuse_dfs的程序會依賴hdfs的C接口動態(tài)庫序矩,從而會間接依賴到libjvm.so鸯绿;而后者位于jre的目錄下。需要修改LD_LIBRARY_PATH簸淀,使得程序可以找到這些動態(tài)庫瓶蝴。
- fuse_dfs在運行時,依賴于fuse內(nèi)核模塊及其相應(yīng)的設(shè)備文件租幕。最簡單的檢測方式是看系統(tǒng)中是否存在/dev/fuse的設(shè)備文件舷手。如果不存在,請安裝fuse:
apt-get install fuse libfuse-dev
- ./fuse_dfs_wrapper.sh在使用的時候可以通過加-d參數(shù)來打印調(diào)試信息劲绪。這種方法可以非常方便的用來排錯:
./fuse_dfs_wrapper.sh dfs://127.0.0.1:9000 /mnt/hdfs -d
如果hdfs開啟了kerberos身份認(rèn)證
上面的例子中男窟,HDFS的服務(wù)端用的是simple的認(rèn)證模式。如果server端開啟了kerberos的身份認(rèn)證贾富,則利用fuse的過程會稍微復(fù)雜一些:
- 在使用fuse_dfs_wrapper.sh之前歉眷,客戶端需要使用kinit來向kerberos獲取自己用戶的credential。相應(yīng)的颤枪,由于credential的ticket存在有效期姥芥,所以請使用另外的程序來定期更新ticket。
- 如果本地用戶名和kerberos的用戶名不一樣汇鞭,訪問hdfs可能會依舊沒有權(quán)限凉唐。這里建議本地建一個同名的用戶來進(jìn)行訪問。例如你的kerberos的用戶名是hdfs_tst/fqdn@realm, 那么請建立hdfs_tst的本地用戶霍骄,并在該用戶下執(zhí)行所有操作台囱。