踐)
系列文章目錄文章目錄系列文章目錄前言Shell命令與HDFS進(jìn)行交互目錄操作文件操作在云服務(wù)器中安裝Eclipse安裝圖形界面。圖形界面設(shè)置為中文圖形界面的取消eclipse調(diào)試java程序1. 新建 Java 項(xiàng)目2. 導(dǎo)入 Hadoop 相關(guān) jar 包3. 編寫(xiě)讀取 HDFS 文件的 Java 示例4. 運(yùn)行結(jié)果說(shuō)明5. 常見(jiàn)報(bào)錯(cuò)與排查方法5.1 缺少依賴ClassNotFoundException / NoClassDefFoundError5.2 連接被拒絕Connection refused5.3 權(quán)限不足Permission denied5.4 文件不存在FileNotFoundException5.5 Windows 下運(yùn)行報(bào)錯(cuò)Could not locate executable null\bin\winutils.exe總結(jié)前言上篇文章介紹了如何在云服務(wù)器上部署hadoop本篇將介紹如何使用HDFS進(jìn)行操作。Shell命令與HDFS進(jìn)行交互首先要先啟動(dòng)hadoop.cd/usr/local/hadoop./sbin/start-dfs.shj進(jìn)行命令的查看./bin/hadoop fs./bin/hadoop fs-help put目錄操作在Hadoop系統(tǒng)安裝好以后第一次使用HDFS時(shí)需要首先在HDFS中創(chuàng)建用戶目錄。本教程全部采用hadoop用戶登錄Linux系統(tǒng)因此需要在HDFS中為hadoop用戶創(chuàng)建一個(gè)用戶目錄命令如下。cd/usr/local/hadoop./bin/hdfs dfs-mkdir-p/user/hadoop可用如下兩個(gè)命令進(jìn)行顯示HDFS中與當(dāng)前用戶hadoop對(duì)應(yīng)的用戶目錄下的內(nèi)容。./bin/hdfs dfs-ls../bin/hdfs dfs-ls/user/hadoop列出HDFS上的所有目錄。./bin/hdfs dfs-ls可以使用如下命令創(chuàng)建一個(gè)input目錄如果存在就不用再建了輸入命令也會(huì)給出提示信息。./bin/hdfs dfs-mkdir input要在HDFS的根目錄下創(chuàng)建一個(gè)名稱為input的目錄則需要使用如下命令。./bin/hdfs dfs-mkdir/input可以使用rm命令刪除一個(gè)目錄比如可以使用如下命令刪除剛才在HDFS中創(chuàng)建的“/input”目錄不是“/user/hadoop/input”目錄。./bin/hdfs dfs-rm-r/input文件操作在實(shí)際應(yīng)用中經(jīng)常需要從本地文件系統(tǒng)向HDFS中上傳文件或者把HDFS中的文件下載到本地文件系統(tǒng)中。首先使用vim編輯器在本地Linux文件系統(tǒng)的“/home/hadoop/”目錄下創(chuàng)建一個(gè)文件myLocalFile.txt里面可以隨意輸入一些單詞比如輸入如下三行。cd/home/hadoopvim myLocalFile.txt輸入以下內(nèi)容Hadoop Spark XMU DBLAB然后可以使用如下命令把本地文件系統(tǒng)的“/home/hadoop/myLocalFile.txt”上傳到HDFS中的當(dāng)前用戶目錄的input目錄下也就是上傳到HDFS的“/user/hadoop/input/”目錄下。首先要切換至hadoop下cd/usr/local/hadoop./bin/hdfs dfs-put/home/hadoop/myLocalFile.txt input可用下面命令進(jìn)行查看。./bin/hdfs dfs-lsinput下面使用如下命令查看HDFS中的myLocalFile.txt這個(gè)文件的內(nèi)容。./bin/hdfs dfs-catinput/myLocalFile.txt切換至/home/hadoop下建立download文件夾。cd ~ mkdir download下面把HDFS中的myLocalFile.txt文件下載到本地文件系統(tǒng)中的“/home/hadoop/download/”這個(gè)目錄下命令如下。cd/usr/local/hadoop./bin/hdfs dfs-get input/myLocalFile.txt/home/hadoop/download可以使用如下命令到本地文件系統(tǒng)查看下載下來(lái)的文件myLocalFile.txt。cd ~ cd download llcatmyLocalFile.txt最后了解一下如何把文件從HDFS中的一個(gè)目錄拷貝到HDFS中的另外一個(gè)目錄。比如如果要把HDFS的“/user/hadoop/input/myLocalFile.txt”文件拷貝到HDFS的另外一個(gè)目錄“/input”中注意這個(gè)input目錄位于HDFS根目錄下可以使用如下命令。cd/usr/local/hadoop./bin/hdfs dfs-cpinput/myLocalFile.txt/input可進(jìn)行查看文件內(nèi)容。./bin/hdfs dfs-ls./bin/hdfs dfs-cat/input在云服務(wù)器中安裝Eclipse下載Eclipse 2021-03版本可以使用以下命令。wget https://mirrors.tuna.tsinghua.edu.cn/eclipse/technology/epp/downloads/release/2023-09/R/eclipseeclipse-cpp-2023-09-R-linux-gtk-x86_64.tar.gzsudo tar-zxvf./eclipse-cpp-2023-09-R-linux-gtk-x86_64.tar.gz-C/usr/local找到/usr/local并查看下面的內(nèi)容。安裝圖形界面。以下的代碼命令會(huì)出現(xiàn)提示輸入y即可。如果所在的用戶是root用戶apt-get update apt-get install-y ubuntu-desktop systemctlset-defaultgraphical.target reboot如果所在的用戶是普通用戶sudo apt-get update sudo apt-get install-y ubuntu-desktop sudo systemctlset-defaultgraphical.target sudo reboot輸入完rebboot后重啟云服務(wù)器會(huì)進(jìn)入下面的界面。選擇hadoop用戶輸入密碼進(jìn)入。圖形界面設(shè)置為中文如果是第一次安裝會(huì)進(jìn)入英文的界面在英文界面找到終端。虛擬機(jī)桌面右鍵找到該位置打開(kāi)終端。在hadoop用戶下安裝中文語(yǔ)言包sudo apt-get install language-pack-zh-hans還需將系統(tǒng)的默認(rèn)語(yǔ)言設(shè)置為中文sudoupdate-localeLANGzh_CN.UTF-8重新啟動(dòng)云服務(wù)器reboot再重啟后點(diǎn)擊下圖紅框位置下滑找到區(qū)域與語(yǔ)言如果上述設(shè)置無(wú)效在英文界面找到該選項(xiàng)。點(diǎn)擊語(yǔ)言進(jìn)行選擇如果在上述選項(xiàng)中未看見(jiàn)中文選項(xiàng)則點(diǎn)擊已安裝的語(yǔ)言。在這窗口中可以點(diǎn)擊添加或刪除語(yǔ)言在里面找到chinese安裝簡(jiǎn)體語(yǔ)言之后點(diǎn)再選擇中文點(diǎn)擊應(yīng)用到整個(gè)系統(tǒng)即可或者再次重啟云服務(wù)器即可。完成了云服務(wù)器的中文設(shè)定。圖形界面的取消在桌面上右鍵之后打開(kāi)終端sudo systemctlset-defaultmulti-user.target sudo reboot進(jìn)行圖形話的取消。徹底刪除sudo apt-get purge ubuntu-desktop unity gnome-shell lightdm sudo apt-get autoremove sudo rebooteclipse調(diào)試java程序前面已經(jīng)完成了 Hadoop 的安裝、HDFS 的 Shell 操作以及 Eclipse 的安裝與圖形界面配置。本節(jié)將在 Eclipse 中編寫(xiě)一個(gè) Java 程序直接通過(guò) HDFS Java API 讀取 HDFS 上的文件并輸出內(nèi)容同時(shí)說(shuō)明運(yùn)行結(jié)果與常見(jiàn)報(bào)錯(cuò)的排查方法。1. 新建 Java 項(xiàng)目打開(kāi) Eclipse依次點(diǎn)擊File - New - Java Project在彈出的窗口中填寫(xiě)項(xiàng)目名稱例如HDFSDemoJRE 選擇本機(jī)已安裝的 JDK建議 JDK 8 及以上點(diǎn)擊Finish完成創(chuàng)建。如果 Eclipse 提示需要配置 JRE可在Window - Preferences - Java - Installed JREs中添加本機(jī)的 JDK 路徑例如/usr/lib/jvm/java-8-openjdk-amd64。項(xiàng)目創(chuàng)建完成后在src目錄上右鍵選擇New - Class填寫(xiě)包名com.hadoop.demo、類名HDFSReadDemo勾選public static void main(String[] args)點(diǎn)擊Finish。2. 導(dǎo)入 Hadoop 相關(guān) jar 包Hadoop 的 Java 依賴都在 Hadoop 安裝目錄的share/hadoop下。最省事的做法是把相關(guān)目錄下的 jar 包全部導(dǎo)入項(xiàng)目在項(xiàng)目名HDFSDemo上右鍵選擇Build Path - Configure Build Path切換到Libraries標(biāo)簽頁(yè)點(diǎn)擊Add External JARs然后依次進(jìn)入 Hadoop 安裝目錄本教程為/usr/local/hadoop把以下目錄中的 jar 包全部選中導(dǎo)入/usr/local/hadoop/share/hadoop/common及其lib子目錄/usr/local/hadoop/share/hadoop/hdfs及其lib子目錄/usr/local/hadoop/share/hadoop/yarn及其lib子目錄/usr/local/hadoop/share/hadoop/mapreduce及其lib子目錄也可以在終端中用一條命令把所需 jar 包復(fù)制到一個(gè)統(tǒng)一目錄再整體導(dǎo)入mkdir-p/home/hadoop/hadoop-libs find/usr/local/hadoop/share/hadoop-name*.jar-execcp{}/home/hadoop/hadoop-libs/ \;然后在Add External JARs中一次性選中/home/hadoop/hadoop-libs下的所有 jar 包即可。3. 編寫(xiě)讀取 HDFS 文件的 Java 示例在HDFSReadDemo.java中寫(xiě)入如下代碼實(shí)現(xiàn)讀取 HDFS 上/user/hadoop/input/myLocalFile.txt文件并打印內(nèi)容packagecom.hadoop.demo;importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.net.URI;importorg.apache.hadoop.conf.Configuration;importorg.apache.hadoop.fs.FSDataInputStream;importorg.apache.hadoop.fs.FileSystem;importorg.apache.hadoop.fs.Path;publicclassHDFSReadDemo{publicstaticvoidmain(String[]args){StringhdfsUrihdfs://localhost:9000;StringfilePath/user/hadoop/input/myLocalFile.txt;ConfigurationconfnewConfiguration();conf.set(fs.defaultFS,hdfsUri);FileSystemfsnull;FSDataInputStreaminnull;BufferedReaderreadernull;try{// 獲取 HDFS 文件系統(tǒng)實(shí)例fsFileSystem.get(newURI(hdfsUri),conf,hadoop);PathpathnewPath(filePath);if(!fs.exists(path)){System.out.println(文件不存在filePath);return;}infs.open(path);readernewBufferedReader(newInputStreamReader(in,UTF-8));System.out.println( 開(kāi)始讀取 filePath );Stringline;while((linereader.readLine())!null){System.out.println(line);}System.out.println( 讀取結(jié)束 );}catch(Exceptione){e.printStackTrace();}finally{try{if(reader!null)reader.close();if(in!null)in.close();if(fs!null)fs.close();}catch(Exceptione){e.printStackTrace();}}}}說(shuō)明幾點(diǎn)hdfs://localhost:9000中的端口要與core-site.xml中fs.defaultFS的配置保持一致若配置的是hdfs://localhost:8020這里也要改成8020。FileSystem.get(new URI(hdfsUri), conf, hadoop)中的hadoop是運(yùn)行 HDFS 的用戶名避免出現(xiàn)權(quán)限不足的問(wèn)題。讀取的文件路徑要與前面通過(guò) Shell 上傳的文件路徑一致即/user/hadoop/input/myLocalFile.txt。4. 運(yùn)行結(jié)果說(shuō)明在 Eclipse 中右鍵HDFSReadDemo.java選擇Run As - Java Application控制臺(tái)輸出如下 開(kāi)始讀取/user/hadoop/input/myLocalFile.txt Hadoop Spark XMU DBLAB 讀取結(jié)束 輸出的內(nèi)容與前面通過(guò)./bin/hdfs dfs -cat input/myLocalFile.txt查看到的內(nèi)容完全一致說(shuō)明 Java 程序已經(jīng)成功通過(guò) HDFS API 讀取到了 HDFS 上的文件。5. 常見(jiàn)報(bào)錯(cuò)與排查方法5.1 缺少依賴ClassNotFoundException / NoClassDefFoundError報(bào)錯(cuò)信息類似java.lang.ClassNotFoundException: org.apache.hadoop.conf.Configuration或java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FileSystem原因Hadoop 的 jar 包沒(méi)有正確加入項(xiàng)目的 Build Path。排查方法檢查Build Path - Configure Build Path - Libraries中是否已經(jīng)包含hadoop-common、hadoop-hdfs等 jar 包。確認(rèn)導(dǎo)入的是share/hadoop下各子目錄及其lib目錄中的 jar 包只導(dǎo)入主 jar 而漏掉lib下的依賴同樣會(huì)報(bào)錯(cuò)。修改后重新Clean項(xiàng)目Project - Clean再運(yùn)行。5.2 連接被拒絕Connection refused報(bào)錯(cuò)信息類似java.net.ConnectException: CallFromxxx to localhost:9000 failed on connection exception: java.net.ConnectException: Connection refused原因HDFS 沒(méi)有啟動(dòng)或者程序中的地址、端口與實(shí)際配置不一致。排查方法在終端執(zhí)行jps確認(rèn)NameNode、DataNode進(jìn)程存在若沒(méi)有執(zhí)行./sbin/start-dfs.sh啟動(dòng) Hadoop。查看core-site.xml中fs.defaultFS的值確認(rèn)代碼中的hdfsUri與之完全一致端口 9000 與 8020 是最常見(jiàn)的差異。如果 Eclipse 運(yùn)行在云服務(wù)器上確認(rèn) HDFS 相關(guān)端口如 9000、9870在安全組中已放行如果 Eclipse 運(yùn)行在本地而 HDFS 在云服務(wù)器上需要把localhost換成云服務(wù)器的公網(wǎng) IP并確保端口可訪問(wèn)。5.3 權(quán)限不足Permission denied報(bào)錯(cuò)信息類似org.apache.hadoop.security.AccessControlException: Permission denied: userxxx,accessREAD,inode/user/hadoop/input/myLocalFile.txt原因運(yùn)行程序的用戶與 HDFS 文件所屬用戶不一致。排查方法在FileSystem.get中顯式指定用戶名如FileSystem.get(new URI(hdfsUri), conf, hadoop)?;蛘咴谶\(yùn)行配置的VM arguments中加入-DHADOOP_USER_NAMEhadoop。也可以對(duì)目標(biāo)文件執(zhí)行./bin/hdfs dfs -chmod -R 777 /user/hadoop/input放開(kāi)權(quán)限僅建議在測(cè)試環(huán)境使用。5.4 文件不存在FileNotFoundException報(bào)錯(cuò)信息類似java.io.FileNotFoundException: File/user/hadoop/input/myLocalFile.txt does not exist原因讀取的路徑寫(xiě)錯(cuò)或文件尚未上傳到 HDFS。排查方法執(zhí)行./bin/hdfs dfs -ls /user/hadoop/input確認(rèn)文件確實(shí)存在。注意 HDFS 路徑是絕對(duì)路徑不要寫(xiě)成相對(duì)路徑或本地路徑。若文件不存在先按前面「文件操作」一節(jié)的命令重新上傳。5.5 Windows 下運(yùn)行報(bào)錯(cuò)Could not locate executable null\bin\winutils.exe原因Hadoop 原生庫(kù)在 Windows 下需要winutils.exe支持。排查方法下載與 Hadoop 版本對(duì)應(yīng)的winutils.exe和hadoop.dll放到本地 Hadoop 目錄的bin下。配置環(huán)境變量HADOOP_HOME指向該目錄并把%HADOOP_HOME%\bin加入Path。更推薦直接在 Linux 云服務(wù)器的圖形界面中使用 Eclipse可避免此類平臺(tái)差異問(wèn)題??偨Y(jié)本文圍繞 HDFS 的實(shí)踐操作展開(kāi)形成了一條從命令行到編程接口的完整鏈路。首先通過(guò) Shell 命令與 HDFS 交互熟悉hadoop fs的用法與幫助信息接著在目錄操作中創(chuàng)建用戶目錄、查看與刪除目錄掌握 HDFS 的路徑體系隨后在文件操作中完成本地文件的上傳、查看、下載與 HDFS 內(nèi)部拷貝理解本地文件系統(tǒng)與 HDFS 之間的數(shù)據(jù)流轉(zhuǎn)。在此基礎(chǔ)上安裝 Eclipse 并配置圖形界面與中文環(huán)境為編寫(xiě) Java 程序提供可視化開(kāi)發(fā)環(huán)境最后通過(guò) HDFS Java API 讀取 HDFS 文件并輸出內(nèi)容把前面的 Shell 操作對(duì)應(yīng)到代碼實(shí)現(xiàn)上。學(xué)習(xí)時(shí)應(yīng)重點(diǎn)把握「先 Shell 驗(yàn)證、再代碼實(shí)現(xiàn)」的思路并注意端口配置、依賴導(dǎo)入與權(quán)限設(shè)置這幾個(gè)關(guān)鍵銜接點(diǎn)。