Hadoop分布式文件系统-HDFS
Hadoop自带一个称为HDFS的分布式文件系统,即Hadoop Distributed FileSystem。管理网络中跨多台计算机存储的文件系统称为分布式文件系统(distributed filesystem)。
参考资料
- 《Hadoop权威指南(第4版)》
目录
- HDFS的设计
- HDFS的概念
- 命令行接口
- Hadoop文件系统
- Java接口
- 数据流
- 通过distcp并行复制
HDFS的设计
支持超大文件
超大文件是指几百MB,几百GB,甚至是几百TB大小的文件。
2008年的时候yahoo将hadoop应用扩展到4000个节点,存储PB级别的数据
支持流式数据访问
HDFS构建思路:一次写入,多次读取是最高效的访问模式。
TODO 一次写入,多次读取和流式数据访问有什么关系?
支持商用硬件
并不需要昂贵且可靠的专用硬件,普通商用硬件即可。
不建议大量的小文件
HDFS所能存储的文件总数受限于namenode的内存大小。根据经验,每个文件,目录和数据块的存储信息大约占150个字节。
假设有一百万个文件,且每个文件占一个数据块,那至少需要300M内存。如果文件数量达十亿个时,那需要的就是高达300G内存。
不支持低时间延迟的数据访问
HDFS是为高吞吐量应用优化的,所以会以提高时间延迟来作为代价。
如果需要低延迟的访问需求,可以选择HBase。
不支持多用户写入,任意修改文件
HDFS中的文件写入只支持单个写入者,而且写操作总是以“只添加”方式在文件末尾写数据。
HDFS的概念
数据块
HDFS中块(block)的默认大小为128M,一般磁盘块大小为512字节,HDFS的块设置为这么大的原因主要是为了最小化寻址开销,块的大小设置还要考虑到对MapReduce中map任务的影响,因为map任务一般一次只处理一个块中的数据,所以块如果过大会导致任务数太少,影响性能。
与单一磁盘的文件系统不同的是,HDFS中小于一个块大小的文件不会占据整个块的空间。例如:一个1MB文件存储在一个128M块中时,文件只使用1MB的磁盘空间,而不是128M.
数据块概念带来的好处:
- 简化了存储子系统的设计。namenode和datanode的设计。
- 允许一个文件的大小大于网络中任意一个磁盘的容易
namenode和datanode
- namenode为管理节点,维护着文件系统树及整棵树内所有的文件和目录。记录每个文件中各个块所在的数据节点信息,但是不永久保存块的位置信息,因为系统启动时块的位置信息会根据数据节点信息重建。
- datanode为工作节点(也称数据节点),受客户端和namenode调度,根据需要存储并检索数据块,并且定期向namenode发送它们所存储的块的列表。
块缓存
datanode从磁盘中读取块,但对于访问频繁的文件,其对应的块可能被显式地缓存在datanode的内存中,以堆外块缓存的形式存在。
联邦HDFS
在hadoop2.X发行版本系列中引入的联邦HDFS允许系统通过添加namenode实现扩展,其中每个namenode管理文件系统命名空间的一部分。
例如,一个namenode管理/user目录下的所有文件,而另一个namenode管理/share目录下的所有文件
在联邦环境下,每个namenode维护一个命名空间卷(namespace volume),由命名空间的元数据和一个数据块池(block pool)组成,数据块池包含该命名空间下文件的所有数据块。
命名空间卷是互相独立的,两两之间并不互相通信。
HDFS的高可用
TODO
命令行接口
// 新建文件夹
hadoop fs -mkdir books
// 将文件复制到HDFS
hadoop fs -copyFromLocal /hgy/test.txt hdfs://xmasq223:9000/hgy/test.txt
// 将文件复制到本地
hadoop fs -copyToLocal hdfs://xmasq223:9000/hgy/test.txt /hgy/test1.txt
// 查看指定列表
hadoop fs -ls /hgy
提供三类权限:r-只读权限,w-写入权限,x-可执行权限,可执行权限可以忽略。
Hadoop文件系统
抽象类:FileSystem,实现类如下:
文件系统 | URI方案 | Java实现(都在org.apache.hadoop包中) | 描述 |
---|---|---|---|
Local | file | fs.LocalFileSystem | 使用客户端校验和的本地磁盘文件系统 |
HDFS | hdfs | hdfs.DistributedFileSystem | Hadoop的分布式文件系统。将HDFS设计成与MapReduce结合使用,可以实现高性能 |
WebHDFS | Webhadfs | ||
Secure WebHDFS | swebhadfs | ||
HAR | har | ||
View | viewfs | ||
FTP | ftp | ||
S3 | S3a | ||
Azure | wasb | ||
Swift | swift |
Java接口
package com.xmasq.demo;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import java.io.*;
import java.net.URI;
import java.util.Properties;
/**
* @author guoyu.huang
* @version 1.0.0
*/
public class Demo {
public static void main(String[] args) throws IOException {
Properties properties = System.getProperties();
properties.setProperty("HADOOP_USER_NAME", "root");
try {
String fileUrl = "hdfs://xmasq223:9000/hgy/newTest.txt";
addFile(fileUrl);
getByFileSystem(fileUrl);
delete(fileUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 添加文件及内容
*
* @param fileUrl
* @throws IOException
*/
public static void addFile(String fileUrl) throws IOException {
// 因为我使用阿里云内网,所以一定使用hostname进行访问
Configuration configuration = new Configuration();
configuration.set("dfs.client.use.datanode.hostname", "true");
FileSystem fileSystem = FileSystem.get(URI.create(fileUrl), configuration);
FSDataOutputStream out = fileSystem.create(new Path(fileUrl));
out.write("This is new test file.".getBytes());
out.close();
}
/**
* 删除文件
*
* @param fileUrl
* @throws IOException
*/
public static void delete(String fileUrl) throws IOException {
// 因为我使用阿里云内网,所以一定使用hostname进行访问
Configuration configuration = new Configuration();
configuration.set("dfs.client.use.datanode.hostname", "true");
FileSystem fileSystem = FileSystem.get(URI.create(fileUrl), configuration);
fileSystem.delete(new Path(fileUrl), true);
}
/**
* 读取数据
*
* @param fileUrl
* @throws IOException
*/
public static void getByFileSystem(String fileUrl) throws IOException {
// 因为我使用阿里云内网,所以一定使用hostname进行访问
Configuration configuration = new Configuration();
configuration.set("dfs.client.use.datanode.hostname", "true");
FileSystem fileSystem = FileSystem.get(URI.create(fileUrl), configuration);
FSDataInputStream in = fileSystem.open(new Path(fileUrl));
IOUtils.copyBytes(in, System.out, 4096, false);
}
}
数据流
文件读取
通过以上代码获得流程图
文件写入
通过以上代码获得流程图
一致模型
TODO
通过distcp并行复制
TODO
上一篇: PyTorch学习(5)—分类