我们开始对租约Lease进行分析,下面是类图。Lease可以认为是一个文件写锁,当客户端需要写文件的时候,它需要申请一个Lease,NameNode负责记录那个文件上有Lease,Lease的客户是谁,超时时间(分布式处理的一种常用技术)等,所有这些工作由下面3个类完成。至于租约过期NameNode需要采取什么动作,并不是这部分code要完成的功能。
LeaseManager(左)管理着系统中的所有Lease(右),同时,LeaseManager有一个线程Monitor,用于检查是否有Lease到期。
一个租约由一个holder(客户端名),lastUpdate(上次更新时间)和paths(该客户端操作的文件集合)构成。了解了这些属性,相关的方法就很好理解了。LeaseManager的方法也就很好理解,就是对Lease进行操作。注意,LeaseManager的addLease并没有检查文件上是否已经有Lease,这个是由LeaseManager的调用者来保证的,这使LeaseManager跟简单。内部类Monitor通过对Lease的最后跟新时间来检测Lease是否过期,如果过期,简单调用FSNamesystem的internalReleaseLease方法。
这部分的代码比我想象的简单,主要是大部分的一致性逻辑都存在于LeaseManager的使用者。在开始分析FSNamesystem.java这个4.5k多行的庞然大物之前,我们继续来扫除外围的障碍。下面是关于访问控制的一些类:
Hadoop文件保护采用的UNIX的机制,文件用户分文件属主、文件组和其他用户,权限读,写和执行(FsAction中抽象了所有组合)。
我们先分析包org.apache.hadoop.fs.permission的几个类吧。FsAction抽象了操作权限,FsPermission记录了某文件/路径的允许情况,分文件属主、文件组和其他用户,同时提供了一系列的转换方法,applyUMask用于去掉某些权限,如某些操作需要去掉文件的写权限,那么可以通过该方法,生成对应的去掉写权限的FsPermission对象。PermissionStatus用于描述一个文件的文件属主、文件组和它的FsPermission。
INode在保存PermissionStatus时,用了不同的方法,它用一个long变量,和SerialNumberManager配合,保存了PermissionStatus的所有信息。
SerialNumberManager保存了文件主和文件主号,用户组和用户组号的对应关系。注意,在持久化信息FSImage中,不保存文件主号和用户组号,它们只是SerialNumberManager分配的,只保存在内存的信息。通过SerialNumberManager得到某文件主的文件主号时,如果找不到文件主号,会往对应关系中添加一条记录。
INode的long变量作为一个位串,分组保存了FsPermission(MODE),文件主号(USER)和用户组号(GROUP)。
PermissionChecker用于权限检查。