bestjoe 发表于 2016-12-9 10:59:51

Hadoop源代码分析(二九)

  public boolean setReplication(String src,
                                      short replication
                                      ) throws IOException;
  setReplication,设置文件src的副本数为replication,返回值为boolean,在FSNameSystem中,调用方法setReplicationInternal,然后写日志。
  setReplicationInternal上来自然是检查参数了,然后通过FSDirectory的setReplication,设置新的副本数,并获取老的副本数。根据新旧数,决定删除/复制数据块。
  增加副本数通过调用updateNeededReplications,为了获取UnderReplicatedBlocks. update需要的参数,FSNameSystem提供了内部方法countNodes和getReplication,获得对应的数值(这两个函数都很简单)。
  proccessOverReplicatedBlock用于减少副本数,它被多个方法调用:
  
http://caibinbupt.iyunv.com/upload/attachment/62342/5a52c1e9-fba4-3e47-b87f-c722fbe695af.jpg
 
  
  主要参数有block,副本数,目标DataNode,源DataNode(用于删除)。proccessOverReplicatedBlock首先找出block所在的,处于非Decommission状态的DataNode的信息,然后调用chooseExcessReplicates。chooseExcessReplicates执行:
l           按机架位置,对DatanodeDescriptor进行分组;
l           将DataNode分为两个集合,分别是一个机架包含一个以上的数据块的和剩余的;
l           选择可以删除的数据块(顺序是:源DataNode,同一个机架上的,剩余的),把它加到recentInvalidateSets中。

  public void setPermission(String src, FsPermission permission
                                 ) throws IOException;
  setPermission,用于设置文件的访问权限。非常简单,首先检查是否有权限,然后调用FSDirectory.setPermission修改文件访问权限。
  
  public void setOwner(String src, String username, String groupname
      ) throws IOException;
    public void setTimes(String src, long mtime, long atime) throws IOException;
  public void setQuota(String path, long namespaceQuota, long diskspaceQuota)
                      throws IOException;
  setOwner,设置文件的文件主和文件组,setTimes,设置文件的访问时间和修改时间,setQuota,设置某路径的空间限额和空间额度,和setPermission类似,调用FSDirectory的对应方法,简单。
  
  public boolean setSafeMode(FSConstants.SafeModeAction action) throws IOException;
  前面我们已经介绍了NameNode的安全模式,客户端通过上面的方法,可以让NameNode进入(SAFEMODE_ENTER)/退出(SAFEMODE_LEAVE)安全模式或查询(SAFEMODE_GET)状态。FSNamesystem的setSafeMode处理这个命令,对于进入安全模式的请求,如果系统现在不处于安全模式,那么创建一个SafeModeInfo对象(创建的这个对象有别于启动时创建的那个SafeModeInfo,它不会自动退出,因为threshold=1.5f),这标志着系统进入安全模式。退出安全模式很简单,将safeMode赋空就可以啦。
  
  public FileStatus[] getListing(String src) throws IOException;
  分析完set*以后,我们来看get*。getListing对应于UNIX系统的ls命令,返回值是FileStatus数组,FileStatus的类图如下,它其实给出了文件的详细信息,如大小,文件主等等。其实,这些信息都存在INode*中,我们只需要把这些信息搬到FileStatus中就OK啦。FSNamesystem和FSDirectory中都有同名方法,真正干活的地方在FSDirectory中。getListing不需要写日志。
  
  
http://caibinbupt.iyunv.com/upload/attachment/62346/6a0a79ab-3d7b-34a0-a7a8-fe8379efee5c.jpg
  public long[] getStats() throws IOException;

  getStatus得到的是文件系统的信息,UNIX对应命令为du,它的实现更简单,所有的信息都存放在FSNamesystem对象里。
  
  public DatanodeInfo[] getDatanodeReport(FSConstants.DatanodeReportType type)
  throws IOException;
  getDatanodeReport,获取当前DataNode的状态,可能的选项有DatanodeReportType.ALL, IVE和DEAD。FSNamesystem的同名方法调用getDatanodeListForReport,通过HostsFileReader读取对应信息。
  
  public long getPreferredBlockSize(String filename) throws IOException;
  getPreferredBlockSize,返回INodeFile.preferredBlockSize,数据块大小。
  
  public FileStatus getFileInfo(String src) throws IOException;
  和getListing类似,不再分析。
  
    public ContentSummary getContentSummary(String path) throws IOException;
  得到文件树的一些信息,如下图:
 

http://caibinbupt.iyunv.com/upload/attachment/62344/b7c55064-0861-3963-bd32-b0d128ca2f2f.jpg
 
  public void metaSave(String filename) throws IOException;
  这个也很简单,它把系统的metadata输出/添加到指定文件上(NameNode所在的文件系统)。
页: [1]
查看完整版本: Hadoop源代码分析(二九)