Editlog的接口规范设计文档(HDFS-1580:Add interface for generic Write Ahead Logging mechanism)
来源:互联网 发布:skycc营销软件系统 编辑:程序博客网 时间:2024/06/05 04:55
转帖请注明本空间地址:http://blog.csdn.net/chenpingbupt
原文请参:
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:
3、NN定期对Journal进行roll,一般是由于checkpoint发起的a、NN给sd一个指定的JournalID来打开该Journal,如果sd没有为这个JournalID进行初始化,那么将抛出异常b、NN从一个特定的txid开始读取Journal,一般是从最后一个checkpointed image的最后一条TransactionID开始读取c、NN获取一个Journal-output-stream开始写新的Transactions,一个Journal只能有一个writer来写入,否则抛出异常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();
}
5、讨论:
1、由Journal的Address和ID组成其URI,NN应该为其生成唯一的JournalID2、Journal可以被构建,格式化,强制格式化。格式化意味着创建一个新的JournalID,强制格式化意味着删除老的。3、如果一个stream已经被open了,再来进行getOutputStream()应该抛出异常4、getInputStream应该返回一个从特定txid开始inputStream5、purgeTransation判断能否安全的删除到所有到指定txid的Transaction6、EditLogOutputStream.setVersion()应该保证任何的后续Transaction必须使用这个新的version7、EditLogInputStream.readNext()应该读向下一个Transaction,后续的getTxnId或者getVersion都应该返回这个Transaction的相关属性。
8、EditLogInputStream.mark()表示这个输入流最多可以读到mark调用的前一个Transaction。这方法和Checkpoint中的roll方法类似。readNext()会将底层的流指向下一个Transaction的开始位置,所以如果应用调用getTxn()可以直接读取到这个Transaction而避免buffer-copy。出于这个原因,EditLogInputStream也实现InputStream去直接读取底层流
9、getNumberOfTransactions(sinceTxnId)返回Journal中可以提供的从sinceTxnId开始的Transaction数量
10、roll方法可以去掉,因为mark完全可以取代
11、当某一checkpointer通知NN开始进行checkpoint,NN将在outputstream上进行mark。那样,所有到mark为止的Transaction都会被checkpointer读取到。
12、新增sync方法,因为在写入editlog的thread一把都是在对namespace进行write,持有写锁,异步的写入可以使得thread尽早释放写锁。
6、Error secnarios
1、当一个outputStream由于权限,空间不足,网络等问题不能创建时,getOutputStream会抛出异常,然后进行重试或者中止2、如果EditLogOutputStream.write()调用不能完成时,需要抛出异常。这时NN可以将该stream关闭,然后将该Journal加入到bad Journal列表。后续可以尝试将该Journal进行restore,如果成功,可以在该stream上再次进行getOutputStream()。这个情况下,这个Journal会丢失一些Transactions,因此无法提供老的Transactions。另一方面对于client来说,write的异常使得client要么进行重试写入该Transaction,但是不能跳过这个而写入下一个Transaction。3、一个打开的Stream必须要保证Transaction是顺序的并连续的。但如果是一个新打开的Stream,到时可以不接着上一个Transaction的txid连续的。但是必须要记录这个流不能提供老的Transactions4、如果Journal失效一段时间然后在写入的时候,就会出现Transaction空洞。那么这时候调用getInputStream(long sinceTxnId)正好是空洞中的Transaction时,将抛出异常。这就意味这Journal必须记录自己能提供的Transactions5、另外getNumberOfTransactions(long sinceTxnId)在sinceTxnId之后发现空洞,也会抛出异常6、readNext如果不能完整的读取一个Transaction,也抛出异常,这是客户端可以:
a、抛弃这个Journalb、关闭这个inputstream,从下一个Txit打开另一个inputstream
7、如果Client检查到Transaction损坏时,要么抛弃这个Journal,要么关闭这个inputStream,从下一个txit打开下一个inputstream
7、JournalSet
JournalSet和Journal具有一致的接口,如前所述JournalSet将一系列的Journals在内部并行操作,对外部而言,就像只有一个Journal,所以它的接口和Journal是一致的。接口如下:public class JournalSet implements Journal {
JournalSet(Configuration conf, URI u, boolean format, boolean force) ;
//List of journals
private List<Journal> listOfJournals;
}JournalSet的构造函数需要从conf中获取Journal的配置,并将其放入到listOfJournals列表中管理。写入时,JournalSet会将写入流分流的写入到各个Journals内去读取时,JournalSet会选择一个它认为最好的Journal进行读取getNumberOfTransactions返回所有流能读到的最大值purgeTransactions会作用到所有的底层流中
- Editlog的接口规范设计文档(HDFS-1580:Add interface for generic Write Ahead Logging mechanism)
- Wal log的接口规范设计文档(HDFS-1580:Add interface for generic Write Ahead Logging mechanism)
- NameNode的FSImage以及EditLog的简化模型设计文档(HDFS-1073:Simpler model for Namenode's FsImage and EditLogs)
- 预写式日志(Write-Ahead Logging (WAL))
- Unity TIP4: 带泛型参数的接口注入(interface,generic)
- Sqlite学习笔记(四)&&SQLite-WAL原理 Write ahead logging
- NVWAL 非易失Write-Ahead Log设计
- HDFS NameNode HA框架设计文档(HDFS-1623:High Availability Framework for HDFS NN)
- HDFS NameNode HA框架设计文档(HDFS-1623:High Availability Framework for HDFS NN)
- HBase WAL(Write-Ahead-Log)学习
- The storage wars: Shadow Paging, Log Structured Merge and Write Ahead Logging
- Write-Ahead 日志记录
- SQLite Write-Ahead 日志
- NameNode HA自动Failover设计文档(HDFS-3042/HDFS-2185:Automatic failover support for NN HA)
- HDFS Append 设计文档的QA(HDFS-265:Revisit append/Questions about the "Append Design")
- Write-Ahead-Log(WAL)保障数据高可用
- docxgen生成接口文档的规范
- 软件模型设计基础-接口(Interface)
- 价格战草草收场 电商巨头空赚知名度赔了美誉度
- 第二次量产成功:KingSton DT 101 G2 8G的量产经历
- Java split
- IT项目管理工具
- 一起读nodejs(三)----模块(Modules)
- Editlog的接口规范设计文档(HDFS-1580:Add interface for generic Write Ahead Logging mechanism)
- 学习join用法
- 最短路径算法--Dijkstra算法,Bellmanford算法,Floyd算法,Johnson算法
- Remove '@override' annotation解决办法
- Codeforces Round #135 (Div. 2)
- Google Host
- 免费电子书列表
- LINQ TO Object
- Wal log的接口规范设计文档(HDFS-1580:Add interface for generic Write Ahead Logging mechanism)