Hadoop---07HDFS 读 / 写 数据流程(面试重点)
Posted 别闹'
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop---07HDFS 读 / 写 数据流程(面试重点)相关的知识,希望对你有一定的参考价值。
文章目录
1. HDFS写数据
1.1 HDFS写数据流程
HDFS读写流程:
- HDFS客户端创建
DistributedFileSystem
(分布式文件系统)类的对象实例。【该对象中封装了与HDFS文件系统操作的相关方法】 - 调用
DistributedFileSystem对象
的create()
方法,通过RPC
请求NameNode
创建文件。
① NameNode执行各种检查判断: 目标文件是否存在、父目录是否存在、客户端是否具有创建文件的权限。
② 检查通过后返回FSDataOutputStream
输出流对象给客户端用于写数据 - 客户端通过
FSDataOutputStream
输出流开始写入数据
① NameNode根据网络拓扑挑选出一组DataNode用于存放数据,默认是3副本存储。
② DataStreamer将数据包流式传输到管道(pipeline)的第一个 DataNode,该DataNode存储数据包并将它发送到 pipeline 的第二个DataNode。同样的,第二个DataNode存储数据包并发送给第三个(也是最后一个)DataNode】 - 传输的反方向上,会通过
ACK
校验数据包传输是否成功 - 客户端完成数据写入后,在
FSDataOutputStream
输出流上调用close()
方法关闭 - 客户端
DsitributedFileSystem
告知NameNode
文件写入完成,等待NameNode
确认。
【因为NameNode已经知道文件由哪些块组成,因此仅需等待最小复制块即可成功返回。最小复制是由参数 dfs.namenode.replication.min 指定,默认是1。即只要有1个副本上传成功,NameNode就认为已经上传成功,如果其他DataNode有缺失的块,可以通过这个DataNode继续复制】
抓住几个点:
- NameNode收到请求后并不是立即响应,而是要检查:目标文件是否存在、父目录是否存在、客户端是否具有创建文件的权限。
- 进行分布式数据传输时,并不是并行的传输,而是串行并发的传输。
因为这样可以将客户端压力转到服务器端来,给用户更好的体验。
- ① 客户端要向DataNode写数据时,是以一种管道(pipeline)的方式。将文件块拆分成多个
64KB
的数据包(packet),多个数据包流水式并发的对同一个DataNode进行写入。
② 传输单元为64KB
,每个单元由若干个分组组成,每个分组为512B的数据 + 4B的校验位 = 516B
1.2 关于副本结点的选择流程
问:在前面说到写数据时,NameNode根据网络拓扑挑选出一组DataNode用于存放数据。那么NameNode是怎么挑选DataNode的?
答:假设副本数为3,则:
-
第一个副本在Client所在结点上;若客户机在集群外,则在集群中随机选一个(因为此时所有DataNode结点与Client距离相等)【保证效率】
节点距离的计算:两个节点到达最近的共同祖先的距离总和。
-
第二个副本在另一个机架上随机选一个结点。【保证可靠】
-
第三个副本在第二个副本所在机随机选一个。【保证效率】
2. HDFS读数据
HDFS读数据的整体流程:
-
HDFS客户端创建
DistributedFileSystem
(分布式文件系统)类的对象实例。 -
调用
DistributedFileSystem对象
的read()
方法,通过RPC
请求NameNode
读取文件。
① NameNode执行各种检查判断: 目标文件是否存在、父目录是否存在、客户端是否具有读取文件的权限。
② 检查通过后返回FSDataInputStream
输出流对象给客户端用于读数据 -
客户端通过
FSDataInputStream
输出流开始写入数据
① 首先选择哪个DataNode结点?两个因素距离最近, DataNode所在服务器负载均衡低
,然后从中读取第一个文件快blk_1
。
② 请求第二个文件块blk_2
时,是在已经读取完成了blk_1
之后才会发出该请求,是串行读,不是多线程并行。最后将读到的blk_2
数据追加到blk_1
末尾,就可以拼接成一个完整的文件。所以,我们在 hadoop 服务器上的data文件夹中找到hadoop存放数据的文件夹
$HADOOP_HOME/data/dfs/data/current/BP-xxxxxxx/current/finalized/subdir0/subdir0
,在里面将某个文件的几个blk_xxx
按顺序拼接,也能恢复出原文件。# 将blk_1的数据写入abc.txt cat blk_1 >> abc.txt # 将blk_2的数据追加到abc.txt cat blk_2 >> abc.txt # 此时就可以恢复出文件abc.txt
-
客户端读完数据后,在
FSDataInputStream
输出流上调用close()
方法关闭 -
客户端
DsitributedFileSystem
告知NameNode
文件读出完成。
以上是关于Hadoop---07HDFS 读 / 写 数据流程(面试重点)的主要内容,如果未能解决你的问题,请参考以下文章