1580:Editlog的接口规范设计文档

原文请参:
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

译文如下:

本文提出一个NN使用editlog的接口设计和规范。

1、设计目标
1、本接口应该和多种底层的editlog存储系统相适应,如本地文件系统,NFS,Bookkeeper等
2、本设计应该在现有的hdfs代码上很容易的实现
3、本设计应该很容易在需要HA的实现时,进行扩展。

2、术语定义:
Journal - 指的是一系列的Transactions,每个Transaction有一个连续增长的整数作为txid与之关联
StorageDevice - 指的是存储journals的设备,如nfs,bookkeeper等等。一个StrorageDevice可能具有内置的冗余保证,也能支持存储多个应用的journal文件,所有一个每个journal需要一个joural id来标识
JournalSet - 一般来说应用系统都会将journal并行的写入到多个存储设备中,为了消除存储系统的不可靠,或者为了进行share,而写入到nfs系统中。这个并行的journal就称为JournalSet,JournalSet扩展了Journal的属性(OO角度)

3、关键用例
典型的系统中,NN会将Journal并行写入到多个StorageDevices,如本地文件系统和nfs、bookkeeper等。以下的用例虽然只提到一个Journal,但是可以将其想象为一个JournalSet,类似的,如果提到一个StorageDevices,在一个StrorageDevice集下亦是适用。
1、NameNode Format:NN在格式化sd的时候将对journal进行初始化并且给点一个journalId,如果之前有一个存在的journal已经具有了该journalid,那么format过程将抛出一个异常,除非设置了强制进行format。
2、NameNode startup:
a、NN给sd一个指定的JournalID来打开该Journal,如果sd没有为这个JournalID进行初始化,那么将抛出异常
b、NN从一个特定的txid开始读取Journal,一般是从最后一个checkpointed image的最后一条TransactionID开始读取
c、NN获取一个Journal-output-stream开始写新的Transactions,一个Journal只能有一个writer来写入,否则抛出异常
3、NN定期对Journal进行roll,一般是由于checkpoint发起的
4、NN删除过期的Transaction,如果NN认为当前已经不需要了,如:checkpoint已经完成
5、CheckpointNode读取一个Journal的Transaction进行Checkpoint的时候,PNN也可以并行的写入到该Journal中
6、StandbyNN读取一个Journal来保持warm的时候,PNN同时也可以对该Journal进行写入
7、当一个StandbyNN准备变成ActiveNN时,会通知该sd去fence其他writer,如果sd不支持fence,那么抛出异常。
Journal抽象设计考虑点
需要将segment这个概念暴露出来吗?原本考虑每个segment都具有相同的布局,能够从Transaction中获取segment的信息,所以在Transaction Record中不需要存储这个segment。另外roll这个方法也没有暴露出来,Journal可以被看作是单一的Transaction序列,从这个角度来看我们也不需要暴露segment的概念
JournalSet和Journal:这两者的关系与不同在哪里?前者继承了后者,前者是后者的同一种抽象的另一种实现。

4、接口规范提议:
interface Journal {
     Journal (URI u, boolean format, boolean force) throws AlreadyExistsException, IOException;
     EditLogOutputStream getOutputStream() throws MultipleWriterException, IOException;
     //This indicates that transactions up to txnId are safe to be deleted.
     void purgeTransactions (long txnId);
     EditLogInputStream getInputStream (long sinceTxnId) throws IOException;
     long getNumberOfTransactions(long sinceTxnId) throws IOException;
}
Interface EditLogOutputStream {
     void write(long txnId, byte[] txn) throws IOException;
     void setVersion(long version);
     void mark();
     close();
     //Alternative to this method is to sync upon every write and let write return asynchronously
     //so that fsnamesystem lock and handle thread is not held while writing and sync‐ing.
     void sync() throws IOException;
}
abstract class EditLogInputStream extends InputStream{
     void readNext();
     long getTxnId();
     long getVersion();
     byte[] getTxn();
     close();
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/c15755456971998b2738fd10c360b79f.html