前言
本文主要介紹以下內(nèi)容:
DFSOutputStream里的一些重要方法的作用
DFSOutputStream里關(guān)于寫Packet的一些有趣的配置項(xiàng)。
重要方法
abort: 終止這個(gè)輸出流淹遵,并且釋放這個(gè)流相關(guān)的所有系統(tǒng)資源私杜。
newStreamForCreate: 生成一個(gè)用于創(chuàng)建文件的輸出流欠气。
initWritePacketSize: 用于確保配置的writePacketSize永遠(yuǎn)不要超過PacketReceiver.MAX_PACKET_SIZE(16MB)。
adjustChunkBoundary: 用于調(diào)整chunk的邊界 。
adjustPacketChunkSize: 用于調(diào)整Packet的chunk size。是用于append操作的場景恋日,調(diào)整要追加數(shù)據(jù)時(shí),最后一個(gè)block的chunk位置嘹狞。例如在append之前岂膳,最后一個(gè)block的最后一個(gè)chunk不滿512字節(jié)(我們管它叫partial chunk),沒有生成checksum磅网,這時(shí)候就會(huì)調(diào)整chunksize谈截,讓append的下一個(gè)Packet只包含一個(gè)chunk來fill up這個(gè)partial chunk(setChecksumBufSize),append之后的數(shù)據(jù)和append之前的數(shù)據(jù)共同構(gòu)成一個(gè)完整的chunk。
enqueueCurrentPacketFull: 當(dāng)packet full的時(shí)候(達(dá)到了packet所能容納的max chunk數(shù)或者getBytesCurBlock==blocksize時(shí))簸喂,就要把這個(gè)full packet嘗試入隊(duì)dataQueue毙死。
endBlock: 如果遇到了block的邊界,發(fā)送一個(gè)empty packet來指示block的結(jié)束喻鳄,重置bytesCurBlock字段扼倘。
setCurrentPacketToEmpty: 創(chuàng)建一個(gè)empty packet 標(biāo)記end of block。
enqueueCurrentPacket: 將DFSOutputStream的currentPacket變量指向的DFSPacket對象入隊(duì)到關(guān)聯(lián)的DataStreamer#dataQueue里除呵。入隊(duì)成功后再菊,將currentPacket置為null。
關(guān)于chunk竿奏、packet的一些日志
2023-12-14 15:34:06,036 [main] INFO hdfs.DFSClient (DFSOutputStream.java:writeChunkPrepare(496)) - WriteChunk allocating new packet seqno=3, src=/f, packetSize=65016, chunksPerPacket=126, bytesCurBlock=9728, output stream=DFSOutputStream:blk_1073741825_1001
packetSize是65016字節(jié)袄简。
每個(gè)packet里chunks個(gè)數(shù)是126個(gè)。
所以每個(gè)chunk的大小是:65016/126 = 516字節(jié)泛啸。(512字節(jié)的data + 4字節(jié)checksum)
解釋一下這里為啥是126個(gè)绿语。 結(jié)合dfs.client-write-packet-size
這個(gè)配置項(xiàng)65536來看。
65536首先要減去MAX_PACKET_HEEADER_LEN(=6)候址,之后變成65530吕粹。
65530/516 等于126.99x,不夠127個(gè)整Chunk岗仑。所以每個(gè)Packet有126個(gè)chunk匹耕。
有趣的一些配置項(xiàng)
第一個(gè):dfs.client.write.max-packets-in-flight
, 默認(rèn)值80荠雕。表示dataQueue和ackQueue里的DFSPacket個(gè)數(shù)和的上限值稳其。 如果OutputStream寫滿一個(gè)packet的數(shù)據(jù)后,想要把這個(gè)DFSPacket入隊(duì)到dataQueue里炸卑,就必須滿足dataQueue和ackQueue里的DFSPacket個(gè)數(shù)小于等于80時(shí)才行既鞠,否則就wait,等待條件滿足盖文。
<property>
<name>dfs.client.write.max-packets-in-flight</name>
<value>80</value>
<description>
The maximum number of DFSPackets allowed in flight.
</description>
</property>
第二個(gè):dfs.client-write-packet-size
嘱蛋,默認(rèn)值65536(即64KB)。表示一個(gè)DFSPacket的size五续。
<property>
<name>dfs.client-write-packet-size</name>
<value>65536</value>
<description>Packet size for clients to write</description>
</property>
dfs.bytes-per-checksum
dfs.stream-buffer-size
dfs.data.transfer.max.packet.size