基于Hadoop与Spark的大数据开发实战
上QQ阅读APP看书,第一时间看更新

任务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);

  }

 }

}