Hadoop-0.20.0源代码分析(09)

通过前面,对Hadoop的org.apache.hadoop.fs包中内容进行分析,已经基本了解到,一个文件系统应该具备哪些基本要素和基本操作。最显著的一个特点就是,FileSystem文件系统是基于流式数据访问的,并且,可以基于命令行的方式来对文件系统的文件进行管理与操作。而且,基于FileSystem文件系统的抽象定义,我们可以了解到,继承自该抽象的一切具体实现的文件系统,都具有统一的文件访问接口。

对于HDFS(Hadoop Distributed FileSystem),同样也是基于FileSystem的抽象实现的,下面看org.apache.hadoop.hdfs包中的代码,该包中的类都是与一个基本的HDFS相关的。

先看继承自FileSystem的实现类DistributedFileSystem。该分布式文件系统是可配置的,在继承自FileSystem的配置的基础上,还有它专有的DFS配置文件,如下所示:

[java]  view plain copy
  1. static{  
  2.   Configuration.addDefaultResource("hdfs-default.xml");  
  3.   Configuration.addDefaultResource("hdfs-site.xml");  
  4. }  

第一个是DFS默认的配置文件,第二个是用户可以根据需要进行定制的配置选项,如果hdfs-site.xml中定义的属性在hdfs-default.xml中已经存在,会覆盖掉hdfs-default.xml中默认的属性值。

该类中有一个内部类DiskStatus,用来表示一个DistributedFileSystem文件系统中磁盘使用的统计信息,如下所示:

[java]  view plain copy
  1. public static class DiskStatus {  
  2.   private long capacity; // 总容量  
  3.   private long dfsUsed; // DFS使用量  
  4.   private long remaining; // 可用量  
  5.   public DiskStatus(long capacity, long dfsUsed, long remaining) {  
  6.     this.capacity = capacity;  
  7.     this.dfsUsed = dfsUsed;  
  8.     this.remaining = remaining;  
  9.   }  
  10.     
  11.   public long getCapacity() {  
  12.     return capacity;  
  13.   }  
  14.   public long getDfsUsed() {  
  15.     return dfsUsed;  
  16.   }  
  17.   public long getRemaining() {  
  18.     return remaining;  
  19.   }  
  20. }  

在DistributedFileSystem实现中,主要是通过其定义的  DFSClient dfs; 来完成文件系统FileSystem抽象的基本操作。DFSClient能够连接到Hadoop文件系统,执行基本的文件操作。对于HDFS的用户如果想要对HDFS执行指定的操作,必须获取到一个DistributedFileSystem实例,才能通过DistributedFileSystem内部的DFSClient来处理任务。

这里,先回顾一下HDFS的架构要点,以便能对HDFS有个深入的了解。

HDFS的架构采用master/slave模式,一个HDFS集群是由一个Namenode和多个Datanode组成。

在HDFS集群中,只有一个Namenode结点。Namenode作为HDFS集群的中心服务器,主要负责:

1、管理HDFS集群中文件系统的名字空间(Namespace),例如打开文件系统、关闭文件系统、重命名文件或者目录等;另外,对任何请求对文件系统名字空间或者属性进行修改的操作,都被Namenode记录下来。

2、管理客户端对HDFS集群中的文件系统中的文件的访问,实际上文件以块的形式存储在Datanode上,文件系统客户端向Namenode请求所要执行操作的文件块(该块存储在指定的Dadanode数据结点上),然后通过与Datanode结点交互来完成文件读写的操作。那么,文件系统客户端与Namenode交互的过程中,只有从Namenode中获取到了所请求的文件块所对应的Datanode结点,才能执行文件的读写操作。也就是说,Namenode结点还负责确定指定的文件块到具体的Datanode结点的映射关系。

3、管理Datanode结点的状态报告,包括Datanode结点的健康状态报告和其所在结点上数据块状态报告,以便能够及时处理失效的数据结点。

在HDFS集群中,一个Datanode结点可以存在多个,一般是一个结点上对应一个Datanode实例。Datanode数据结点进程的任务是:

1、负责管理它所在结点上存储的数据的读写。一般是文件系统客户端需要请求对指定数据结点进行读写操作,Datanode作为数据结点的服务进程来与文件系统客户端打交道。同时,是否需要执行对文件块的创建、删除、复制等操作,Datanode数据结点进程还要在Namenode的统一指挥调度下完成,当与Namenode交互过程中收到了可以执行文件块的创建、删除或复制操作的命令后,才开始让文件系统客户端执行指定的操作。具体文件的操作并不是Datanode来实际完成的,而是经过Datanode许可后,文件系统客户端进程来执行实际操作。

2、向Namenode结点报告状态。每个Datanode结点会周期性地向Namenode发送心跳信号和文件块状态报告,以便Namenode获取到工作集群中Datanode结点状态的全局视图,从而掌握它们的状态。如果存在Datanode结点失效的情况时,Namenode会调度其它Datanode执行失效结点上文件块的复制处理,保证文件块的副本数达到规定数量。

3、执行数据的流水线复制。当文件系统客户端从Namenode服务器进程获取到要进行复制的数据块列表(列表中包含指定副本的存放位置,亦即某个Datanode结点)后,会首先将客户端缓存的文件块复制到第一个Datanode结点上,此时并非整个块都复制到第一个Datanode完成以后才复制到第二个Datanode结点上,而是由第一个Datanode向第二个Datanode结点复制,……,如此下去完成文件块及其块副本的流水线复制。

通过上面的叙述,可以看到,在HDFS集群中,存在三个主要的进程:Namenode进程、Datanode进程和文件系统客户端进程,这三个进程之间都是基于Hadoop实现的RPC机制进行通信的,该IPC模型基于Client/Server模式进行通信。因此上述三个进程之间存在如下端到端通信与交互:

1、(Client)Datanode / Namenode(Server)

2、(Client)DFS Client / Namenode(Server)

3、(Client)DFS Client / Datanode(Server)

4、(Client)Datanode A / Datanode B(Server)

接下来,我们看DistributedFileSystem分布式文件系统的实现,首先看DistributedFileSystem是如何初始化的initialize方法:

[java]  view plain copy
  1. public void initialize(URI uri, Configuration conf) throws IOException {  
  2.   super.initialize(uri, conf); // 继承自FileSystem  
  3.   setConf(conf);  
  4.   
  5.   String host = uri.getHost(); // 根据URI获取到Namenode主机  
  6.   if (host == null) {  
  7.     throw new IOException("Incomplete HDFS URI, no host: "+ uri);  
  8.   }  
  9.   
  10.   InetSocketAddress namenode = NameNode.getAddress(uri.getAuthority()); //获取到Namenode的Socket地址  
  11.   this.dfs = new DFSClient(namenode, conf, statistics); // 构造一个DFSClient实例  
  12.   this.uri = NameNode.getUri(namenode);  
  13.   this.workingDir = getHomeDirectory();  
  14. }  

通过这个初始化的方法可以看到,一个DFSClient实例要想执行DFS上的任务,必须与Namenode建立连接,在与Namenode通信获取许可的情况下才能执行任务。

DistributedFileSystem类的定义基本操作,主要是从它与FilesSstem抽象类定义的不同操作来了解。如下所示:

[java]  view plain copy
  1. /**  
  2.  * 获取文件系统的磁盘使用情况统计数据 
  3.  */  
  4. public DiskStatus getDiskStatus() throws IOException {  
  5.   return dfs.getDiskStatus();  
  6. }  
  7.   
  8. /** 
  9.  * 设置安全模式状态 
  10.  */  
  11. public boolean setSafeMode(FSConstants.SafeModeAction action)   
  12. throws IOException {  
  13.   return dfs.setSafeMode(action);  
  14. }  
  15.   
  16. /** 
  17.  * 对文件系统名字空间映像进行保存  
  18.  */  
  19. public void saveNamespace() throws AccessControlException, IOException {  
  20.   dfs.saveNamespace();  
  21. }  
  22.   
  23. /** 
  24.  * 刷新主机列表   
  25.  */  
  26. public void refreshNodes() throws IOException {  
  27.   dfs.refreshNodes();  
  28. }  
  29.   
  30. /** 
  31.  *返回标识为失效状态的块副本的数目 
  32.  */  
  33. public long getCorruptBlocksCount() throws IOException {  
  34.   return dfs.getCorruptBlocksCount();  
  35. }  
  36.   
  37. /** 
  38.  * 返回每个Datanode结点的状态信息   
  39.  */  
  40. public DatanodeInfo[] getDataNodeStats() throws IOException {  
  41.   return dfs.datanodeReport(DatanodeReportType.ALL);  
  42. }  
  43.   
  44. /* 
  45.  * 请求Namenode结点,将文件系统元数据写入到指定文件pathname中,如果该文件已经存在,则追加写入。 
  46.  */  
  47. public void metaSave(String pathname) throws IOException {  
  48.   dfs.metaSave(pathname);  
  49. }  

可见,实际上还是通过org.apache.hadoop.hdfs.DFSClient来实现保存的操作的。还有一个用来报告块副本的校验和出错的方法:

[java]  view plain copy
  1. public boolean reportChecksumFailure(Path f, FSDataInputStream in, long inPos, FSDataInputStream sums, long sumsPos)  

目前实现是,如果某个文件块及其对应的块副本的校验和不匹配,只能够知道该文件块状态有问题,没有实现报告具体是哪个块副本出了问题。

一个分布式文件系统实例 ,是通过DFS Client来进行文件的创建、删除、复制等等操作的。因此,如果希望了解DFSClient如何执行这些操作的,就需要对DFSClient 的实现进行分析了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值