HDFS常用操作及编程实践
一、实验目的
- 熟悉HDFS的常用shell命令
- 配置eclipse编程环境
- 编程实现创建目录、上传文件、显示文件内容功能
- 创建一个约1.6M大小的文件,然后设置块大小(1048576)上传文件
- 编程实现按行读取HDFS文件,显示文件块信息,实现缓存功能
二、实验环境
- centos 6.5
- VMware Workstation
三、实验内容
先关闭集群
stop-dfs.sh
zkServer.sh stop
下次启动只要执行
start-dfs.sh
api客户端设置
1.解压hadoop-2.6.5.tar.gz ,hadoop-2.6.5-src.tar.gz 两个压缩文件 到一个干净的目录,比如d:\hadoop\usr
2.再创建hadoop-lib目录,将hadoop-2.6.5/share/hadoop各个目录里的jar包拷贝至这里(httpfs,kms除外)
3.配置windows环境变量 :
HADOOP_HOME=D:\hadoop\usr\hadoop-2.6.5
HADOOP_USER_NAME=root
path=%HADOOP_HOME%\bin;
4.将老师提供的bin目录的文件复制到d:\hadoop\usr\hadoop-2.6.5\bin(覆盖)
5.将bin里的hadoop.dll拷贝到c:\windows\System32
6.解压 eclipse-mars.rar,将hadoop-eclipse-plugin-2.6.0.jar(可视化插件)拷贝到d:\eclipse-mars\mars\plugins
- 启动hadoop (node01)
- 启动eclipse,project Explorer里有DFS Locations(如果没有出现,选择Java EE),小象图标(可视化控件)
- 配置eclipse:
菜单:
window-preferences-hadoop map/reduce
hadoop installation directory:d:\hadoop\usr\hadoop-2.6.5
new hadoop location(定位器)
location name: 任意取
DFS Master (不选 use M/R Master host)
Host:node01 #active的节点
port:8020(50070是浏览器的端口)
实验(创建一个目录/user/root)
- 新建一个Java项目
- 导入Jar包:
菜单:window-preferences-java-build path-user libraries
自定义一个jar包(比如hadoop_jars)
菜单:add external JARS
选择D:\hadoop\usr\hadoop-lib所有jar包
项目里导入hadoop_jars包 //右击项目名-build path-configure build path-java build path-libraries-add library-use library-hadoop_jars
项目里导入jUnit 4 //右击项目名-build path-configure build path-java build path-libraries-add library-jUnit 4
- 导入hdfs-site.xml,core-site.xml配置文件到项目的src目录(使用xftp传输)
- 新建一个class
Test20191909/src com.sxt.hdfs.test TestHDFS
四、出现的问题及解决方案
- jdk版本太高,导致eclipce安装失败,方案:重新安装低版本的jdk
五、实验结果
- 浏览器查看上传文件块信息截图
- HDFS命令,程序源代码,程序运行结果截图
代码:
Configuration conf=null; FileSystem fs=null; @Before public void conn() throws IOException{ conf=new Configuration(); fs=FileSystem.get(conf); } @Test public void mkdir() throws IOException{ Path path=new Path("/mytemp"); if(fs.exists(path)) fs.delete(path,true); fs.mkdirs(path); } @Test public void uploadFile() throws IOException{ // 文件的上传路径 Path path=new Path("/mytemp/jk.txt"); FSDataOutputStream fdos=fs.create(path); // 拿到磁盘文件 InputStream is=new BufferedInputStream(new FileInputStream("D:\\hadoop\\usr\\Test\\hadoop实操.txt")); IOUtils.copyBytes(is,fdos,conf,true); } //在远端上传root/software/test.txt //hdfs dfs -D dfs.blocksize=1048576 -put test.txt @Test public void readFile() throws IOException{ Path path=new Path("/user/root/test.txt"); FileStatus file=fs.getFileStatus(path); BlockLocation[] blks=fs.getFileBlockLocations(file, 0, file.getLen()); // 遍历数组 for(BlockLocation blk:blks){ System.out.println(blk); } //读取文件 FSDataInputStream fdis=fs.open(path); System.out.println((char)fdis.readByte()); System.out.println((char)fdis.readByte()); System.out.println((char)fdis.readByte()); System.out.println((char)fdis.readByte()); System.out.println((char)fdis.readByte()); package com.sxt.hdfs.test; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.BlockLocation; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; public class TestHDFS { Configuration conf=null; FileSystem fs=null; @Before public void conn() throws IOException{ conf=new Configuration(); fs=FileSystem.get(conf); } @Test public void mkdir() throws IOException{ Path path=new Path("/mytemp"); if(fs.exists(path)) fs.delete(path,true); fs.mkdirs(path); } @Test public void uploadFile() throws IOException{ // 文件的上传路径 Path path=new Path("/mytemp/jk.txt"); FSDataOutputStream fdos=fs.create(path); // 拿到磁盘文件 InputStream is=new BufferedInputStream(new FileInputStream("D:\\hadoop\\usr\\Test\\hadoop实操.txt")); IOUtils.copyBytes(is,fdos,conf,true); } //上传root/software/test.txt //hdfs dfs -D dfs.blocksize=1048576 -put test.txt @Test public void readFile() throws IOException{ Path path=new Path("/user/root/test.txt"); FileStatus file=fs.getFileStatus(path); BlockLocation[] blks=fs.getFileBlockLocations(file, 0, file.getLen()); // 遍历数组 for(BlockLocation blk:blks){ System.out.println(blk); } //读取文件 FSDataInputStream fdis=fs.open(path); System.out.println((char)fdis.readByte()); System.out.println((char)fdis.readByte()); System.out.println((char)fdis.readByte()); System.out.println((char)fdis.readByte()); System.out.println((char)fdis.readByte()); } @After public void close() throws IOException{ fs.close(); } } } @After public void close() throws IOException{ fs.close(); }
使用mkdir程序创建目录
使用uploadFile程序上传文件
在远端上传root/software/test.txt
hdfs dfs -D dfs.blocksize=1048576 -put test.txt
使用readFile程序获取节点信息
六、实验思考题
- 端口号9000和50070的区别?
- 9000端口通常用于HDFS的通信,即Hadoop分布式文件系统的通信端口。在Hadoop配置中,HDFS使用9000端口进行数据通信。
- 50070端口一般用于Hadoop集群的Web界面,是Hadoop的NameNode节点的Web UI端口,可以通过浏览器访问该端口查看Hadoop集群的状态以及文件系统的相关信息。
编程中你用到了哪些Java对象?
在你的Java程序中,主要使用了以下Java对象:
- Configuration:Hadoop配置对象,用于管理Hadoop的配置信息。
- FileSystem:Hadoop的文件系统抽象类,用于与HDFS进行交互。
- Path:表示Hadoop中的路径对象,用于指定文件或目录的路径。
- FSDataOutputStream:用于向HDFS写入数据的输出流对象。
- InputStream:Java标准库中的输入流,用于读取本地文件的数据。
- FileStatus:表示文件状态的对象,包括文件大小、块信息等。
- BlockLocation:表示文件块在HDFS上的位置信息。
- FSDataInputStream:用于从HDFS读取数据的输入流对象。
- hadoop fs、hadoop dfs、hdfs dfs的区别?
hadoop fs
是Hadoop提供的一个通用文件系统操作命令,可以用来操作不同类型的文件系统,默认情况下会映射到HDFS文件系统。hadoop dfs
是Hadoop早期版本提供的命令,用于操作HDFS文件系统,现在已经废弃,推荐使用hadoop fs
命令代替。hdfs dfs
是Hadoop当前版本推荐的操作HDFS文件系统的命令,是最新版本中用于操作HDFS的命令,推荐使用这个命令进行HDFS文件系统的管理和操作。
atus:表示文件状态的对象,包括文件大小、块信息等。
- BlockLocation:表示文件块在HDFS上的位置信息。
- FSDataInputStream:用于从HDFS读取数据的输入流对象。
- hadoop fs、hadoop dfs、hdfs dfs的区别?
hadoop fs
是Hadoop提供的一个通用文件系统操作命令,可以用来操作不同类型的文件系统,默认情况下会映射到HDFS文件系统。hadoop dfs
是Hadoop早期版本提供的命令,用于操作HDFS文件系统,现在已经废弃,推荐使用hadoop fs
命令代替。hdfs dfs
是Hadoop当前版本推荐的操作HDFS文件系统的命令,是最新版本中用于操作HDFS的命令,推荐使用这个命令进行HDFS文件系统的管理和操作。