hadoop源码详细解读1——类Storage
由于工作中用到了hadoop,一直想对其源码一探究竟,苦于时间有限,所以此系列希望督促自己完成hdfs的源码解读,这里先把前期对于datanode的源码详细解读放上来。
学习源码是一个磨砺人的心智的过程,所以需要好好利用已有的资料(ps:百度文库里hdfs源码解析),先从宏观上明白一组类的作用,然后再看源码围观分析;可能会非常耗时,但是明白了设计思想,对自身也是一种提高,兵贵神速,读源码贵在坚持!
用途:
主要用来进行版本管理,包括升级、回滚
设计思路:
Version的信息是一个对象StorageInfo(版本、ID、cTime)
对目录进行管理的对象StorageDirectory(root、lock)
对一个节点的存储管理的对象Storage(type、各种文件名)
每个datanode或者namenode都有一个Storage对象,包含多个StorageDirectory(conf下的配置文件里配置的)
每个StorageDirectory主要有一下几个操作:
1、read()
a)读取此StorageDirectory下的current目录下的VERSION,并且和此Storage的信息对比,主要是在启动的时候比对版本
2、write()
a)将StorageDirectory的信息更新到VERSION中去
3、 clearDirectory():
a) 用在格式化时
b) 先判断目录是否存在,存在则删除(删不掉,抛异常),不存在则新建(建不了,抛异常)
4、 StorageState analyzeStorage(StartupOption startOpt):
a) 检查此StorageDirectory的一致性
b) 步骤:
i. 判断root路径是否存在,如不存在,进一步判断启动操作是否是FORMAT,如果不是,则返回NON_EXEISTING;如果是,则创建路径,如果创建失败,抛异常;接下来判断root是否是一个Directory和可写入的,如果不是则都返回NON_EXEISTING,同时在这个过程中要多Security进行判断
ii. 锁定文件(用文件channel的锁即可,排他性)
iii. 判断startOpt是否是FORMAT,如果是,则返回NON_FORMATTED
iv. 然后判断是否需要conversion,如果需要,则返货CONERT,判断方法是abstract的,由子类实现
v. 如果在StorageDirectory里不存在任何的tmp文件,进一步,如果hasCurrent(),返回NORMAL,如果hasPrevious则抛出version file in current directory it is missing的异常,默认返回NOT_FORMATTED
vi. 如果tmp文件数大于1,抛出"too many temporary directories."异常
vii. 如果hasFinalizedTmp,进一步,如果hasPrevious,抛出tmp_prevous and tmp_finalized cannot exist together异常,默认返COMPLETE_FINALIZE
viii. 如果hasPreviousTmp,进一步,如果hasPrevious,抛出previous and tmp_prevouds cannot exist together,如果hasCurrent,返回COMPLETE_UPGRADE,默认返回RECOVER_UPGRADE
ix. assert hasRemovedTmp,然后如果hasCurrent和hasPrevious都为false,则抛出异常(有且仅有一个存在,当removed tmp存在时)
x. 如果hasCurrent,返回COMPLETE_ROLLBACK
xi. 最后默认返回RECOVER_ROLLBACK
5、 void doRecover(StorageState curState)
a).在执行升级操作时宕机了,需要先分析StorageDirectory的状态,然后用此方法恢复
b).步骤
i. 判断curState
是COMPLETE_UPGRADE的,则要mv previous.tmp -> previous,直接rename
是RECOVERUPGRADE,要mv previous.tmp -> current,先判断当前的current目录是否存在,如果存在,则先删除,然后rename
是COMPLETE_ROLLBACK,要rm removed.tmp,直接delete掉
是RECOVER_ROLLBACK,要mv removed.tmp -> current,rename即可
是COMPLETE_FINALIZE,要rm finalized.tmp,直接delete掉
默认不能识别的IO抛出异常
感想:学习了这些,还是破有感触的,这个类的设计和实现较好的体现了简单的事务管理,看完了这些,你是否明白了为什么上传一个文件到hadoop中,先要加上.tmp,然后rename,删除本地文件时,也要先rename为.tmp文件,然后再删除!