大数据程序员大数据技术

HDFS深度历险 之 从客户端逻辑看HDFS写入机制

2017-03-17  本文已影响486人  猴子顶呱呱

HDFS架构简介

Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。本文基于Hadoop 2.7.3源码,分析本地文件推送(新建/追加)到的HDFS客户端逻辑。

HDFS架构图
  1. HDFS架构主要包含两种类型的节点:NameNode和DataNode。
  2. NameNode,其实就是名字节点,其功能类似于我们常用的磁盘文件系统中的inode。对于HDFS而言,NameNode相当于“目录管理器”和“inode表”。
  3. NameNode保存两类关键的映射表:
  1. 对于Hadoop 2.7.3而言,一个DataBlock默认是128MB,所以一个文件可能需要N个DataBlock来存储,那么名字空间表很可能是一个文件名映射到一个DataBlock的数组。
  2. 关于这两张表如何协作定位文件:
  1. 客户端与NameNode、NameNode与DataNode的连接,全部都是通过ProtoBuf的RPC调用来实现的。关于ProtoBuf可以参考这里。例如,下面就是追加文件的append请求的RPC协议:
//摘自hadoop-hdfs-project/hadoop-hdfs/src/main/proto/ClientNamenodeProtocol.proto

//RPC请求
rpc append(AppendRequestProto) returns(AppendResponseProto);

//请求报文
message AppendRequestProto {
  required string src = 1;
  required string clientName = 2;
  optional uint32 flag = 3; // bits set using CreateFlag
}

//应答报文
message AppendResponseProto {
  optional LocatedBlockProto block = 1;
  optional HdfsFileStatusProto stat = 2;
}

HDFS写文件Pipeline机制

HDFS在对文件的写入方面,只允许数据追加到文件末尾,而不允许在文件中间修改文件。因为在文件中间修改文件,需要涉及文件锁、数据块之类的比较复杂的逻辑。

Hadoop的文件按照DataBlock分块,并以DataBlock为单位做冗余(负载均衡)。HDFS可以指定一个复制因子(replication),默认是保存3份,根据dfs.replication配置项配置。

下面分析HDFS写文件的Pipeline流程(蓝色线表示用于通讯,红色线表示数据的传输路线):

hadoop pipeline流程图

数据发送至此完成。

HDFS文件推送客户端

要把本地文件推送到HDFS,可以通过以下两个命令实现:

hadoop fs -appendToFile <localsrc> ... <dst>
hadoop fs -put [-f] [-p] [-l] <localsrc> ... <dst>

跟踪调用堆栈发现,这两个命令最终是调用DFSOutputStream.java中的代码实现文件的拷贝。

辅助发送的相关类和数据结构

这份代码里面包含了一些用于辅助发送的类:

还有一些保存发送数据相关信息的数据结构:

看完上面的数据结构,整个数据发送流程就很明显了:
<u>DFSOutputStream把数据组装成DFSPacket对象,放入dataQueue;然后等待发送线程DataStreamer发送到DataNode;DataStreamer发送之后,把DFSPacket对象移动到ackQueue,等待ACK线程ResponseProcessor在收到对应的ACK之后把该DFSPacket从队列移除。</u>

下面主要分析DFSOutputStream.java这个客户端代码的执行流程。

数据发送的主要流程

HDFS客户端数据发送流程.png
上一篇下一篇

猜你喜欢

热点阅读