namenode任务线程之LeaseManager$Monitor

今天分析namenode里的后台任务线程LeaseManager$Monitor,租约管理器LeaseManager负责管理租约(对于租约的概念可以看我上一篇文章),需要定时查看那些过期的租约然后销毁他们,这个从Monitor的注释中也可以看的出

 

Java代码     收藏代码
  1. * Monitor checks  for  leases that have expired,  
  2. * and disposes of them.  

 那么租约管理器的完整功能又是什么呢。这个还是从他的java doc入手(hadoop里的注释写的非常好,结合注释和代码看的比较快)

 

Java代码     收藏代码
  1. /**  
  2.  * LeaseManager does the lease housekeeping for writing on files.     
  3.  * This class also provides useful static methods for lease recovery.  
  4.  *   
  5.  * Lease Recovery Algorithm  
  6.  * 1) Namenode retrieves lease information  
  7.  * 2) For each file f in the lease, consider the last block b of f  
  8.  * 2.1) Get the datanodes which contains b  
  9.  * 2.2) Assign one of the datanodes as the primary datanode p  
  10.  
  11.  * 2.3) p obtains a new generation stamp form the namenode  
  12.  * 2.4) p get the block info from each datanode  
  13.  * 2.5) p computes the minimum block length  
  14.  * 2.6) p updates the datanodes, which have a valid generation stamp,  
  15.  *      with the new generation stamp and the minimum block length   
  16.  * 2.7) p acknowledges the namenode the update results  
  17.  
  18.  * 2.8) Namenode updates the BlockInfo  
  19.  * 2.9) Namenode removes f from the lease  
  20.  *      and removes the lease once all files have been removed  
  21.  * 2.10) Namenode commit changes to edit log  
  22.  */   

 租约管理器提供了如下接口给外部使用

Java代码     收藏代码
  1. /**  
  2.    * Adds (or re-adds) the lease for the specified file.  
  3.    */   
  4.   synchronized   void  addLease(String holder, String src)   
  5.   
  6.   
  7.   /**  
  8.    * Remove the lease for the specified holder and src  
  9.    */   
  10.   synchronized   void  removeLease(String holder, String src)  

 租约可以简单的理解,谁拥有什么的权限(只是带有时间限制而已),那么对于存储这个关联关系最好的数据结构就是map了,LeaseManager里存放租约的有如下几个数据结构

Java代码     收藏代码
  1. //   
  2. // Used for handling lock-leases   
  3. // Mapping: leaseHolder -> Lease   
  4. //   
  5. private  SortedMap<String, Lease> leases   
  6. // Set of: Lease   
  7. private  SortedSet<Lease> sortedLeases   
  8.   
  9. //    
  10. // Map path names to leases. It is protected by the sortedLeases lock.   
  11. // The map stores pathnames in lexicographical order.   
  12. //   
  13. private  SortedMap<String, Lease> sortedLeasesByPath   

 其中第一个SortedMap主要是存放who拥有which lease,例如A客户端当前A1请求拥有L这个租约,至于L这个租约的具体表现形式就要看租约lease这个类的描述了,租约类主要有以下几个字段来描述

 

Java代码     收藏代码
  1. private   final  String holder;   //租约的持有者   
  2. private   long  lastUpdate;      //上次租约签订的时间   
  3. private   final  Collection<String> paths =  new  TreeSet<String>();  //租约所管辖的对像,这里是hdfs文件   

 还是继续上面的例子说,假设L这个租约当前维护的是hdfs文件test_temp1_file,那么SortedMap里存放的数据类似就是这样的结构

 

Js代码     收藏代码
  1. "key"  :  "client_A_request_A1"   
  2.     "value"  :  {  
  3.             "holder" : "client_A_request_A1" ,  
  4.             "lastUpdate" : "now()"   
  5.             "paths" :[ "test_temp1_file" ]   
  6.      }  
  7.  }  

 第二个SortedSet主要是存放每个lease对象,这个SortedSet的目的是用于在租约过期检测里能够尽量检测那些租约快到期的数据,租约对象自身实现了Comparable接口,然后利用租约的更新时间和租约的持有者来做比较,例如有2个租约,A的上次更新时间为111111  B的上次更新时间为111112,那么B的状态就比A新1个时间单位,故A相比B更接近租约到期时间,所以AB同时存放在SortedSet中时,A在B的上面(TreeSet基于红黑树的TreeMap来实现)。

   第三个SortedMap主要维护一个管辖资源与租约的映射关系,例如针对test_temp1_file这个hdfs文件会存在leaseA这租约,这个主要是用于namenode查看某个数据块是否当前存在某个租约的时候使用。

 

对于租约的add操作什么时候会执行呢,跟踪代码可以看到是

Java代码     收藏代码
  1. 1 :loadFSEditLog  
  2. 2 :loadFSImage  
  3. 3 :appendFile  
  4. 4 :startFile(createFile)  

 这个等到分析datanode节点时会仔细来分析,这里暂时先知道来源。

 

 好现在开始分析leaseManager的Monitor任务线程的功能,他主要就是检测过期的租约,然后执行一些相应的处理。

检测过期的策略是首先从SortedSet里取出最接近过期的,也就是更新时间比较早的数据,然后用这个来和一个最大租约过期时间做比较,如果认为过期了就执行以下操作:

 

Java代码     收藏代码
  1. 1 :判断这个租约管辖的hdfs文件上是否还有其他数据块请求(例如租约期间的其他排队请求)  
  2. 2 :如果还有针对这个文件的请求,则这个租约就续约然后执行后续的块处理  
  3. 3 :如果没有其他请求则删除租约,关闭这个hdfs文件,同时持久化文件块映射关系  

 

针对租约期间其他的请求如何处理将在datanode节点上分析,现在分析还不够全面。

更多信息请查看 java进阶网 http://www.javady.com

你可能感兴趣的:(hadoop,Hadoop入门,hadoop教程)