标签:www 包含 rtl 大数据集 nal 流程分析 另一个 文件中 关闭
Hadoop 中有三大组件:HDFS、MapReduce、YARN,HDFS 负责大文件存储的问题,MapReduce 负责大数据计算,而 YARN 负责资源的调度,接下来的文章我会一一介绍这几个组件。今天我们先来聊聊 HDFS 的架构及文件的读写流程。
HDFS 设计的目的是为了存储大数据集的文件,因此一台服务器是应付不了的,我们需要一个集群来实现这个目标。当用户需要存储一个文件时,HDFS 会将这个文件切分为一个个小的数据块(在 2.x 的版本中,每个数据块默认大小为 128M),再对每个数据块进行存储,当所有的数据块存储成功之后,才表示这个数据存到 HDFS 中了。HDFS 还会对每个数据块进行备份操作,使系统具有高容错性。
了解了 HDFS 的设计目标之后,我们来看下它的总体架构,下面这张图是从 HADOOP 官网扣下来的,除了刚刚提到的数据块(Blocks),还有两个比较重要的角色:NameNode 和 DataNode。DataNode 即数据节点,顾名思义,它们是存储真实数据的节点(每个节点就是一台服务器)。而 NameNode 呢?它主要维护元数据信息,包括:
但是这里需要注意的是,NameNode 不会将每个数据块的地址信息持久化到磁盘中,这些信息会在 NameNode 启动之后从各个 DataNode 中获取并存放在内存中,因为从内存中读取数据比从磁盘中读取数据快得多,这无疑大大提高了客户端读取文件的性能。
不过,这张图并没有把 HDFS 中另一个重要的角色标出来 --- Secondary NameNode,这个家伙又是干什么的呢?这就不得不提到 HDFS 文件写入过程中涉及到的两个文件 --- fsimage 和 edits。fsimage 是 NameNode 启动时对整个文件系统的快照,edits 是在 NameNode 启动后,对整个系统的改动序列,在系统重启时,会将 edits 合并到 fsimage 文件上。由于 NameNode 会长时间运行,写入的数据量大时,edits 文件会变得很大,这就会出现下面这些问题:
为了解决上述问题,就出现了 Secondary NameNode。它会定时到 NameNode 中获取 edits 文件,并更新到 fsimage 上,一旦有新的 fsimage 文件,它就将其拷贝会 NameNode 上。NameNode 下次启动时直接使用这个 fsimage,省去了合并 fsimage 和 edits 文件的过程。这就是 Secondary NameNode 在 HDFS 中的作用。
接下来的读写流程我们会结合代码进行分析,使用 JAVA API 对 HDFS 进行操作非常简单,利用 maven 环境,在 pom.xml 中加入 hdaoop client 的依赖就可以使用 HDFS 的 API 了。
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>#{hadoop.version}</version>
</dependency>
HDFS 文件读取的的代码如下:
public static void main(String[] args) throws Exception{
Configuration conf = new Configuration();
/*
* hadoop 可以跟多种文件系统交互,根据下图,我们也可以看到 FileSystem 有多种实现
* 为了让 hadoop 知道是与什么文件系统进行交互的,我们需要在配置文件中指定。
*/
conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
String uri = "hdfs://hadoop-master:9000/e.txt";
// 获取文件系统,这里 FileSystem 具体实现为上面指定的 DistributedFileSystem
FileSystem fs = FileSystem.get(URI.create(uri), conf);
OutputStream out ;
FSDataInputStream in = null;
try {
out = new FileOutputStream("e.txt");
in = fs.open(new Path(uri));
// 读取文件到本地
byte[] buf = new byte[4096];
for(int bytesRead = in.read(buf); bytesRead >= 0; bytesRead = in.read(buf)) {
out.write(buf, 0, bytesRead);
}
} finally {
IOUtils.closeStream(in);
}
}
根据上述代码,我们也大致可以猜出 HDFS 读取文件的流程了:
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
String uri = "hdfs://192.168.1.150:9000/friend/test.txt";
FileSystem fs = FileSystem.get(URI.create(uri), conf);
InputStream in = null;
FSDataOutputStream out = null;
try {
in = new FileInputStream("e-friend.txt") ;
out = fs.create(new Path(uri));
byte[] buf = new byte[4096];
for(int bytesRead = in.read(buf); bytesRead >= 0; bytesRead = in.read(buf)) {
out.write(buf, 0, bytesRead);
}
} finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}
读写数据的代码相似,但是写数据的过程更加复杂,我们一步一步来看。
标签:www 包含 rtl 大数据集 nal 流程分析 另一个 文件中 关闭
原文地址:https://www.cnblogs.com/firepation/p/11405056.html