1 数据流
1.1 读取文件数据的剖析
为了知道客户端与HDFS,NameNode,DataNode交互过程中数据的流向,请看图3-2,这张图显示了读取文件过程中主要的事件顺序。
客户端通过调用FileSystem对象的open()方法打开一个希望从中读取数据的文件,对于HDFS来说,FileSystem是一个DistributedFileSystem的实例对象(图3-2 步骤1)。DistributedFileSystem远程调用名称节点(NameNode)得到文件开头几个块的位置。对于每一个块,名称节点返回包含这个块复本的所有数据节点(DataNode)的地址。进一步,这些数据节点会根据集群的网络拓扑结构按照距离客户端的远近进行排序。如果客户端本身是一个数据节点(例如一个MapReduce任务),而这个数据节点包含要读取的块的复本,则客户端会直接从本地读取。
DistributedFileSystem返回一个FSDataInputStream对象给客户端,用于从文件中读取数据。FSDataInputStream是一个输入流,支持文件寻位(seek)。FSDataInputStream里包装了一个DFSInputStream类,这个类支持数据节点和名称节点的I/O操作。
客户端调用read()方法从流中读取数据。DFSInputStream存储了文件中开头几个块所在的数据节点的地址。首先连接第一个块所在的最近的数据节点,数据从数据节点被读取到客户端,然后不断地从这个流中读取(步骤4)直接这个块数据被读完,然后DFSInputStream将会关闭到这个数据节点的连接,寻找下一个块所在的最近的数据节点(步骤5)。这一系列操作对客户端来说是透明的,它不用管。从客户端的角度来看,它仅仅是在读取一个连续的数据流。