[英]Which Java file does Hadoop HDFS file splitting into Blocks
眾所周知,當將本地文本文件復制到HDFS時,該文件將被拆分為固定大小的128 MB。 例如,當我將256 MB的文本文件復制到HDFS中時,將有2個塊(256/128)包含“分割的”文件。
有人可以告訴我Hadoop 2.7.1源代碼中的哪個java / jar文件執行將文件拆分為塊的功能,以及哪個java / jar文件將這些塊寫入datanode的目錄中。
幫我追蹤這段代碼。
我只找到了他們對FileInputFormat.java中找到的塊進行邏輯輸入拆分的地方,這不是我所需要的。 我需要將Java文件用於拆分的物理文件。
將數據寫入DataNodes的代碼位於2個文件中:
DFSOutputStream.java
(包: org.apache.hadoop.hdfs
)
客戶端寫入的數據被拆分為數據包(通常為64k大小)。 當數據包准備就緒時,數據將排隊入數據隊列,由DataStreamer
拾取。
DataStreamer
(軟件包: org.apache.hadoop.hdfs
)
它拾取數據隊列中的數據包並將其發送到管道中的數據節點(由於復制因子3,通常數據管道中有3個數據節點)。
它檢索一個新的塊ID,然后開始將數據流傳輸到數據節點。 寫入數據塊時,它將關閉當前塊並獲得一個新塊,用於寫入下一組數據包。
下面是獲得新塊的代碼:
// 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
不斷將數據追加到塊中,因此它更新了寫入的字節數。
/**
* 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
獲得一個新塊以寫入數據。
塊大小由hdfs-site.xml
文件中的dfs.blocksize
參數確定(在我的集群中設置為128 MB = 134217728):
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
<description>The default block size for new files, in bytes.
You can use the following suffix (case insensitive): k(kilo),
m(mega), g(giga), t(tera), p(peta), e(exa) to specify the
size (such as 128k, 512m, 1g, etc.), Or provide complete size
in bytes (such as 134217728 for 128 MB).
</description>
</property>
它不是一個jar / java文件,它具有拆分文件的功能。 客戶端守護程序執行此任務。 當您從本地加載文件時,客戶端僅讀取128MB,它通過詢問namenode來找到一個存儲位置,並且還可以確保文件已正確復制和復制。 客戶端在此階段不知道文件的實際大小,除非它要以相同的方式讀取所有塊。
當您要存儲文件時,hdfs不會使用您提到的FileInputFormat.java。 當您要在該文件上運行任何mapreduce任務時使用它。 它與文件的存儲無關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.