本文是关于Append设计文档中一些设计点的QA,原文的地址已经不记得是从HDFS中的那个Jira上看到的了,可以参考Append设计文档来看:
https://issues.apache.org/jira/secure/attachment/12445209/appendDesign3.pdf
译文如下:
以下场景中,可能发生那些失败,以及如何处理? Blocks being copied (replicated/balance) 源DN启动replicating过程,过程中的错误可能导致过程不会完成。目标DN首先将数据写入"blocksBeingReplcated"文件夹,如有错误发生,目标DN将这些残缺的block移除,当这个DN重启时,会将所有的"blocksBeingReplcated"中的blk移除。 Blocks being written, no sync, no append Blocks being written, syncs, no append Blocks being appended, no sync Blocks being appended, no sync 以上4中情况的处理方式都是一样的。这里的设计将append视为普通的write,所有的case中,NN会为文件持久化一个lease,这也意味着NN自身不care文件长度而是将这个责任代理给writer/datanode。leaserecovery将这些信息从writer/datanode转移到namenode 当writer/appender开始写一个block,DN将blk的数据写入到"blocksBeingWritten"目录下。当writer/appender成功完成时候,blk会从"blocksBeingWritten"转移到真实的目录下。 如果writer/appender在中途挂了,那么会导致该Pipeline中各个DN在"blocksBeingWritten"的blk具有不同的长度,这时候NN会发起一个leaseRecovery来处理这个情况。 如果writer/appender中途遇到错误,writer会发起这个Leaserecovery,最后NN也会知悉文件的长度和GS。 blk一直在"blocksBeingWritten"中,即使进行了flush调用也如此,因为flush不会使得DN产生blockRecevied调用去通知NN,这个设计使得多次调用flush不会产生对NN的压力。 Which blocks to send in a block report? those being written to, appended, sync? 当一个blk被written/appended,它会处在"blocksBeingWritten"目录中,这意味着一个存在的blk将会被移到"blocksBeingWritten"去做append。而blockReport将会忽略"blocksBeingWritten"和"blocksBeingReplicated"目录。 如果NN在blockReport中收到一个blk数据一个持有lease的文件,NN会将其插入到lease记录中。但是不会触发replication和corrupt检查。 如果blocksmap中记录的长度小于汇报长度,将删除所有的replica的locations,然后插入这个新的locations。 如果blocksmap中记录的长度大于汇报长度,将不会插入到blocksmap中 如果blocksmap中记录的长度等于汇报长度,将这个replica插入到blocksmap中 如果blocksmap中记录的GS小于汇报GS,将replica插入到blocksmap中,但不会创建和删除replica。这一般发生在writer/appender多次进行Recovery What happens on a datanode restart? DN重启时,首先将所有 "blocksBeingReplicated"中的blk删除。然后检查所有在"blocksBeingWritten"中的blk,如果blk的data和crc匹配,将这个blk视为有效,并将其移动到真实目录。这样就可以让blockreport将这个blk汇报到NN中。 由于NN具有这个文件的lease,所以在NN收到blockReport时候,就能对这个replica进行Leaserecovery 如果crc和data不匹配,那么会将data或crc进行truncate到匹配的长度,再将blk从"blocksBeingWritten"移到真实目录。 Block lengths on NN side - what should happen? 由于NN并不知悉文件(具有lease)的长度,只有writer/datanode知晓。所以NN永远不会发起blk的replication/deletion。 Namenode failures NN会将文件的lease进行持久化到transaction log中。当NN重启,会读取transaction log去进行Leaserecovery Handling of blockReceived message NN检查该blk的文件是否具有lease,如有,则将blk加入到blocksmap,但不检查corrupt,excess,new replication requests。 如果NN中的长度小于汇报过来的长度,所以的replica的locations将从blocksmap中删除,插入这个新的locations。 如果NN的要大于汇报的,那么这个replica的locations将不会被插入。 如果NN的要等于汇报的,那么这个replica将会插入到blocksmap中。 当文件具有lease时,NN绝不会发起blk的creation and deletion How does lease recovery on the datanode handle partial corrupt data? Leaserecovery中,PD通过调用Pipeline中的其他DN的InterDatanodeProtocol.updateBlock()方法,对Pipeline中DN的replica都设置GS和长度。 DN收到InterDatanodeProtocol.updateBlock()调用时候,首先检查该blk是否处于"blocksBringWritten",如是,则检查crc和data是否匹配,否则truncate到匹配位置。 最后DN将blk打上新的时间戳,并且将其从"blocksBringWritten"移到真实位置 Completion of lease recovery 成功Leaserecovery将关闭该文件,关闭文件的时候NN会索引的blk进行备份检查,看看是否需要进行blk的备份。