首页 百科知识 源代码分析(三九)

源代码分析(三九)

时间:2022-09-22 百科知识 版权反馈
【摘要】:接下来当然是分析输出流了。getBuffer用户获得整个包,包括包头和数据。DataStreamer获取一个数据包,然后判断到DataNode的连接是否是打开的,如果不是,通过DFSOutputStream.nextBlockOutputStream打开到DataNode的连接,并启动ResponseProcessor线程。DataStreamer的循环在最后一个数据包写出去以后,会等待直到ackQueue队列为空,然后做清理动作,退出线程。如果是成功的应答,则删除在ackQueue的包,如果有错误,那么,记录出错的DataNode,并设置标志位。

接下来当然是分析输出流了。

处于继承体系的最上方是OutputStream,它实现了Closeable(方法close)和Flushable(方法flush)接口,提供了3个不同形式的write方法,这些方法的含义都很清楚。接下来的是FSOutputSummer,它引入了HDFS写数据时需要的计算校验和的功能。FSOutputSummer的write方法会调用write1,write1中计算校验和并将用户输入的数据拷贝到对象的缓冲区中,缓冲区满了以后会调用flushBuffer,flushBuffer最终调用还是虚方法的writeChunk,这个时候,缓冲区对应的校验和缓冲区对的内容都已经准备好了。通过这个类,HDFS可以把一个流转换成为DataNode数据接口上的包格式(前面我们讨论过这个包的格式,如下)。


mhtml:file://I:\技术文章下载\2010-4-23整理到notebook\Hadoop汇总2010-4-22\Hadoop源码分析\Hadoop<a href=源代码分析(三九)%20-%20-%20JavaEye技术网站.mht!http://caibinbupt.javaeye.com/upload/attachment/70042/c6593a6b-a95f-3af1-a348-bbdb42bc24cc.jpg">
 

 

DFSOutputStream继承自FSOutputSummer,是一个非常复杂的类,它包含了几个内部类。我们先分析Packet,其实它对应了上面的数据包,有了上面的图,这个类就很好理解了,它的成员变量和上面数据块包含的信息基本一一对应。构造函数需要的参数有pktSize,包的大小,chunksPerPkt,chunk的数目(chunk是一个校验单元)和该包在Block中的偏移量offsetInBlock。writeData和writeChecksum用于往缓冲区里写数据/校验和。getBuffer用户获得整个包,包括包头和数据。

DataStreamer和ResponseProcessor用于写包/读应答,和我们前面讨论DataNode的Pipe写时类似,客户端写数据也需要两个线程,下图扩展了我们在讨论DataNode处理写时的示意图,包含了客户端:


mhtml:file://I:\技术文章下载\2010-4-23整理到notebook\Hadoop汇总2010-4-22\Hadoop源码分析\Hadoop源代码分析(三九)%20-%20-%20JavaEye技术网站.mht!http://caibinbupt.javaeye.com/upload/attachment/70039/d6e34094-0412-381e-a7a9-6d9e54851caa.jpg
 

 

DataStreamer启动后进入一个循环,在没有错误和关闭标记为false的情况下,该循环首先调用processDatanodeError,处理可能的IO错误,这个过程比较复杂,我们在后面再讨论。

接着DataStreamer会在dataQueue(数据队列)上等待,直到有数据出现在队列上。DataStreamer获取一个数据包,然后判断到DataNode的连接是否是打开的,如果不是,通过DFSOutputStream.nextBlockOutputStream打开到DataNode的连接,并启动ResponseProcessor线程。

DataNode的连接准备好以后,DataStreamer获取数据包缓冲区,然后将数据包从dataQueue队列挪到ackQueue队列,最后通过blockStream,写数据。如果数据包是最后一个,那么,DataStreamer将会写一个长度域为0的包,指示DataNode数据传输结束。

DataStreamer的循环在最后一个数据包写出去以后,会等待直到ackQueue队列为空(表明所有的应答已经被接收),然后做清理动作(包括关闭socket连接,ResponseProcessor线程等),退出线程。

ResponseProcessor相对来说比较简单,就是等待来自DataNode的应答。如果是成功的应答,则删除在ackQueue的包,如果有错误,那么,记录出错的DataNode,并设置标志位。


免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈