前言
在文章开始,先讲个大家都经历过的事--去图书馆借书,当然,喜欢阅读的朋友也许和我一样比较喜欢借书阅读,借书阅读方便是方便,但是唯一不好的地方在于他又期限,就是deadlline,之前在我们学校有规定,如果超期为归还的书不允许借阅另外的书籍,所以要想使自己能接到新的书,就必须先归怀超期的书籍。当然这个经历本身再寻常不过了,但是我想表达的是在HDFS分布式文件系统中的租约机制与此过程有着极强的吻合性,后面的归还书籍相当于租约恢复的操作,下面详细介绍一下什么是租约。
租约以及租约相关类
租约可简单理解为在短期时间内对于租约持有者也就是客户端一定的权限,例如写文件的凭证。在每次HDFS中进行块的添加,删除操作时候,都会进行租约的核查和更新,以此维护各个文件操作情况。一下列出租约的相关类:
1.LeaseManager--租约管理类,可以理解为是一个租约大管家,里面维护了多种映射关系的租约集合列表。
2.LeaseManager.Lease--租约实体类,就是租约具体的表现形式类。在下面会详细介绍,此类中的变量和方法。
3.FSNamesystem--名字系统类,因为在这个大杂烩的大类中会用到租约相关的方法,也就加入进来。
Lease
首先从小类开始分析,也就是租约类Lease,他是一个内部类,存在于LeaseManager中。对于租约,首先有明白这样一个概念,租约是凭证,对客户端写操作文件的一种凭证,首先肯定得包含租约持有者变量,其次有租约记录的操作文件列表,当然租约还需要有时间,来记录租约超时的情况,所以类的变量结构如下
/************************************************************
* A Lease governs all the locks held by a single client.
* For each client there's a corresponding lease, whose
* timestamp is updated when the client periodically
* checks in. If the client dies and allows its lease to
* expire, all the corresponding locks can be released.
*************************************************************/
//每条租约记录信息,只能被单一的客户端占有
class Lease implements Comparable<Lease> {
//租约信息客户持有者
private final String holder;
//租约最后更新时间
private long lastUpdate;
//此租约内所打开的文件,维护一个客户端打开的所有文件
private final Collection<String> paths = new TreeSet<String>();
/** Only LeaseManager object can create a lease */
private Lease(String holder) {
this.holder = holder;
renew();
}
.....
在这里,Lease类将客户端打开的所有文件维护在了paths类中,然后通过租约持有者的名字进行初始构造函数的构造。然后注意这里有一个renew()方法,他是做租约时间更新的
/** Only LeaseManager object can renew a lease */
//根据租约最后的检测时间
private void renew() {
this.lastUpdate = FSNamesystem.now();
}
OK,租约类暂时先了解到这里,跳到下一个租约管理者类LeaseManager.
LeaseManager
身为一个管理者,内部变量肯定会稍稍多一些
/**
* LeaseManager does the lease housekeeping for writing on files.
* This class also provides useful static methods for lease recovery.
*
* Lease Recovery Algorithm
* 1) Namenode retrieves lease information
* 2) For each file f in the lease, consider the last block b of f
* 2.1) Get the datanodes which contains b
* 2.2) Assign one of the datanodes as the primary datanode p
* 2.3) p obtains a new generation stamp form the namenode
* 2.4) p get the block info from each datanode
* 2.5) p computes the minimum block length
* 2.6) p updates the datanodes, which have a valid generation stamp,
* with the new generation stamp and the minimum block length
* 2.7) p acknowledges the namenode the update results
* 2.8) Namenode updates the BlockInfo
* 2.9) Namenode removes f from the lease
* and removes the lease once all files have been removed
* 2.10) Namenode commit changes to edit log
* 租约管理器,包含了与文件租约相关的许多方法
*/
public class LeaseManager {
public static final Log LOG = LogFactory.getLog(LeaseManager.class);
private final FSNamesystem fsnamesystem;
//租约软超时时间
private long softLimit = FSConstants.LEASE_SOFTLIMIT_PERIOD;
//租约硬超时时间
private long hardLimit = FSConstants.LEASE_HARDLIMIT_PERIOD;
//
// Used for handling lock-leases
// Mapping: leaseHolder -> Lease
//租约持有者到租约的映射图,保存在treeMap图中
private SortedMap<String, Lease> leases = new TreeMap<String, Lease>();
// Set of: Lease
//全部租约图
private SortedSet<Lease> sortedLeases = new TreeSet<Lease>();
//
// Map path names to leases. It is protected by the sortedLeases lock.
// The map stores pathnames in lexicographical order.
//路径租约图映射关系
private SortedM