### 3.1 實驗目的
1. 會在Linux環境下編寫讀寫HDFS文件的代碼;
2. 會使用jar命令打包代碼;
3. 會在client服務器上運行HDFS讀寫程序;
4. 會在Windows上安裝Eclipse Hadoop插件;
5. 會在Eclipse環境編寫讀寫HDFS文件的代碼;
6. 會使用Eclipse打包代碼;
7. 會使用Xftp工具將實驗電腦上的文件上傳至client服務器。
### 3.2 實驗要求
實驗結束時,每位學生均已搭建HDFS開發環境;編寫了HDFS寫、讀代碼;在client機上執行了該寫、讀程序。通過實驗了解HDFS讀寫文件的調用流程,理解HDFS讀寫文件的原理。
### 3.3 實驗原理
#### 3.3.1 Java Classpath
Classpath設置的目的,在于告訴Java執行環境,在哪些目錄下可以找到您所要執行的Java程序所需要的類或者包。
Java執行環境本身就是一個平臺,執行于這個平臺上的程序是已編譯完成的Java程序(后面會介紹到Java程序編譯完成之后,會以.class文件存在)。如果將Java執行環境比喻為操作系統,如果設置Path變量是為了讓操作系統找到指定的工具程序(以Windows來說就是找到.exe文件),則設置Classpath的目的就是讓Java執行環境找到指定的Java程序(也就是.class文件)。
有幾個方法可以設置Classpath,較簡單的方法是在系統變量中新增Classpath環境變量。以Windows 7操作系統為例,右鍵點擊計算機→屬性→高級系統設置→環境變量,在彈出菜單的“系統變量”下單擊“新建”按鈕,在“變量名”文本框中輸入Classpath,在“變量值”文本框中輸入Java類文件的位置。例如可以輸入“.; D:\Java\jdk1.7.0_79\lib\tools.jar; D:\Java\jdk1.7.0_79\lib\rt.jar”,每一路徑中間必須以英文;作為分隔。如圖3-1所示:

事實上JDK 7.0默認就會到當前工作目錄(上面的.設置),以及JDK的lib目錄(這里假設是D:\Java\jdk1.7.0_796\lib)中尋找Java程序。所以如果Java程序是在這兩個目錄中,則不必設置Classpath變量也可以找得到,將來如果Java程序不是放置在這兩個目錄時,則可以按上述設置Classpath。
如果所使用的JDK工具程序具有Classpath命令選項,則可以在執行工具程序時一并指定Classpath。例如:
javac -classpath classpath1;classpath2...其中classpath1、classpath 2是實際要指定的路徑。也可以在命令符模式下執行以下的命令,直接設置環境變量,包括Classpath變量(這個設置在下次重新打開命令符模式時就不再有效):
set CLASSPATH=%CLASSPATH%;classpath1;classpath2...總而言之,設置Classpath的目的,在于告訴Java執行環境,在哪些目錄下可以找到您所要執行的Java程序(.class文件)。
#### 3.3.2 Eclipse Hadoop插件
Eclipse 是一個跨平臺的自由集成開發環境(IDE)。通過安裝不同的插件,Eclipse可以支持不同的計算機語言,比如C++和Python等開發工具,亦可以通過hadoop插件來擴展開發Hadoop相關程序。
實際工作中,Eclipse Hadoop插件需要根據hadoop集群的版本號進行下載并編譯,過程較為繁瑣。為了節約時間,將更多的精力用于實現讀寫HDFS文件,在大數據實驗一體機的相關下載頁面中已經提供了2.7.1版本的hadoop插件和相關的hadoop包下載,實驗人員可以直接下載這些插件,快速在Eclipse中進行安裝,開發自己的hadoop程序。
### 3.4 實驗步驟
#### 3.4.1 配置client服務器classpath
使用ssh工具登錄client服務器,執行命令vi /etc/profile,編輯該文件,將末尾的如下幾行:
~~~
JAVA_HOME=/usr/local/jdk1.7.0_79/
export JRE_HOME=/usr/local/jdk1.7.0_79//jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
export HADOOP_HOME=/usr/cstor/hadoop
export PATH=$PATH:$HADOOP_HOME/bin
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib"
~~~
用下列行進行替換:
~~~
JAVA_HOME=/usr/local/jdk1.7.0_79/
export HADOOP_HOME=/usr/cstor/hadoop
export JRE_HOME=/usr/local/jdk1.7.0_79//jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$HADOOP_HOME/share/hadoop/common/*:$HADOOP_HOME/share/hadoop/common/lib/*
export PATH=$PATH:$HADOOP_HOME/bin
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib:$HADOOP_HOME/lib/native"
~~~
執行命令source /etc/profile,使剛才的環境變量修改生效:
~~~
[root@client ~]# source /etc/profile
~~~
#### 3.4.2 在client服務器編寫HDFS寫程序
在client服務器上執行命令vi WriteFile.java,編寫HDFS寫文件程序:
~~~
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class WriteFile {
public static void main(String[] args)throws Exception{
Configuration conf=new Configuration();
FileSystem hdfs = FileSystem.get(conf);
Path dfs = new Path("/weather.txt");
FSDataOutputStream outputStream = hdfs.create(dfs);
outputStream.writeUTF("nj 20161009 23\n");
outputStream.close();
}
}
~~~
#### 3.4.3 編譯并打包HDFS寫程序
使用javac編譯剛剛編寫的代碼,并使用jar命令打包為hdpAction.jar:
~~~
[root@client ~]# javac WriteFile.java
[root@client ~]# jar -cvf hdpAction.jar WriteFile.class
added manifest
adding: WriteFile.class(in = 833) (out= 489)(deflated 41%)
~~~
#### 3.4.4 執行HDFS寫程序
在client服務器上使用hadoop jar命令執行hdpAction.jar:
~~~
[root@client ~]# hadoop jar ~/hdpAction.jar WriteFile
~~~
查看是否已生成weather.txt文件,若已生成,則查看文件內容是否正確:
~~~
[root@client ~]# hadoop fs -ls /
Found 2 items
-rw-r--r-- 3 root supergroup 29 2016-12-05 12:28 /machines
-rw-r--r-- 3 root supergroup 17 2016-12-05 14:54 /weather.txt
[root@client ~]# hadoop fs -cat /weather.txt
nj 20161009 23
~~~
#### 3.4.5 在client服務器編寫HDFS讀程序
在client服務器上執行命令vi ReadFile.java,編寫HDFS讀文件程序:
~~~
import java.io.IOException;
import org.apache.Hadoop.conf.Configuration;
import org.apache.Hadoop.fs.FSDataInputStream;
import org.apache.Hadoop.fs.FileSystem;
import org.apache.Hadoop.fs.Path;
public class ReadFile {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
Path inFile = new Path("/weather.txt");
FileSystem hdfs = FileSystem.get(conf);
FSDataInputStream inputStream = hdfs.open(inFile);
System.out.println("myfile: " + inputStream.readUTF());
inputStream.close();
}
}
~~~
#### 3.4.6 編譯并打包HDFS讀程序
使用javac編譯剛剛編寫的代碼,并使用jar命令打包為hdpAction.jar
~~~
[root@client ~]# javac ReadFile.java
[root@client ~]# jar -cvf hdpAction.jar ReadFile.class
added manifest
adding: ReadFile.class(in = 1093) (out= 597)(deflated 45%)
~~~
#### 3.4.7 執行HDFS讀程序
在client服務器上使用hadoop jar命令執行hdpAction.jar,查看程序運行結果:
~~~
[root@client ~]# hadoop jar ~/hdpAction.jar ReadFile
myfile: nj 20161009 23
[root@client ~]#
~~~
#### 3.4.8 安裝與配置Eclipse Hadoop插件
關閉Eclipse軟件,將hadoop-eclipse-plugin-2.7.1.jar文件拷貝至eclipse安裝目錄的plugins文件夾下。如圖3-2和圖3-3所示:


接下來,我們需要準備本地的Hadoop環境,用于加載hadoop目錄中的jar包,只需解壓hadoop-2.7.1.tar.gz文件,解壓過程中可能會遇到如下錯誤,點擊關閉忽略即可。
現在,我們需要驗證是否可以用Eclipse新建Hadoop(HDFS)項目。打開Eclipse軟件,依次點擊FileàNewàOther,查看是否已經有Map/Reduce Project的選項。第一次新建Map/Reduce項目時,需要指定hadoop解壓后的位置。如圖3-5、圖3-6和圖3-7所示:

圖3-5 Eclipse新建Map/Reduce項目

圖3-6 設置Hadoop安裝目錄

圖3-7 指定Hadoop安裝目錄
#### 3.4.9 使用Eclipse開發并打包HDFS寫文件程序
打開Eclipse,依次點擊FileàNewàMap/Reduce Project或FileàNewàOtherà Map/Reduce Project,新建項目名為WriteHDFS的Map/Reduce項目。
新建WriteFile類并編寫如下代碼:
~~~
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class WriteFile {
public static void main(String[] args)throws Exception{
Configuration conf=new Configuration();
FileSystem hdfs = FileSystem.get(conf);
Path dfs = new Path("/weather.txt");
FSDataOutputStream outputStream = hdfs.create(dfs);
outputStream.writeUTF("nj 20161009 23\n");
outputStream.close();
}
}
~~~
在Eclipse左側的導航欄選中該項目,點擊ExportàJavaàJAR File,填寫導出文件的路徑和文件名(本例中設置為hdpAction.jar),確定導出即可。如圖3-8和圖3-9所示:

圖3-8 選擇導出JAR包文件

圖3-9 指定導出的JAR包文件名
#### 3.4.10 上傳HDFS寫文件程序jar包并執行
使用WinSCP、XManager或其它SSH工具的sftp工具上傳剛剛生成的hdpAction.jar包至client服務器:
~~~
sftp> lcd C:/Users/Administrator/Desktop/
sftp> put hdpAction.jar
Uploading hdpAction.jar to /root/hdpAction.jar
100% 2KB 2KB/s 00:00:00
C:/Users/Administrator/Desktop/hdpAction.jar: 2807 bytes transferred in 0 seconds (2807 bytes/s)
~~~
在client服務器上使用hadoop jar命令執行hdpAction.jar:
~~~
[root@client ~]# hadoop jar ~/hdpAction.jar WriteFile
~~~
查看是否已生成weather.txt文件,若已生成,則查看文件內容是否正確:
~~~
[root@client ~]# hadoop fs -ls /
Found 2 items
-rw-r--r-- 3 root supergroup 29 2016-12-05 12:28 /machines
-rw-r--r-- 3 root supergroup 17 2016-12-05 14:54 /weather.txt
[root@client ~]# Hadoop fs -cat /weather.txt
nj 20161009 23
~~~
#### 3.4.11 使用Eclipse開發并打包HDFS讀文件程序
打開Eclipse,依次點擊FileàNewàMap/Reduce Project或FileàNewàOtherà Map/Reduce Project,新建項目名為ReadHDFS的Map/Reduce項目。
新建ReadFile類并編寫如下代碼:
~~~
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class ReadFile {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
Path inFile = new Path("/weather.txt");
FileSystem hdfs = FileSystem.get(conf);
FSDataInputStream inputStream = hdfs.open(inFile);
System.out.println("myfile: " + inputStream.readUTF());
inputStream.close();
}
}
~~~
在Eclipse左側的導航欄選中該項目,點擊ExportàJavaàJAR File,導出為hdpAction.jar。
3.4.12 上傳HDFS讀文件程序jar包并執行
使用WinSCP、XManager或其它SSH工具的sftp工具上傳剛剛生成的hdpAction.jar包至client服務器,并在client服務器上使用hadoop jar命令執行hdpAction.jar,查看程序運行結果:
~~~
[root@client ~]# hadoop jar ~/hdpAction.jar ReadFile
myfile: nj 20161009 23
[root@client ~]#
~~~
- GitHub---資源收集
- 【GitHub】收錄總榜單
- 【Office & Markdown & PDF】資源收集
- 【前端】資源收集
- 【開源項目】資源收集
- 【代碼備份】資源收集
- 【代碼加密】資源收集
- 【好文章推薦】資源收集
- GitHub---實踐方案
- 【Laradock】實踐方案
- 【開發規范】實踐方案
- 【laravel-snappy】實踐方案
- 【隊列---Laravel-Horizon 】實踐方案
- 【檢索---Elasticsearch】實踐方案---簡單了解
- 【Laravel-admin】實踐方案
- 技術選型
- 技術選型結果
- PHP開發流程
- Laravel自帶異常
- 技術選型問題 & 解決方法
- 修改(Admin)文件夾路徑
- 兩個用戶表合并
- 創建Token,獲取接口數據
- CreateFreshApiToken中間件使用
- Generator從表生成文件,不包括遷移文件
- 添加用戶的同時生產令牌
- 其它參考文章
- Laravel-admin常見問題
- form(),show()獲取對象數據
- Form右上角按鈕重寫
- form回調中的錯誤提醒,回調傳參
- 【小工具類】實踐方案
- 字符串
- 數組
- 無限級分類遞歸
- 時間
- 正則表達式
- 文件
- 經緯度、時區
- DataEdit快捷操作類庫
- 數據庫表結構管理
- 【Guzzle】實踐方案---工具類
- Java---大數據在線實驗
- 基礎實驗操作
- 【一】基礎操作實驗
- HDFS
- 【二】部署HDFS
- 【三】讀寫HDFS文件
- YARN
- 【四】部署YARN集群
- MapReduce
- 【五】單詞計數
- Hive
- 【十】部署Hive
- 【十一】新建Hive表
- 【十二】Hive分區
- ZooKeeper
- 【二十】部署ZooKeeper
- 【二十一】進程協作
- HBase
- 【二十二】部署HBase
- 【二十三】新建HBase表
- Storm
- 【二十四】部署Storm
- 【二十五】實時WordCountTopology
- Kafka
- 【二十七】Kafka訂閱推送示例
- Redis
- 【二十九】Redis部署與簡單使用
- 【三十】MapReduce與Spark讀寫Redis
- MongoDB
- 【三十一】讀寫MongoDB
- MySQL
- 關于最重要的參數選項調整建議
- 索引,Explain優化工具
- 事務級別
- sql好的書寫習慣
- limit(分頁)
- 趕集網Mysql36條軍規
- 分庫分表技術演進&最佳實踐
- MariaDB 和 MySQL 全面對比
- 永遠不要在 MySQL 中使用“utf8”
- 看云--推薦的Mysql優化
- 完整、詳細的MySQL規范
- 慢查詢日志
- pt-query-digest結果分析
- Redis
- 看云-推薦的redis學習
- Memcache和Redis不同
- 阿里云Redis開發規范
- Centos7
- 虛擬機配置網絡
- 硬盤掛載、分區、文件大小
- 防火墻(firewalld、firewalld-cmd、systemctl、iptables)
- 兩個機器互相拷貝文件
- 查進程、查端口
- 壓縮、解壓
- 查看物理CPU個數、CPU內核數、線程數
- apt-get源--阿里
- RAID磁盤陣列
- Docker
- Dockerfile制作常用命令
- registry私有倉庫
- PHP_7.2
- Dockerfile
- php.ini
- 使用說明
- Nginx_1.15
- Dockerfile
- nginx.conf
- prod_nginx.conf
- 使用說明
- MySql_5.7
- Dockerfile
- my.cnf
- 使用說明
- redmine_3.4
- Dockerfile
- 使用說明
- gitlab-ce_11.9.6-ce.0
- 使用說明
- Redis_5.0
- Dockerfile
- redis.conf
- 使用說明
- Jenkins
- Dockerfile
- 使用說明
- webssh--python3.7
- Dockerfile
- 使用說明
- 進階使用
- 高階使用
- minio
- 使用說明
- aws_cloud9_ide
- 使用說明
- VNC
- 使用說明
- jdk1.8——yum安裝
- tomcat9——安裝
- guacamole——0.9.13
- libreoffice
- Dockerfile
- 使用說明
- Kubernetes
- kubectl常用命令
- 環境搭建(1.9.6)
- kubernetes1.9.6墻內離線部署
- kubernetes1.9.6單機器部署
- helm安裝
- helm常用命令
- Swoole
- 環境的搭建
- swoole的簡單實例
- 服務端的cli方式運行
- 客戶端的運行方式
- 定時任務的入門
- 刪除定時任務
- 初始化定時任務
- 日志管理
- 具體任務的異常捕獲
- 手動重啟shell腳本
- 閱讀感受
- 【讀書】登天的感覺——岳曉東
- 【讀書】為何家會傷人——武志紅
- 【感受】箭扣,一次就好
- 【讀書】思考與致富——拿破侖-希爾
- 【感受】做事講方法
- 【感受】未來暢想
- 【素材】智力問答
- 【百家】曾國藩家訓
- 【百家】正說和珅
- 【感受】談判小技巧
- 【讀書】股票作手回憶錄——利弗莫爾
- 【感受】最幸福的人——工匠
- 【收藏】土味情話大合集
- 【讀書】解憂雜貨店——東野圭吾
- 【收藏】家鄉名人
- 【讀書】把時間當作朋友——李笑來
- 【感受】輿論和八卦
- 【讀書】老人與海——海明威
- 【讀書】必然——凱文凱利
- 【經典】逍遙游——莊周
- Git+PHPStorm+Composer
- Git命令
- .gitignore忽略規則
- PHPStorm第一次使用
- PHPStorm關聯gitlab
- Composer修改鏡像源
- Xdebug
- PHP進階
- 緩存在高并發場景下的常見問題
- 一、緩存一致性問題
- 二、緩存并發問題
- 三、緩存穿透問題
- 四、緩存顛簸問題
- 五、緩存的雪崩現象
- 六、緩存無底洞現象
- Laravel源碼解析(知識點)
- 閉包、IOC容器服務綁定延遲加載
- 延遲靜態綁定基類
- 反射,依賴注入
- __callStatic 魔術方法,Facade 工作原理
- array_reduce,中間件解析
- Eloquent核心
- Laravel框架加載流程
- 線程、進程、協程
- Linux進程、線程、協程
- poll、epoll
- epoll原理
- Liunx線程調度算法
- 紅黑樹
- 同步/異步、阻塞/非阻塞
- PHP-FPM
- Nginx
- Swoole
- Go
- 驚群問題
- 線程模型比較
- 并發模型比較
- Lua
- OpenResty
- 數據一致性
- 悲觀鎖--VS--樂觀鎖
- 事務--mysql VS redis
- 事務嵌套--Doctrine VS Laravel
- 單體應用中執行順序問題
- 數據一致性問題描述
- 分布式理論
- 數據一致性---接口冪等性
- 分布式事務---2PC VS 3PC
- 分布式事務---TCC
- 分布式事務---基于消息
- 接口安全性
- PHP & Nginx
- 請求超時問題
- 兩者之間的通信原理
- TCP三次握手
- Nginx常用優化
- PHP數組底層原理
- PHP排序函數sort底層原理
- PHP函數---trim()
- 樹形數據在關系型庫中存儲
- 標簽(Tag)的各種設計