标签:
杂谈 |
from:
三、文件的写入
下面解析向hdfs上传一个文件的过程。
3.1、客户端上传一个文件到hdfs,一般会调用DistributedFileSystem.create,其实现如下:
|
|
其最终生成一个FSDataOutputStream用于向新生成的文件中写入数据。其成员变量dfs的类型为DFSClient,DFSClient的create函数如下:
|
|
其中构造了一个DFSOutputStream,在其构造函数中,同过RPC调用NameNode的create来创建一个文件。
当然,构造函数中还做了一件重要的事情,就是streamer.start(),也即启动了一个pipeline,用于写数据,在写入数据的过程中,我们会仔细分析。
|
|
NameNode的create函数调用namesystem.startFile函数,其又调用startFileInternal函数,实现如下:
|
|
下面轮到客户端向新创建的文件中写入数据了,一般会使用FSDataOutputStream的write函数,最终会调用DFSOutputStream的writeChunk函数:
按照hdfs的设计,对block的数据写入使用的是pipeline的方式,也即将数据分成一个个的package,如果需要复制三分,分别写入DataNode 1, 2, 3,则会进行如下的过程:
首先将package 1写入DataNode 1 然后由DataNode 1负责将package 1写入DataNode 2,同时客户端可以将pacage 2写入DataNode 1 然后DataNode 2负责将package 1写入DataNode 3, 同时客户端可以讲package 3写入DataNode 1,DataNode 1将package 2写入DataNode 2 就这样将一个个package排着队的传递下去,直到所有的数据全部写入并复制完毕|
|
DataStreamer的run函数如下:
|
|
其中重要的一个函数是nextBlockOutputStream,实现如下:
|
|
locateFollowingBlock中通过RPC调用namenode.addBlock(src, clientName)函数
NameNode的addBlock函数实现如下:
|
|
FSNamesystem的getAdditionalBlock实现如下:
|
|
在分配了DataNode和block以后,createBlockOutputStream开始写入数据。
|
|
客户端在DataStreamer的run函数中创建了写入流后,调用blockStream.write将数据写入DataNode
DataNode的DataXceiver中,收到指令DataTransferProtocol.OP_WRITE_BLOCK则调用writeBlock函数:
|
|
BlockReceiver的receiveBlock函数中,一段重要的逻辑如下:
|
|
BlockReceiver的receivePacket函数如下:

加载中…