2015年(9)
分类: HADOOP
2015-05-12 17:18:46
万事俱备,我们可以来分析NameNode 上的流程啦。 首先我们来看NameNode 上实现的ClientProtocol,客户端通过这个接口,可以对目录树进行操作,打开/关闭文件等。 getBlockLocations 用于确定文件内容的位置,它的输入参数为:文件名,偏移量,长度,返回值是一个LocatedBlocks 对象 (如下图),它携带的信息很多,大部分字段我们以前都讨论过。 getBlockLocations 直接调用NameSystem 的同名方法。NameSystem 中这样的方法首先会检查权限和对参数进行检查(如偏移量 和长度要大于0),然后再调用实际的方法。找LocatedBlocks 先找src 对应的INode,然后通过INode 的getBlocks 方法,可 以拿到该节点的Block 列表,如果返回为空,表明该INode 不是文件,返回null;如果Block 列表长度为0,以空的Block 数 组构造返回的LocatedBlocks。 如果Block 数组不为空,则通过请求的偏移量和长度,就可以把这个区间涉及的Block 找出来,对于每一个block,执行: 通过BlocksMap 我们可以找到它存在于几个DataNode 上(BlocksMap.numNodes 方法); 计算包含该数据块但数据块是坏的DataNode 的数目(通过NameSystem.countNodes 方法,间接访问CorruptReplicasMap 中的信息); 计算坏数据块的数目(CorruptReplicasMap.numCorruptReplicas 方法,应该和上面的数相等); 通过上面的计算,我们得到现在还OK 的数据块数目; 从BlocksMap 中找出所有OK 的数据块对应的DatanodeDescriptor(DatanodeInfo 的父类); 创建对应的LocatedBlock。 收集到每个数据块的LocatedBlock 信息后,很自然就能构造LocatedBlocks 对象。getBlockLocations 其实只是一个读的方法, 请求到了NameNode 以后只需要查表就行了。 create 方法,该方法用于在目录树上创建文件(创建目录使用mkdir),需要的参数比较多,包括文件名,权限,客户端名, 是否覆盖已存在文件,副本数和块大小。NameNode 的create 调用NameSystem 的startFile 方法(startFile 需要的参数 clientMachine 从线程局部变量获取)。 startFile 方法先调用startFileInternal 完成操作,然后调用logSync,等待日志写完后才返回。 startFileInternal 不但服务于startFile,也被appendFile 调用(通过参数append 区分)。方法的最开始是一堆检查,包括: 安全模式,文件名src 是否正确,权限,租约,replication 参数,overwrite 参数(对append 操作是判断src 指向是否存在 并且是文件)。租约检查很简单,如果通过FSDirectory.getFileINode(src)得到的文件是出于构造状态,表明有客户正在操 作该文件,这时会抛出异常AlreadyBeingCreatedException。 如果对于创建操作,会通过FSDirectory 的addFile 往目录树上添加一个文件并在租约管理器里添加一条记录。 对于append 操作,执行的是构造一个新的INodeFileUnderConstruction 并替换原有的节点,然后在租约管理器里添加一条记 录。 总的来说,最简单的create 流程就是在目录树上创建一个INodeFileUnderConstruction 对象并往租约管理器里添加一条记录。 我们顺便分析一下append 吧,它的返回值是LocatedBlock,比起getBlockLocations,它只需要返回数组的一项。appendFile 是NameSystem 的实现方法,它首先调用上面讨论的startFileInternal 方法(已经在租约管理器里添加了一条记录)然后写日 志。然后寻找对应文件INodeFile 中记录的最后一个block,并通过BlocksMap.getStoredBlock()方法得到BlockInfo,然后 再从BlocksMap 中获得所有的DatanodeDescriptor,就可以构造LocatedBlock 了。需要注意的,如果该Block 在需要被复制 的集合(UnderReplicatedBlocks)中,移除它。 如果文件刚被创建或者是最后一个数据块已经写满,那么append 会返回null,这是客户端需要使用addBlock,为文件添加数 据块。 更多精彩内容请关注: 关注超人学院微信:BJ-CRXY |