1、backupnode启动后,在初始化阶段完成握手和注册,其中在握手阶段handShake,检测storage的版本是否一致,同时建立到namenode的RPC句柄,保存在成员变量namenode当中,registerWith通过RPC调用Namenode的register,完成backupnode信息在namenode上的注册,同时完成在FSNamesystem和FSEditLog上的检查,如果已经存在了,应该不允许注册,但FSEditLog的checkBackupRegisteion的代码似乎有些问题
2、启动CheckpointDaemon,进行Checkpoint的工作,checkuppoint的具体工作如下:
1)检测时间上是否到了可以启动的条件
2)检测是否是启动时,执行checkupoint,这个在初始化时设置启动时执行checkpoint
3)开始做真正的checkpoint的工作,具体在docheckpoint函数,具体过程如下:
a)rpc调用namenode的startCheckpoint函数,获取namenode的通知,如果namenode发现namespace版本不一致、或者backupnode有更新的image等,会返回ACT_SHUTDOWN的命令,如果一切正常,namenode端会调用FSImage的rollEditLog,而后namenode端调用logJSpoolStart,并将isImageObsolete和needToReturnImg作为CheckpointCommand的一部份返回;startCheckpoint的最后一个工作就是调用FSEdit的logSync函数,不理解这里调用这个函数有什么意义呢?
i)在FSImage的rollEditLog中会调用EditLog的rollEditLog,完成目录的切换,切换的过程包括关闭原来的stream并在新的目录中开启stream;其中FSImage的rollEditLog还会设置ckptState为ROLLED_EDIT,incrementCheckpointTime和产生新的CheckpointSignature;
ii)logJSpoolStart,则主要是将backupnode的stream加入到edit的streams当中,并且写入第一个EditLog:OP_JSPOOL_START到每一个stream当中
iii)CheckpointCommand被返回,其中isImageObsolete为true,如果namenode的edit和backupnode的edit不一致,否则为false;needToReturnImage表示如果namenode有放置edit的目录,则返回checkpoint的image,否则不用返回,因为namenode可以不记录edit,但如果不记录,有如何做checkpoint呢?有点矛盾呀?
b)backupnode将自身的FSImage设置为CheckpointState.UPLOAD_START,CheckuppointState有:START,ROLLED_EDIT,UPLOAD_START,UPLOAD_DONE这样几个状态,此时,namenode应该处于ROLLED_EDIT状态,backupnode处于UPLOAD_START状态
c)如果只有namenode有image等数据(也就是isImageobsolete is true),则将backupnode的内存和disk的数据都reset一下,通过调用resetNamespace函数,然后通过输入signature参数调用dowloadCheckpoint函数,来下载image数据,数据通过HTTP服务下载,如果isImageObsolete is false,则不需要做这些事情了。
d)backupnode的image对象开始loadCheckpoint,将checkpoint装载到内存后在save到disk上,完成了新的checkpoint的生成过程
e)如果需要上传image,则将新的checkpoint上传到namenode,通过调用uploadCheckpoint函数实现
f)rpc调用namenode的endCheckpoint,通知namenode checkpoint已经完成;namenode调用namespace的endCheckpoint,继续传递调用到FSImage的endCheckpoint,FSImage的endCheckpoint调用rollFSImage,在rollFSImage中,会通知FSEdit去purgeEditLog,也就是删除掉原来的editlog,并将edit.new rename为edit;将checkpoint进行重命名,调用FSImage的renameCheckpoint,将名字从fsimage.ckpt改为fsimage ;调用resetVersion,所做的主要工作包括,设置layoutVersion,不同版本的Hadoop保存的image的layoutVersion会不同,更新checkpointTime,最后在resetVersion,这个函数比较难理解的是删除old image和edit,其实是根据条件删除,因为一个目录可以同时保存image和edits,所以按照程序的语义如果目录类型不是image,那么就把其中的image文件删除,如果一个目录不是edit,就把其中的edit文件删掉,然后将每个目录中的version文件更新,最后把ckpState的状态指定为START,ckpState的命名容易让人误解,其实状态START就是一般情况,不是真正开始做checkpoint,比如系统刚开始启动时,ckpState的状态就是START,所以这相当与让状态又恢复到初始状态。
g)backupnode通过调用convergeJournalSpool将checkpoint阶段缓冲的editlog合并到内存的image当中
h)再次设置注册信息setRegistration,目的是为了保持registration的更新,因为在registration中包含了Image的信息,包括checkpointTime等,因此checkpoint完成后需要更新一下注册信息
i)如果当期backupnode的role是CHECKPOINT,那么可以让内存中的FSImage关闭掉了,否则如果是BACKUP的话,就保持这些信息在内存当中
3、通过checkpoint工作,backupnode内存中已经装载了namesystem的数据,当backupnode刚刚加载完namesystem数据时,jsState会设置成OFF接下来,namenode会通过rpc调用backupnode的journal函数,将实时的edit数据传输给backupnode。
下面讨论一下backupstorage中jsState的状态转化过程,通过这个过程的分析,可以更好理解edit spool的工作过程:
-----------------
backupstorage中jsState的状态转换过程
1、初始状态为OFF
2、在startJournalSpool时,无论原来什么状态都会转为INPROGRESS