HDFS(五)—— HDFS 文件上传的过程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a909301740/article/details/84454512

HDFS数据上传过程

一、客户端发送请求

客户端执行上传文件的命令:hdfs dfs -put a.avi /movie

二、DFSClient.java 创建 DistributedFileSystem

请求首先被 DFSClient.java 这个类获取到,由该类创建 DistributedFileSystem 对象。

三、建立 RPC 通信,获得 NameNode 的代理对象

DistributedFileSystem 建立与 NameNode 之间的 RPC 通信,并且得到一个 NameNode 的代理对象:NameNodeProxies

NameNodeProxies 是个复数,是因为我们为了保证 HA(高可用),会使用多个 NameNode 节点。

四、请求创建文件的元信息

由 NameNodeProxies 去请求 NameNode 创建文件的元信息。

五、创建文件的元信息

NameNode 创建文件的元信息,元信息的内容如下:

{
	"文件名" : "a.avi",
	"路径" : "/movie",
	"大小" : "160M",
	"数据块数量" : "2个",
	"数据块1位置" : "DN1, DN3, DN1",
	"数据块2位置" : "DN2, DN3, DN2"
}

关于数据块的位置,可以结合 机架感知 的相关知识去理解。

六、缓存元信息

元信息也就是我们之前提到的 fsimage 文件中的数据,由于文件的元信息经常会被用到,所以 HDFS 会将它们缓存在内存中,内存的默认大小是 1000M。

这个值可以在 hadoop-env.sh 文件中修改:

# The maximum amount of heap to use, in MB. Default is 1000.
#export HADOOP_HEAPSIZE=
#export HADOOP_NAMENODE_INIT_HEAPSIZE=""

七、缓存满了将云信息持久化

将元信息缓存在内存中可以大大提高效率,但是内存空间是有限的,内存满了怎么办?

HDFS 会使用 LRU 算法,将最近未被使用的元信息存储到 fsimage 文件中。

八、返回元信息

创建完元信息之后,NameNode 会将元信息返回给 DFSClient.java。

九、创建输出流

DFSClient 会创建一个输出流 =>FSDataOutputStream。

就像我们代码中所写的那样:

    @Test
    public void testUpLoad() throws Exception {
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://192.168.220.111:9000");

        FileSystem client = FileSystem.get(conf);

        // 构造一个输入流
        InputStream in = new FileInputStream("D:\\TestUpload.java");
        // 构造一个输出流,不存在目录则会创建
        OutputStream out = client.create(new Path("/tool/upload.java"));
        IOUtils.copyBytes(in, out, 1024);
    }

调用 create(new Path("/tool/upload.java"))方法获取到的输出流实际上是一个 FSDataOutputStream 对象。

十、上传第一个数据块

然后再通过 IO 操作上传数据到 DataNode。

IOUtils.copyBytes(in, out, 1024);

十一、根据冗余信息进行复制

为了保证数据的可用性,通过水平复制在各个 DataNode 之间复制数据。

十二、通过循环,上传所有数据块

循环操作,将剩余的数据块上传到 DataNode。

猜你喜欢

转载自blog.csdn.net/a909301740/article/details/84454512