2021SC@SDUSC
DataNodeProtocol
public DatanodeRegistration register(DatanodeRegistration nodeReg ) throws IOException用于DataNode 向 NameNode 登记。输入和输出参数都是 DatanodeRegistration 在NameNode里,先是检查 该 DataNode 是否能接入到 NameNode,到准备应答,更新请求的 DataNodeID。从DataNodeMap得到对应的 DataNodeDescriptor,为 NodeS。从Host2NodesMap(主机名到DatanodeDescriptor 数组的映射)中获取DataNodeDescriptor,为 NodeN; 如果 NodeN!=null 同时 NodeS!=NodeN。 那么我们需要先在系统中删除NodeN,并在 Host2NodesMap 中删除 NodeN; 如果 NodeS 存在,表明前面已经注册过。则: 1.更新网络拓扑 2.更新心跳信息
public DatanodeCommand blockReport(DatanodeRegistration nodeReg, long[] blocks) throws IOExceptionDataNode 向 NameNode 报告它拥有的所有数据块,其中,参数 blocks 包含了数组化以后数据块的信息。FSNamesystem.processReport 处理这个请求。 调用 DatanodeDescriptor 的 reportDiff,将上报的数据块分成三组: 删除:其它情况; 加入:BlocksMap 中有数据块,但目前的 DatanodeDescriptor 上没有对应信息; 使无效:BlocksMap 中没有找到数据块。 对应需要加入的数据块,调用 addStoredBlock 方法: 1.从 BlocksMap 获取现在的信息,记为 storedBlock;如果为空,返回; 2.记录 block 和 DatanodeDescriptor 的关系; 如果现有数据块长度为 0,更新为上报的 block 的值; 如果现有数据块长度比新上报的长,invalidateBlock当前数据块; 如果现有数据块长度比新上报的小,那么会删除所有老的数据块(迓是通过 invalidateBlock),并更新BlocksMap 中数据块的大小信息。 对于标记为使无效的数据块,调用 addToInvalidates 方法,直接加到FSNamesystem 的成员变量 recentInvalidateSets 中:
public void blockReceived(DatanodeRegistration registration, Block blocks[], String[] delHints)DataNode 可以通过 blockReceived,向 NameNode 报告它最近接收到的数据块,同时给出如果数据块副本数太多时,可以删除数据块的节点(参数 delHints)。在 DataNode 中,这个信息是通过方法 notifyNamenodeReceivedBlock,记录到对应的列表中。
public void errorReport(DatanodeRegistration registration, int errorCode, String msg)向 NameNode 报告 DataNode 上的一个错误,如果错误是硬盘错,会删除该 DataNode,其它情况只是简单地记录收到一条出错信息。
public NamespaceInfo versionRequest() throws IOException;从 NameNode 上获叏取NamespaceInfo,该信息用于构造 DataNode 上的 DataStorage。
public void reportBadBlocks(LocatedBlock[] blocks) throws IOException报告错误的数据块。NameNode 会循环调用 FSNamesystem 的 markBlockAsCorrupt 方法。 本次对于Hadoop源码的分析实现了解读NameNode 上的 ClientProtocol 和 DatanodeProtocol中的代码,对于一些较难代码仍有不理解之处,还需多多学习。



