- 基于Hadoop與Spark的大數據開發實戰
- 肖睿 丁科 吳剛山
- 1917字
- 2019-09-10 13:26:14
任務2 HDFS基本操作
關鍵步驟如下。
掌握使用shell訪問HDFS文件系統。
掌握使用Java API訪問HDFS文件系統。
2.2.1 使用HDFS shell訪問
HDFS Shell訪問
1.概述
HDFS為使用者提供了基于shell操作命令來管理HDFS上的數據的功能。這些shell命令和Linux的命令十分類似,這樣設計的好處是讓已經熟悉Linux的用戶可以更加快速地對HDFS的數據進行操作,減少學習的時間。
注意
使用HDFS shell之前需要先啟動Hadoop。
HDFS的基本命令格式如下。
bin/hdfs dfs -cmd <args>
注意
cmd就是具體的命令,cmd前面的“-”千萬不要省略。
2.列出文件目錄
命令:hadoop fs -ls 目錄路徑
示例:查看HDFS根目錄下的文件
[hadoop@hadoop000 ~]$ hadoop fs -ls /
Found 4 items
-rw-r--r-- 1 hadoop supergroup 159 2017-01-15 05:11/README.html
drwxr-xr-x -hadoop supergroup 0 2017-01-15 05:15/data
drwxr-xr-x -hadoop supergroup 0 2017-01-15 05:31/datas
-rw-r--r-- 1 hadoop supergroup 40 2017-01-15 05:13/text.log
如果想遞歸查看文件,可以使用-ls -R命令,即該命令不僅會打印出目錄路徑下的文件,而且會打印出其子目錄和子目錄的文件。例如想查看/data下的所有文件。
[hadoop@hadoop000 ~]$ hadoop fs -ls -R /data
drwxr-xr-x -hadoop supergroup 0 2017-01-15 05:12/data/input
-rw-r--r-- 1 hadoop supergroup 21102856 2017-01-15 05:12/data/input/src.zip
-rw-r--r-- 1 hadoop supergroup 40 2017-01-15 05:15/data/text.log
3.在HDFS中創建文件夾
命令:hadoop fs -mkdir 文件夾名稱
示例:在HDFS的根目錄下創建名為datatest的文件夾
[hadoop@hadoop000 ~]$ hadoop fs -mkdir /datatest
[hadoop@hadoop000 ~]$ hadoop fs -ls /
Found 5 items
-rw-r--r-- 1 hadoop supergroup 159 2017-01-15 05:11/README.html
drwxr-xr-x -hadoop supergroup 0 2017-01-15 05:15/data
drwxr-xr-x -hadoop supergroup 0 2017-01-15 05:31/datas
drwxr-xr-x -hadoop supergroup 0 2017-01-17 03:39/datatest
-rw-r--r-- 1 hadoop supergroup 40 2017-01-15 05:13/text.log
如果想級聯創建一個文件夾,需要在-mkdir 命令后指定-p參數。例如,我們想在HDFS上創建這樣一個目錄:/datatest/mr/input,而mr目錄在之前是不存在的,所以想一次性創建成功,必須加上-p參數,否則會報錯,命令為:hadoop fs -mkdir -p /datatest/mr/input。
[hadoop@hadoop000 ~]$ hadoop fs -mkdir -p /datatest/mr/input
[hadoop@hadoop000 ~]$ hadoop fs -ls /datatest
Found 1 items
drwxr-xr-x - hadoop supergroup 0 2017-01-17 03:41 /datatest/mr
[hadoop@hadoop000 ~]$ hadoop fs -ls /datatest/mr
Found 1 items
drwxr-xr-x - hadoop supergroup 0 2017-01-17 03:41 /datatest/mr/input
4.上傳文件至HDFS
命令:hadoop fs -put 源路徑目標存放路徑
示例:將本地Linux文件系統目錄/home/hadoop/data/下的input.txt文件上傳至HDFS文件目錄/datatest下
[hadoop@hadoop000 ~]$ hodoop fs -put /home/hadoop/data/input.txt /datatest
[hadoop@hadoop000 ~]$ hodoop fs -ls /datatest
Found 2 items
-rw-r--r-- 1 hadoop supergroup 343 2017-01-17 03:44/datatest/input.txt
drwxr-xr-x -hadoop supergroup 0 2017-01-17 03:41/datatest/mr
5.從HDFS上下載文件
命令:hdfs dfs -get HDFS文件路徑本地存放路徑
示例:將剛剛上傳的input.txt文件下載到本地用戶的目錄下
[hadoop@hadoop000~]$ hdfs dfs -get /datatest/input.txt /home/hadoop/app
[hadoop@hadoop000~]$ ll
-rw-r--r--.1 hadoop hadoop 343 Jan 17 03:48 input.txt
6.查看HDFS上某個文件的內容
命令:hadoop fs-text(cat) HDFS上的文件存放路徑
示例:查看剛剛上傳的input.txt文件
[hadoop@hadoop000~]$ hodoop fs -text /datatest/input.txt
spark hadoop spark hadoop hive
hadoop kafka Hbase spark Hadoop
spark hive cisco ES hadoop flume
注意
text命令和cat命令都可以用來查看文件內容,這里只演示了text命令,cat命令請讀者自己動手操作。
7.統計目錄下各文件的大小
命令:hodoop fs -du 目錄路徑
示例:查看/data test/目錄下各個文件的大小
[hadoop@hadoop000 ~]$ hodoop fs -du /datatest/
96 96 /datatest/input.txt
0 0 /datatest/mr
注意
統計目錄下文件大小使用的單位是字節。
8.刪除HDFS上的某個文件或者文件夾
命令:hodoop fs -rm(r) 文件存放路徑
示例:刪除剛剛上傳的input.txt文件
[hadoop@hadoop000 ~]$ hodoop fs -rm /datatest/input.txt
Deleted /datatest/input.txt
[hadoop@hadoop000 ~]$ hodoop fs -ls /datatest/
Found 1 items
drwxr-xr-x -hadoop supergroup 0 2017-01-17 03:41/datatest/mr
在HDFS中刪除文件與刪除目錄所使用命令有區別,一個是-rm,表示刪除指定的文件或者空目錄;一個是-rmr,表示遞歸刪除指定目錄下的所有子目錄和文件。如下面的命令是刪除output下的所有子目錄和文件。
hodoop fs -rmr /test/output
注意
在生產環境中要慎用-rmr,容易引起誤刪除操作。
9.使用help命令尋求幫助
命令:hodoop fs -help 命令
示例:查看rm命令的幫助
[hadoop@hadoop000~]$hodoop fs-help rm
-rm[-f][-r|-R][-skipTrash]<src>...:
Delete all files that match the specified file pattern.Equivalent to the Unix
command"rm<src>"
-skipTrash option bypasses trash,if enabled,and immediately deletes<src>
-f If the file does not exist,do not display a diagnostic message or
modify the exit status to reflect an error.
-[rR] Recursively deletes directories
以上講解的命令是日常工作中使用頻次較高的,所以務必要熟練掌握。如果還想學習其他shell命令操作,可以訪問官網(http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/File System Shell.html)、使用help幫助或者在網絡上搜索,在此不再贅述。
2.2.2 使用Java API訪問
1.概述
除了可以使用HDFS shell的方式來訪問HDFS上的數據,Hadoop還提供了以Java API的方式來操作HDFS上的數據。我們實際開發的大數據應用都是以代碼的方式提交的,所以在代碼中使用API的方式來操作HDFS數據也必須掌握。下面介紹如何使用Java API對HDFS中的文件進行操作。
2.搭建開發環境
我們使用Maven來構建Java應用程序,所以需要添加maven的依賴包。
代碼2.1 Maven pom文件
<properties>
<project.build.source Encoding>UTF-8</project.build.source Encoding>
<hadoop.version>2.6.0-cdh5.7.0</hadoop.version>
</properties>
<dependencies>
<dependency>
<group Id>org.apache.hadoop</group Id>
<artifact Id>hadoop-common</artifact Id>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<group Id>org.apache.hadoop</group Id>
<artifact Id>hadoop-hdfs</artifact Id>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<group Id>junit</group Id>
<artifact Id>junit</artifact Id>
<version>4.10</version>
</dependency>
</dependencies>
注意
在執行單元測試之前,需要在$HADOOP_HOME/etc/hadoop/hdfs-site.xml中添加如下配置,并重啟HDFS集群。
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
3.單元測試的set Up和tear Down方法
在單元測試中,一般將初始化的操作放在set Up方法中完成,將關閉資源的操作放在tear Down方法中完成。那么我們在測試HDFS時,打開文件系統的操作就可以放在set Up中,而關閉文件系統的操作就可以放在tear Down中。
代碼2.2 單元測試set Up和tear Down方法
package com.kgc.bigdata.hadoop.hdfs.api;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.URI;
/ **
* HDFS Java API操作
*/
public class HDFSApp {
public static final String HDFS_PATH ="hdfs://hadoop000:8020";
Configuration configuration = null;
File System file System = null;
@Before
public void set Up() throws Exception{
System.out.println("HDFSApp.set Up()");
configuration = new Configuration();
file System = File System.get(new URI(HDFS_PATH), configuration);
}
@After
public void tear Down() throws Exception{
file System = null;
configuration = null;
System.out.println("HDFSApp.tear Down()");
}
}
4.使用Java API操作HDFS的常用操作
代碼2.3 Java API操作HDFS文件
/ **
*創建目錄
*/
@Test
public void mkdir() throws Exception {
file System.mkdirs(new Path("/hdfsapi/test"));
}
/ **
*創建文件
*/
@Test
public void create() throws Exception {
FSData Output Stream output = file System.create(new Path("/hdfsapi/test/a.txt"));
output.write("hello world".get Bytes());
output.flush();
output.close();
}
/ **
*重命名
*/
@Test
public void rename() throws Exception {
Path old Path = new Path("/hdfsapi/test/a.txt");
Path new Path = new Path("/hdfsapi/test/b.txt");
System.out.println(file System.rename(old Path, new Path));
}
/ **
*上傳本地文件到HDFS
*/
@Test
public void copyFromLocalFile() throws Exception {
Path src = new Path("/home/hadoop/data/hello.txt");
Path dist = new Path("/hdfsapi/test/");
fileSystem.copyFromLocalFile(src, dist);
}
/ **
* 查看某個目錄下的所有文件
*/
@Test
public void listFiles() throws Exception {
FileStatus[] listStatus = fileSystem.listStatus(new Path("/hdfsapi/test"));
for (FileStatus fileStatus : listStatus) {
String isDir=fileStatus.isDirectory()?"文件夾":"文件"; //文件/文件夾
String permission = fileStatus.getPermission().toString(); //權限
short replication = fileStatus.getReplication(); //副本系數
long len = fileStatus.getLen(); //長度
String path = fileStatus.getPath().toString(); //路徑
System.out.println(isDir + "\t" + permission + "\t" + replication + "\t" + len + "\t" + path);
}
}
/ **
* 查看文件塊信息
*/
@Test
public void getFileBlockLocations() throws Exception {
FileStatus fileStatus = fileSystem.getFileStatus(new Path("/hdfsapi/test/b.txt"));
BlockLocation[] blocks = fileSystem.getFileBlockLocations(fileStatus, 0, fileStatus.getLen());
for (BlockLocation block : blocks) {
for (String host : block.getHosts()) {
System.out.println(host);
}
}
}