原文请参:
https://issues.apache.org/jira/browse/HDFS-1580
1、接口定义
abstract class JournalFactory {JournalFactory(Configuration conf);void close();boolean available();void format();// get past logfilesList<URI> getLogs(long sinceTransactionId);// StreamsEditLogInputStream getInputStream(URI);EditLogOutputStream getOutputStream(URI);}class EditLogOutputStream {...void beginRoll(long txid) throws IOException;void endRoll() throws IOException;abstract void write(long txid, byte op, Writable ... writables) throws IOException;}class EditLogInputStream {...void getLayoutVersion() throws IOException;}JournalFactory负责管理StrorageDevice(SD),SD可以存储多个Wal。例如:目录edits_dir可以存储edits,edits.new,在hdfs-1073之后,还可以存储edits.{txid-txid}。FileJournalFactory管理文件SD,容许client访问Storage中的logsURI可以定位logs,client可以使用URI来打开。FSEditLog包含一个EditLogOutputStream列表,这个列表都是从JournalFactory中构建出来的1、1 format()FSEditLog.format()负责将所有URI指定的dir进行初始化,但是它是通过调用所有URI的factory的format来进行初始化的,以便底层的Storage可以创建流进行logging日志。如果是FileJournalFactory,其format是一个stun,具体参加IMAGE-AND_EDITS问题部分。1、2 VersioningEditlog的格式也在不断的变化,所以在EditLogInputStream中加入了一个getLayoutVersion()来获取这个信息。1、3 Error handling当底层的Storage出错时,该Stream会被删除,一般过程是,EditLogOutputStream在写入时,抛出异常,Editlog接受异常并将stream从activeStreams中删除。FSEditLog会在roll的时候尝试读取该删除的流1、4 RollingEditLogOutputStream.roll()会保证所有所有的txid在roll之前都已经提交了
2 Configuring custom WAL
3 FileJournalManager目前NN通过dfs.namenode.edits.dir来指定一个URI列表作为Editlog的目录,而使用dfs.namenode.edits.plugin.<PLUGIN>来指定一个JournalFactory的实现去初始化这个URI指定的目录。<property>
<name>dfs.namenode.edits.dir</name>
<value>mywal://foobar/etc/etc</value>
<description>Location of editlog.</description>
</property>
<property>
<name>dfs.namenode.edits.plugin.mywal</name>
<value>com.mycompany.hdfs.MyWalJournalFactory</value>
<description>Journal Factory implementation.</description>
</property>Factory的构造函数中需要conf和URI列表两个
FileJournalManager作为一个特殊用例对待,当URI的sechma是file://开始的时候4 Transferring logs to checkpointer
现在的Checkpointer需要通过http下载image和edits,在这个设计之后,只需下载image即可。当需要load edits的时候,JournalFactory.getLogs将会返回一个URI列表,然后通过使用JournalFactory.getInputStream()来打开,如果是FileJournalFactory,getInputStream会来检查该URI是本地还是remote的,如果是remote的会先通过http下载到本地5 Modifications to FSImage
6 The IMAGE_AND_EDITS problem5、1 formatFSImage增加一个format方法,用来format一下NNStorage和Editlog5、2 loadFSImage()目前loadFSImage会遍历所有的SD获取他们的Checkpoint time。在这个设计之后,loadFSImage只会到IMAGE类型的SD并且调用FSEditLog.getLogs(),并将返回的URI加载到Namesystem。5、3 recoverInterruptedCheckpoint这个先留着,本意是通过家产edits.new的存在性来判断Checkpointing过程是否在完成之前被中止了。HDFS-1073将会包这个给干掉,它通过将文件上传到一个零时文件,然后原子性的重命名。
7 Backup namenode functionallityFileJournalFactory.format()仅仅是一个stub,因为现在的FSImage有一种IAMGE_AND_EDITS的SD,如果FSImage格式化所有的IMAGE类型的SD,FSEdit格式化所有的EDITS类型的SD,那么两者都会format上述的IMAGE_AND_EDITS的SD。所以这个事情留给FSImage去做。
当前BN在FSImage and FSNamesystem,都有一些特殊的对待,这个设计中也先不管了。BN的stream初始化和清理都在logJSpoolStart和releaseBackupStream中完成。FSEditLog遍历所有的EDITS目录来做roll,有了close和获取新stream的方法之后,BackupStreams显然没有必要也去遍历。