博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

namenode初分析:FSNamesystem<一>

Posted on 2012-04-21 00:00  Hadoop-scutmstcSIG  阅读(2165)  评论(0编辑  收藏  举报

    Written by 坏人,Hadoop Special Interest Group.


这学期加了hadoop源码的兴趣小组。和大家一起尝试着看hadoop中的源码。希望可以一起努力吧namenode初分析:FSNamesystem<一>

    好了,介绍一下本人的情况吧。没什么hadoop的基础,也发现自己看不下hadoop权威指南这本书。感觉这本书好像介绍怎么用hadoop的内容会比较多。而自己对这个没啥兴趣,自己主要想搞清楚这个可以处理海量数据的东西是怎么运作的,运作的原理,运作的实现方式等啥的,自己可以知道里面的一些东西,自己就满足了。实践啥的,现在没有啥硬件条件,所以就先弄懂他的原理呗。不过说起来hadoop中的很多东西其实都不是什么新东西,如里面的抽象的文件系统,里面的mapreduce过程感觉又和多处理器的一些原理相似,只不过抽象的层次不同。他的价值在更多的在于对大数据量的处理。自己的兴趣也在这一块,所以,你懂得。
    好了,说了那么多,开始对hadoop源码的第一部分:hdfs的解读吧。
    说起hdfs,就会提到这张比较经典HDFS文件写入过程(在《hadoop权威指南》中文版的71页,英文版的66页),它介绍了文件写入的大致过程(这个请读者自己看一下这个过程,我会当你知道这个大概的过程):

 

我们可以暂且将往HDFS里面写文件的过程暂且看成三个部分:namenode、datanode和DFSClient。我先从namenode入手看,各个击破吧。

 

    从老外的注释中,我们可以看到,namenode主要保存了两种信息:

 

     1)  filename->blocksequence (namespace)
     2)  block->machinelist ("inodes")

 

    但是这两部分主要都是由FSNamesystem完成,Namenode自己主要实现了三个通信接口:

 

  •    ClientProtocol:和客户端的通信
  •    DatanodeProtocol:和datanode的通信
  •    NamenodeProtocol:主要和second namenode的通信

 

    在实际的代码中,namenode还实现了两个接口:RefreshAuthorizationPolicyProtocol以及        RefreshUserMappingsProtocol,这两个IPC协议从名字上看应该是和用户认证有关系的。(PS:其实自己也很好奇,hadoop里面好像没啥用用户名和密码登录的过程,其对文件的保护好像就是根据文件的保护权限来限制,那个hadoop怎么在客户端连接过来的时候知道他是那个用户呢,怎么保证他就是那个用户呢,这个应该就和这几个IPC有关吧,仅猜测,接下来看到相应的源码就知道了)在实际的代码中,都会用到这几个协议,这几个协议交互的内容和交互的过程也是接下来的工作之一了。

 

    好了,让我们来看看FSNamenode是怎么实现将文件名对应到相应的几台datanode的过程了(上面两个过程的整合)。

 

    先列出来FSNamesytem中的主要的几个元素,:

 

         1、FSDirectory  dir;

 

         2、BlockMap blocksMap;

 

         3、CorruptReplicasMap   corruptReplicas;

 

         4、PendingReplicationBlocks pendingReplications

 

         5、UnderReplicatedBlocks neededReplications;

 

         6、TreeMap<String,Collection<Block>> resentInvalidateSets;

 

         7、TreeMap<String,Collection<Block>> excessReplicateMap;

 

         8、LeaseManager leaseManager;

 

         9、TreeMap<String,DatanodeDescriptor> datanodeMap;

 

   接下来的讲解我根据了另外一篇讲的不错的文章的结构来讲解,文章的最后我会附上参考网文的网址。

 

   首先看看filename--->block的实现。在运行时,这个对应关系一直放在内存中,也会放在硬盘中(fsimage文件和相应的edits.log文件)。

 

    在内存中,FSNamesystem靠保存一棵目录树维持文件的目录结构,用到如下几个数据结构(如下图),这几个结构都和linux的文件系统类似,INode作为基类保存文件或者目录的名称,INodeDirectory保存一个INode列表,表示目录下的文件或者目录,INodeFile保存文件的信息,如block号,文件权限等。这个没什么好详细介绍的。FSNamesystem中的dir会保存一个INodeDirectoryWithQuota类型的rootDir保存根节点。

 

在硬盘中,目录的信息以fsimage文件的形式存放,并将读入fsimage之后对文件结构的操作放在edits.log中。启动时,FSDirectory调用FSImage的LoadFSImage方法和LoadFSEdits方法将fsimage和edits.log读入内存,合成为新的目录结构。Secondnamenode会定期的读取namenode中的这两个文件,合成为一个新的fsimage文件,更新namenode中的fsimage(等一下会大概讲一下这个过程)。

     硬盘上的fsimage的结构在网上盛传着一张“淘宝师兄画的图”。没找到出处,先直接拿过来借用一下。

 

 

 

 

  • imgVersion:image版本号
  • namespaceID:命名空间ID,生命周期内不会变。主要是要和datanode注册时使用的registrationID相同就行了。
  • numFiles:文件和目录的数目,你懂得。
  • genStamp:时间戳,暂时还不知道为啥要生成这个时间戳。
  • Path:你懂得,文件或者目录的路径名
  • replicas:记录namenode知道这个文件的副本数,这个参数对目录没用(目录为0)。
  • mtime:make time
  • atime:access time
  • blocksize:目录的该参数为0,记录block大小
  • numBlock:block数目,目录此参数为-1
  • nsQuota和dsQuota:这两个参数默认为-1,暂时还不知道这两个参数的含义。
  • username、group和perm:记录文件的用户名,组名,权限

   如果是文件的话,后面会有numBlock个<blockid,numbytes,genStamp>数据。

   再说说block--->datanode的关系,它通过BlocksMap类型的blocksMap元素保存在内存中。不在硬盘保存。它通过datanode的blockReport来收集构建。让datanode来告诉namenode哪一个datanode有什么block。
   BlocksMap中有一个GSet<Block,BlockInfo>的元素,这涉及到两个结构,Block和BlockInfo,我将这两个结构中比较重要的信息画出来,如下图:

 

 

 

这里面BlockInfo有一个比较重要的结构,就是Object[3] triplets。因为一个block可能在多个datanode中都有备份,有多少个备份就会有多少个BlockInfo,这些BlockInfo之间通过Object[3]这个结构中的第二和第三个元素串成一个双向链表的结构,而Block只需要对应第一个BlockInfo即可实现一对多的关系。(好像讲的有点乱。。。namenode初分析:FSNamesystem<一>大家凑活理解吧)

    说到这里,好像Namenode交给FSNamesystem该完成的任务已经靠前面结构中的dir和blocksMap这两个元素完成了。那还要其他元素干什么呢?

    好吧,一开始我也是这么想的。但是一个完整的文件系统需要处理出错,失效的block。同时还要处理一些对文件的锁机制(如防止两个用户对同一个文件的同时写入)等,还要记录datanode的一些信息(说了,namenode比较懒namenode初分析:FSNamesystem<一>)。这些靠上面贴出来的剩下的一些元素完成。鉴于这篇文章已经有点长了,所以我另起一篇。来继续介绍剩余的元素。