1.本文目的

通过解析客户端创建文件流程,认知hadoop的HDFS系统的一些功能和概念。


2.主要概念

2.1 NameNode(NN)

HDFS系统核心组件,负责分布式文件系统的名字空间管理、INode表的文件映射管理。如果不开启备份/故障恢复/Federation模式,一般的HDFS系统就只有1个NameNode,当然这样是存在单点故障隐患的。

NN管理两个核心的表:文件到块序列的映射、块到机器序列的映射。

第一个表存储在磁盘中,第二表在NN每次启动后重建。

2.2 NameNodeServer(NNS)

负责NN和其它组件的通信接口的开放(IPC、http)等。

NN通过客户端协议(ClientProtocol)和客户端通信,通过数据节点协议(DataNodeProtocol)和DN通信。

2.3 FSNameSystem

管理文件系统相关,承担了NN的主要职责。

2.4 DataNode(DN)

分布式文件系统中存放实际数据的节点,存储了一系列的文件块,一个DFS部署中通常有许多DN。

DN和NN,DN和DN,DN和客户端都通过不同的IPC协议进行交互。

通常,DN接受来自NN的指令,比如拷贝、删除文件块。

客户端在通过NN获取了文件块的位置信息后,就可以和DN直接交互,比如读取块、写入块数据等。

DN节点只管理一个核心表:文件块到字节流的映射。

在DN的生命周期中,不断地和NN通信,报告自己所存储的文件块的状态,NN不直接向DN通信,而是应答DN的请求,比如在DN的心跳请求后,回复一些关于复制、删除、恢复文件块的命令(comands)。

DN和外界通信的接口<host:port>会报告给NN,想和此DN交互的客户端或其它DN可以通过和NN通信来获取这一信息。

2.5 Block

文件块,hadoop文件系统的原语,hadoop分布式文件系统中存储的最小单位。一个hadoop文件就是由一系列分散在不同的DataNode上的block组成。

2.6 BlockLocation

文件块在分布式网络中的位置<host:port>,也包括一些块的元数据,比如块是否损坏、块的大小、块在文件中的偏移等。

2.7 DFSClient

分布式文件系统的客户端,用户可以获取一个客户端实例和NameNode及DataNode交互,DFSClient通过客户端协议和hadoop文件系统交互。

2.8 Lease

租约,当客户端创建或打开一个文件并准备进行写操作,NameNode会维护一个文件租约,以标记谁正在对此文件进行写操作。客户端需要定时更新租约,否则当租约过期,NN会关闭文件或者将文件的租约交给其它客户端。

2.9 LeaseRenewer

续约管控线程,当一个DFSClient调用申请租约后,如果此线程尚未启动,则启动,并定期向NameNode续约。


三.创建一个文件

当hadoop的分布式集群启动之后,可以通过FS或Shell来创建文件,FS创建文件的命令如下:

//cluser是hadoop集群,通过fs和集群文件系统交互
final DistributedFileSystem fs = cluster.getFileSystem();
// 要创建的文件名
final Path tmpFile1 = new Path("/tmpfile1.dat"); //创建文件
public static void createFile(FileSystem fs, Path fileName, long fileLen,
short replFactor, long seed) throws IOException {
if (!fs.mkdirs(fileName.getParent())) {
throw new IOException("Mkdirs failed to create " +
fileName.getParent().toString());
}
FSDataOutputStream out = null;
try {
out = fs.create(fileName, replFactor);
byte[] toWrite = new byte[1024];
Random rb = new Random(seed);
long bytesToWrite = fileLen;
while (bytesToWrite>0) {
rb.nextBytes(toWrite);
int bytesToWriteNext = (1024<bytesToWrite)?1024:(int)bytesToWrite; out.write(toWrite, 0, bytesToWriteNext);
bytesToWrite -= bytesToWriteNext;
}
out.close();
out = null;
} finally {
IOUtils.closeStream(out);
}
}

四、流程分析

创建一个名为tmpfile1.dat的文件,主要流程如下:


4.1 发送创建文件的请求(CreateFile)

客户端向NN发起请求,获取文件信息,NN会在缓存中查找是否存在请求创建的文件项(file entry),如果没找到,就在NameSystem中创建一个新的文件项:

块管理器(BlockManager)检查复制因子是否在范围内,如果复制因子过小或过大就会异常。

同时会进行权限验证、加密、安全模式检测(如果在安全模式不能创建文件)等,并记录操作日志和事件日志,然后向客户端返回文件状态。


4.2 申请文件租用权(beginFileLease)

客户端取得文件状态后,对文件申请租用(lease),如果租用过期,客户端将无法再继续对文件进行访问,除非进行续租。


4.3 数据流管控线程启动(DataStreamer & ResponseProcessor)

DataStreamer线程负责数据的实际发送:

当数据队列(Data Queue)为空时,会睡眠,并定期苏醒以检测数据队列是否有新的数据需要发送、Socket套接字是否超时、是否继续睡眠等状态。

ResponseProcessor负责接收和处理pipeline下游传回的数据接收确认信息pipelineACK


4.4 发送添加块申请并初始化数据管道(AddBlock & Setup Pipeline)

当有新的数据需要发送,并且块创建阶段处于PIPELINE_SETUP_CREATE,DataStreamer会和NameNode通信,调用AddBlock方法,通知NN创建、分配新的块及位置,NN返回后,初始化Pipeline和发送流。


4.5 DataNode数据接收服务线程启动(DataXceiverServer & DataXceiver)

当DataNode启动后,其内部的DataXceiverServer组件启动,此线程管理向其所属的DN发送数据的连接建立工作,新连接来时,DataXceiverServer会启动一个DataXceiver线程,此线程负责流向DN的数据接收工作。


4.6 在Pipeline中处理数据的发送和接收

客户端在获取了NameNode分配的文件块的网络位置之后,就可以和存放此块的DataNode交互。

客户端通过SASL加密方式和DN建立连接,并通过pipeline来发送数据。


4.6.1 从pipeline接收数据

pipeline由数据源节点、多个数据目的节点组成,请参考上面的流程图。

位于pipeline中的第一个DataNode会接收到来自客户端的数据流,其内部DataXceiver组件,通过读取操作类型(OP),来区分进行何种操作,如下所示:

  protected final void processOp(Op op) throws IOException {
switch(op) {
case READ_BLOCK:
opReadBlock();
break;
//本例中将会使用WRITE_BLOCK指令
case WRITE_BLOCK:
opWriteBlock(in);
break; //略... default:
throw new IOException("Unknown op " + op + " in data stream");
}
}

如果OP是WRITE_BLOCK,调用写数据块的方法,此方法会根据数据源是客户端还是其他DataNode、块创建的阶段等条件进行不同的逻辑。


4.6.2 数据在pipeline中流动

在本例中,第一个收到数据的DN会再启动一个blockReceiver线程,以接收实际的块数据,在本地保存了块数据后,其负责向pipeline中的后续DN继续发送块数据。

每次向下游DN节点发送数据,标志着数据目的节点的targets数组都会排除自身,这样,就控制了pipeline的长度。

下游收到块数据的DN会向上游DN或者客户端报告数据接收状态。

这种链式或者序列化的数据转移方式,就像数据在管道中从上游流向下游,所以这种方式称作pipeline


4.6.3 pipeline的生命周期



在本例中:

DataStreamer线程启动后,pipeline进入PIPELINE_SETUP_CREATE阶段;

数据流初始化后,pipeline进入DATA_STREAMING阶段;

数据发送完毕后,pipeline进入PIPELINE_CLOSE阶段。

客户端在DataStreamer线程启动后,同时启动了一个ResponseProcessor线程,此线程用于接收pipeline中来自下游节点的数据接收状态报告pipelineACK,同时此线程和DataStreamer线程协调管理pipeline状态。

当DataStreamer向pipeline发送数据时,会将发送的数据包(packet)从数据队列(Data Queue)中移除,并加入数据确认队列(Ack Queue):

//DataStreamer发送数据后,将dataQueue的第一个元素出队,并加入ackQueue
one = dataQueue.getFirst();
dataQueue.removeFirst();
ackQueue.addLast(one);

而当ResponseProcessor收到下游的pipelineAck后,据此确认信息来判断pipeline状态,是否需要重置和重新调整。如果确认信息是下游节点数据接收成功了,就将确认队列(AckQueue)的第一个数据包删除。

//ResponseProcessor收到成功的Ack,就将ackQueue的第一个包移除
lastAckedSeqno = seqno;
ackQueue.removeFirst();
dataQueue.notifyAll();

通过这样的方式,DataStreamer可以确认数据包是否发送成功,也可以确认全部的数据包是否已经发送完毕。

显然,当AckQueue空了,并且已经发送的数据包是块里的最后一个包,数据就发送完毕了。

发送完毕的判断如下所示:

          if (one.lastPacketInBlock) {
// wait for all data packets have been successfully acked
synchronized (dataQueue) {
while (!streamerClosed && !hasError &&
ackQueue.size() != 0 && dfsClient.clientRunning) {
try {
// wait for acks to arrive from datanodes
dataQueue.wait(1000);
} catch (InterruptedException e) {
DFSClient.LOG.warn("Caught exception ", e);
}
}
}
if (streamerClosed || hasError || !dfsClient.clientRunning) {
continue;
}
//在没有错误的情况下,AckQueue为空,并且包one是block的最后一个包,数据就发送完了
stage = BlockConstructionStage.PIPELINE_CLOSE;
}

4.7 发送文件操作完成请求(completeFile)

客户端向NameNode发送completeFile请求:

NN收到请求后,验证块的BlockPoolId是否正确,接着对操作权限、文件写锁(write lock)、安全模式、租约、INode是否存在、INode类型等等进行验证,最后记录操作日志并返回给客户端。


4.8 停止文件租约(endFileLease)

客户端在完成文件写操作后,调用leaseRenewer(LR)实例,从LR管理的续约文件表中删除此文件,表明不再更新租约,一段时间后,租约在NN端自然失效。


【Hadoop】HDFS - 创建文件流程详解的更多相关文章

  1. Linux常用命令 - 五种创建文件命令详解

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 创建文 ...

  2. 超详细的HDFS读写流程详解(最容易理解的方式)

    HDFS采用的是master/slaves这种主从的结构模型管理数据,这种结构模型主要由四个部分组成,分别是Client(客户端).Namenode(名称节点).Datanode(数据节点)和Seco ...

  3. Scrapy框架——介绍、安装、命令行创建,启动、项目目录结构介绍、Spiders文件夹详解(包括去重规则)、Selectors解析页面、Items、pipelines(自定义pipeline)、下载中间件(Downloader Middleware)、爬虫中间件、信号

    一 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前Scrapy的用途十分广泛,可 ...

  4. iOS 组件化流程详解(git创建流程)

    [链接]组件化流程详解(一)https://www.jianshu.com/p/2deca619ff7e

  5. Hadoop 新 MapReduce 框架 Yarn 详解

    Hadoop 新 MapReduce 框架 Yarn 详解: http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-yarn/ Ap ...

  6. C++的性能C#的产能?! - .Net Native 系列《二》:.NET Native开发流程详解

    之前一文<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥> 获得很多朋友支持和鼓励,也更让我坚定做这项技术的推广者,希望能让更多的朋友了解这项技术,于是先从官方 ...

  7. git概念及工作流程详解

    git概念及工作流程详解 既然我们已经把gitlab安装完毕[当然这是非必要条件],我们就可以使用git来管理自己的项目了,前文也多多少少提及到git的基本命令,本文就先简单对比下SVN与git的区别 ...

  8. Hadoop深入学习:MapTask详解

    转自:http://flyingdutchman.iteye.com/blog/1878775#bc2337280 Hadoop深入学习:MapTask详解 博客分类: Hadoop MapTask执 ...

  9. FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

随机推荐

  1. 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树

    [题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...

  2. HDU 1229 还是A+B(A+B陶冶情操)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1229 解题报告:A+B #include<cstdio> int main() { int ...

  3. linux磁盘已满,文件占用情况

    du -sh /data0/* 如上,/data0/* 表示查看data0文件夹下各个目录的磁盘占用情况 df -h 查看总的磁盘占比

  4. 『Numpy学习指南』Matplotlib绘图

    数据生成: import numpy as np import matplotlib.pyplot as plt func = np.poly1d(np.array([,,,])) func1 = f ...

  5. C语言字节对齐 __align(),__attribute((aligned (n))),#pragma pack(n)【转】

    转自:https://www.cnblogs.com/ransn/p/5081198.html 转载地址 : http://blog.csdn.net/21aspnet/article/details ...

  6. 利用backtrace和ucontex定位segment错误【转】

    转自:https://blog.csdn.net/gqtcgq/article/details/53883546 C程序运行时,经常会碰到”segmentfault”错误.这是由于程序中非法访问内存导 ...

  7. mitmdump 屏蔽443错误

    mitmdump --ignore-hosts ".*443$" -s test.py

  8. 微信小程序调用接口返回数据或提交数据

    由于小程序发起网络请求需要通过 wx.request 文档地址 https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html 习 ...

  9. 2017-2018-2 20155225《网络对抗技术》实验一 PC平台逆向破解

    2017-2018-2 20155225<网络对抗技术>实验一 PC平台逆向破解 1.直接修改程序机器指令,改变程序执行流程 理清思路: 我们的目标文件是一个linux可执行文件,格式为E ...

  10. Java编程的逻辑 (76) - 并发容器 - 各种队列

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...