哪个Java文件将Hadoop HDFS文件拆分为块

时间:2016-01-12 21:45:49

标签: java apache hadoop hdfs

众所周知,当将本地文本文件复制到HDFS时,该文件将被拆分为固定大小128 MB。例如,当我将256 MB文本文件复制到HDFS时,将有2个块(256/128)包含" splitted"文件。

有人可以告诉我 Hadoop 2.7.1 源代码中的哪个java / jar文件执行将文件拆分为块的功能以及哪个java / jar文件将块写入datanode&# 39; s目录。

帮我跟踪这段代码。

我只找到了他们为FileInputFormat.java中找到的块进行逻辑输入拆分的那个,这不是我需要的。我需要java文件来分割物理文件。

2 个答案:

答案 0 :(得分:1)

将数据写入DataNode的代码存在于2个文件中:

  • # use fatal; my $file = open 'nonexistent', :r; say 'Reached here'; my @lines = $file.IO.lines; (包裹:DFSOutputStream.java

    客户端写入的数据被分成数据包(通常为64k大小)。当数据包准备就绪时,数据将被排入数据队列,由org.apache.hadoop.hdfs获取。

  • DataStreamer(包裹:DataStreamer

    它获取数据队列中的数据包并将它们发送到管道中的数据节点(由于复制因子为3,数据管道中通常有3个数据节点)。

    它检索新的块ID并开始将数据流式传输到数据节点。当写入一个数据块时,它会关闭当前块并获取一个用于写入下一组数据包的新块。

    获取新块的代码如下:

    org.apache.hadoop.hdfs

    当前块关闭的代码如下:

    // get new block from namenode.
    if (stage == BlockConstructionStage.PIPELINE_SETUP_CREATE) {
      if(LOG.isDebugEnabled()) {
        LOG.debug("Allocating new block");
      }
      setPipeline(nextBlockOutputStream());
      initDataStreaming();
    }
    

    // Is this block full? if (one.isLastPacketInBlock()) { // wait for the close packet has been acked synchronized (dataQueue) { while (!shouldStop() && ackQueue.size() != 0) { dataQueue.wait(1000);// wait for acks to arrive from datanodes } } if (shouldStop()) { continue; } endBlock(); } 方法中,舞台再次设置为:

    endBlock()

    这意味着,创建了一个新的管道,用于将下一组数据包写入新的块。

编辑:如何检测到块的结束?

stage = BlockConstructionStage.PIPELINE_SETUP_CREATE; 继续向块附加数据时,它会更新写入的字节数。

DataStreamer

如果写入的字节数等于blocksize:

,它还会继续检查
/**
  * increase bytes of current block by len.
  *
  * @param len how many bytes to increase to current block
  */
void incBytesCurBlock(long len) {
    this.bytesCurBlock += len;
}

在上面的陈述中,以下条件检查是否达到了块大小:

// If packet is full, enqueue it for transmission
//
if (currentPacket.getNumChunks() == currentPacket.getMaxChunks() ||
    getStreamer().getBytesCurBlock() == blockSize) {
  enqueueCurrentPacketFull();
}

如果遇到块边界,则调用getStreamer().getBytesCurBlock() == blockSize) 方法:

endBlock()

这将确保当前块关闭并从/** * if encountering a block boundary, send an empty packet to * indicate the end of block and reset bytesCurBlock. * * @throws IOException */ protected void endBlock() throws IOException { if (getStreamer().getBytesCurBlock() == blockSize) { setCurrentPacketToEmpty(); enqueueCurrentPacket(); getStreamer().setBytesCurBlock(0); lastFlushOffset = 0; } } 获取新块以写入数据。

块大小由Name Node文件中的dfs.blocksize参数确定(在我的群集中设置为128 MB = 134217728):

hdfs-site.xml

答案 1 :(得分:0)

它不是一个执行拆分文件功能的jar / java文件。它是执行此任务的客户端守护程序。当您从本地加载文件时,客户端首先只读取128MB,它通过询问namenode找到存储它的位置,并确保正确复制和复制该文件。此阶段的客户端不知道文件的实际大小,除非它以相同的方式读取所有块。

当您要存储文件时,hdfs不会使用您提到的FileInputFormat.java。当您要在该文件上运行任何mapreduce任务时使用它。它与文件存储无关。