HDFS Append 设计文档的QA(Questions about the “Append Design”)

2019-03-28 13:26|来源: 网络

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

相关问答

更多
  • 终于摆脱了错误。 显然,必须关闭从filesystem调用create时返回的FSDataOutputStream 。 话虽这么说,这就是现在实现HDFSFileUtilImpl的方法createFileInCluster : @Override public void createFileInCluster(String uriOfFile) throws IOException { Validate.notEmpty(uriOfFile); FSDataOutputStream ...
  • 您的第一次尝试非常接近,但请记住, append()返回#thumbnails ,而不是您刚添加的项目。 相反,首先构建您的项目,然后在添加之前应用hide().fadeIn() : $('#thumbnails').append($('
  • ').hide().fadeIn(2000)); 这使用美元函数提前构建
  • 。 你也可以写两条线,当然如果这样做更清楚: var item = $('
  • 您可以保存当前保存的元素,因此下次调用该函数时,将其删除。 例如: let previous; _placeBet = () => { const tipChipSnap = snap('#chip-bet'); const tipChipSvgContent = Snap.parse(this.props.chipSelectedSvg.content); tipChipSnap.append(tipChipSvgContent); if (previous) previous.remo ...
  • 首先初始化商店可能会有所帮助。 然后,您应该能够将数据mytable分配给mytable并使用它,就像您在仅限数据帧的示例中一样。 store = pd.HDFStore('test.h5') store['mytable'] = d1 store['mytable'].append(d2.loc[d2.index.difference(store['mytable'].index)]) col a x 1 y 1 b x 2 It might help to init ...
  • 由于HDFS用于一次写入,因此可以多次读取。 我们无法更改包含Hdfs文件。 您正在尝试将数据附加到hdfs中的文件。 复制文件intohdfs然后你可以使用-getmerge实用程序。 hadoop fs -getmerge [addnl]。 使用map reduce的另一个解决方案是:将新文件作为分布式缓存文件(它应该适合内存)并读取已存在于hdfs中的文件并比较Map方法中的记录。 Since HDFS is used for Write Once , Read Many times. we can ...
  • 像这样? var maxAppend = 0; $("#add-cert").click(function(){ if (maxAppend >= 5) return; var addinput = $( "
    "+ "
    "+ "< ...
  • 如果我理解你的问题,我建议你尝试使用com.twitter.bijection.Injection和com.twitter.bijection.avro.GenericAvroCodecs包。 看看http://aseigneurin.github.io/2016/03/04/kafka-spark-avro-producing-and-consuming-avro-messages.html 。 在那里,在Kafka生产者中,GenericRecord被转换为bytes [],它们放在Kafka主题中,然 ...
  • 因为append()列表方法不返回列表,所以它只是修改它被调用的列表。 在这种情况下,匿名列表被修改,然后丢弃。 文档不是非常清晰,但它说的是: list.append(x)的 将项目添加到列表的末尾; 相当于a[len(a):] = [x] 。 对于其他方法(如list.count(x) ,在描述中会出现“return”一词,意味着如果没有,则该方法没有返回值。 Because the append() list method doesn't return the list, it just modifi ...
  • 在这里,您只需要使用concat_ws将数据连接concat_ws并将其作为文本对齐: query = """select concat_ws(',', date, nvl(min(id), 0), nvl(max(id), 0)) from mytempTable""" sqlContext.sql(query).write("text").mode("append").save("/tmp/fooo") 甚至是更好的选择: from pyspark.sql import functions as f ...
  • $('
    ').append('default ' + event.type + ' prevented') 返回附加文本的div。 并且这个div被附加到'#log'元素。 链接函数调用是使这两个函数有用的东西。 从文档: .append()和.appendTo()方法执行相同的任务。 主要区别在于语法特定,内容和目标的放置。 使用.append(),方法前面的选择器表达式是插入内容的容器。 另一方面,使用.appendTo(),内容在方法之前,作为选择器表达式或动态创建的标记,并将其插入目标容 ...