1.HDFS体系结构与基本概念
1.1.NameNode
(1)作用
是整个文件系统的管理节点,它维护着整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表,接受用户的操作请求。
(2)目录结构
在hdfs-default.xml中查看dfs.name.dir、dfs.name.edits.dir对应的代码如下所示:
- <property>
- <name>dfs.name.dir</name>
- <value>${hadoop.tmp.dir}/dfs/name</value>
- <description>Determines where on the local filesystem the DFS name node
- should store the name table(fsimage). If this is a comma-delimited list
- of directories then the name table is replicated in all of the
- directories, for redundancy. </description>
- </property>
- <property>
- <name>dfs.name.edits.dir</name>
- <value>${dfs.name.dir}</value>
- <description>Determines where on the local filesystem the DFS name node
- should store the transaction (edits) file. If this is a comma-delimited list
- of directories then the transaction file is replicated in all of the
- directories, for redundancy. Default value is same as dfs.name.dir
- </description>
- </property>
(3)查看方法
在Linux中通过命令行的方式查看
文件包括fsimage、edits以及fstime:
fsimage:元数据镜像文件,存储某一时段NameNode内存元数据信息;
edits:操作日志文件;
fstime:保存最近一次checkpoint的时间;
通过浏览器的方式查看
1.2.DataNode
(1)作用
提供真实文件数据的存储服务。
(2)Block类以及文件块介绍
通过Ctrl+Shift+T组合键查找“Block”类,必须是位于org.apache.hadoop.hdfs.protocol中
文件块(block):最基本的存储单位。对于文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block。HDFS默认Block大小是64MB,以一个256MB文件,共有256/64=4个Block.
说明:不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。
(3)Replication(副本)介绍
副本目的在于安全,正是因为集群环境的不可靠,所以才使用副本机制来保证数据的安全性;
副本的缺点在于会占用大量的存储空间,副本越多,占用的空间也会越多。但是相比丢失数据的风险,存储空间的花费是值得的。
副本数一般是三个,从hdfs-default.xml中可以查看:
(4)目录结构
从hdfs-default.xml中可以查看该文件在linux上存储位置:
(5)查看方法
启动服务后在浏览其中输入http://hadoop0:50075/即可访问,参考下图:
1.3.SecondaryNameNode
作用:合并 NameNode 中的 edits 到 fsimage 中。
执行过程:从NameNode上下载元数据信息(fsimage,edits),然后把二者合并,生成新的fsimage,在本地保存,并将其推送到NameNode,同时重置NameNode的edits.
合并原理:
默认在安装在NameNode节点上,但这样做不安全!
2.Java接口以及常用api
在 hadoop 的 HDFS 操作中,有个非常重要的 api,是 org.apache.hadoop.fs.FileSystem,
这是用户代码操作 HDFS 的直接入口,该类含有操作 HDFS 的各种方法,类似于 jdbc 中操作数据库的直接入口是 Connection 类。
2.1.HDFS之HelloWorld
- package mavshuang.helloworld;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.URL;
-
- import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
- import org.apache.hadoop.io.IOUtils;
-
- public class HelloWorldDemo {
-
- static final String INPUT_PATH = "hdfs://hadoop0:9000/helloworld";
-
- public static void main(String[] args) throws IOException {
-
- URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
- final URL url = new URL(INPUT_PATH);
- InputStream inputStream = url.openStream();
- IOUtils.copyBytes(inputStream, System.out, 1024, true);
- }
- }
2.2.对文件的操作
(1) FileSystem:用户代码操作HDFS时,是直接调用FileSystem的子类完成的
- private static FileSystem getFileSystem() throws IOException, URISyntaxException {
- return FileSystem.get(new URI("hdfs://hadoop0:9000/"), new Configuration());
- }
(2)HDFS的FileSystem之创建文件(夹)
参考代码:
-
- private static void mkDirs(final FileSystem fileSystem) throws IOException {
- boolean mkdirs = fileSystem.mkdirs(new Path("/test"));
- }
在Linux中演示效果:
(3)HDFS的FileSystem之上传文件
参考代码:
-
- private static void uploadFile(final FileSystem fileSystem) throws IOException, FileNotFoundException {
- FSDataOutputStream out = fileSystem.create(new Path(HDFS_PATH));
- IOUtils.copyBytes(new FileInputStream("C:/Windows/System32/drivers/etc/hosts"), out, new Configuration(), true);
- }
在Linux中演示效果:
(4)HDFS的FileSystem之下载文件
参考代码:
-
- private static void downloadFile(final FileSystem fileSystem) throws IOException {
- FSDataInputStream downloadFile = fileSystem.open(new Path(HDFS_PATH));
- IOUtils.copyBytes(downloadFile, System.out, new Configuration(), true);
- }
在Eclipse中演示效果:
(5)HDFS的FileSystem之查看文件状态
参考代码:
-
- private static void listStatus(final FileSystem fileSystem) throws IOException {
- FileStatus[] listStatus = fileSystem.listStatus(new Path("/"));
- for (FileStatus fileStatus : listStatus) {
- String isDir = fileStatus.isDir() ? "d" : "-";
- FsPermission permission = fileStatus.getPermission();
- short replication = fileStatus.getReplication();
- String owner = fileStatus.getOwner();
- String group = fileStatus.getGroup();
- long len = fileStatus.getLen();
- long modificationTime = fileStatus.getModificationTime();
- String path = fileStatus.getPath().toString();
- String line = isDir + "\t" + permission + "\t" + replication + "\t" + owner + "\t" + group + "\t" + len + "\t" + modificationTime + "\t" + path;
- System.out.println(line);
- }
- }
在Eclipse中演示效果:
(6)HDFS的FileSystem之删除文件
参考代码:
-
- private static void delete(final FileSystem fileSystem) throws IOException {
- fileSystem.delete(new Path("/test"),true);
- }
在Linux中演示效果: