HDFS-1580:Wal log的接口规范设计文档

汪迎春 2012-08-30

原文请参:
https://issues.apache.org/jira/browse/HDFS-1580
https://issues.apache.org/jira/secure/attachment/12481883/EditlogInterface.3.pdf
https://issues.apache.org/jira/secure/attachment/12474635/generic_wal_iface.pdf

1、接口定义
abstract class JournalFactory {
     JournalFactory(Configuration conf);
     void close();
     boolean available();
     void format();
     // get past logfiles
     List<URI> getLogs(long sinceTransactionId);
     // Streams
     EditLogInputStream 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中的logs
URI可以定位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     Versioning
Editlog的格式也在不断的变化,所以在EditLogInputStream中加入了一个getLayoutVersion()来获取这个信息。

1、3     Error handling
当底层的Storage出错时,该Stream会被删除,一般过程是,EditLogOutputStream在写入时,抛出异常,Editlog接受异常并将stream从activeStreams中删除。FSEditLog会在roll的时候尝试读取该删除的流

1、4     Rolling
EditLogOutputStream.roll()会保证所有所有的txid在roll之前都已经提交了

2     Configuring custom WAL
目前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列表两个

3     FileJournalManager
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

5、1     format
FSImage增加一个format方法,用来format一下NNStorage和Editlog

5、2     loadFSImage()
目前loadFSImage会遍历所有的SD获取他们的Checkpoint time。在这个设计之后,loadFSImage只会到IMAGE类型的SD并且调用FSEditLog.getLogs(),并将返回的URI加载到Namesystem。

5、3     recoverInterruptedCheckpoint
这个先留着,本意是通过家产edits.new的存在性来判断Checkpointing过程是否在完成之前被中止了。HDFS-1073将会包这个给干掉,它通过将文件上传到一个零时文件,然后原子性的重命名。

6     The IMAGE_AND_EDITS problem
FileJournalFactory.format()仅仅是一个stub,因为现在的FSImage有一种IAMGE_AND_EDITS的SD,如果FSImage格式化所有的IMAGE类型的SD,FSEdit格式化所有的EDITS类型的SD,那么两者都会format上述的IMAGE_AND_EDITS的SD。所以这个事情留给FSImage去做。

7     Backup namenode functionallity
当前BN在FSImage and FSNamesystem,都有一些特殊的对待,这个设计中也先不管了。
BN的stream初始化和清理都在logJSpoolStart和releaseBackupStream中完成。
FSEditLog遍历所有的EDITS目录来做roll,有了close和获取新stream的方法之后,BackupStreams显然没有必要也去遍历。

相关推荐