java 写tb级文件_三管齐下!TB 级文件的上传性能瞬间被优化 100 倍!
作者 | 中華石杉
責(zé)編 | 伍杏玲
本文經(jīng)授權(quán)轉(zhuǎn)載石杉的架構(gòu)筆記(ID:shishan100)
這篇文章我們來看看,世界上最優(yōu)秀的分布式文件系統(tǒng)HDFS,是如何對(duì)超大文件的上傳做性能優(yōu)化的?
首先,我們還是通過一張圖來看一下文件上傳的大概的原理。
由上圖所示,文件上傳的原理,其實(shí)說出來也簡(jiǎn)單。
比如有個(gè)TB級(jí)的大文件,太大了,HDFS客戶端會(huì)給拆成很多block,一個(gè)block就是128MB。
這個(gè)HDFS客戶端你可以理解為是云盤系統(tǒng)、日志采集系統(tǒng)之類的東西。
比如有人上傳一個(gè)1TB的大文件到網(wǎng)盤,或者是上傳個(gè)1TB的大日志文件。
然后,HDFS客戶端把一個(gè)一個(gè)的block上傳到第一個(gè)DataNode
第一個(gè)DataNode會(huì)把這個(gè)block復(fù)制一份,做一個(gè)副本發(fā)送給第二個(gè)DataNode。
第二個(gè)DataNode發(fā)送一個(gè)block副本到第三個(gè)DataNode。
所以你會(huì)發(fā)現(xiàn),一個(gè)block有3個(gè)副本,分布在三臺(tái)機(jī)器上。任何一臺(tái)機(jī)器宕機(jī),數(shù)據(jù)是不會(huì)丟失的。
最后,一個(gè)TB級(jí)大文件就被拆散成了N多個(gè)MB級(jí)的小文件存放在很多臺(tái)機(jī)器上了,這就是分布式存儲(chǔ)。
原始的文件上傳方案
今天要討論的問題,就是HDFS客戶端上傳TB級(jí)大文件時(shí)候,是怎么上傳呢?
我們先來考慮一下,如果用一個(gè)比較原始的方式來上傳,應(yīng)該怎么做?
大概能想到的是下面這個(gè)圖里的樣子。
很多Java的初學(xué)者,估計(jì)都知道這樣來上傳文件。
其實(shí)無非就是不停的從本地磁盤文件用輸入流讀取數(shù)據(jù),讀到一點(diǎn),就立馬通過網(wǎng)絡(luò)的輸出流寫到DataNode里去。
上面這種流程圖的代碼,估計(jì)剛畢業(yè)的同學(xué)都可以立馬寫出來。因?yàn)閷?duì)文件的輸入流最多就是個(gè)FileInputStream。而對(duì)DataNode的輸出流,最多就是個(gè)Socket返回的OutputStream。
然后中間找一個(gè)小的內(nèi)存byte[]數(shù)組,進(jìn)行流對(duì)拷就行了,從本地文件讀一點(diǎn)數(shù)據(jù),就給DataNode發(fā)一點(diǎn)數(shù)據(jù)。
但是如果你要這么弄,性能是極其低下的,網(wǎng)絡(luò)通信講究的是適當(dāng)頻率,每次batch批量發(fā)送。
你得讀一大批數(shù)據(jù),通過網(wǎng)絡(luò)通信發(fā)一批數(shù)據(jù),不能說讀一點(diǎn)點(diǎn)數(shù)據(jù),就立馬來一次網(wǎng)絡(luò)通信,就發(fā)出去這一點(diǎn)點(diǎn)的數(shù)據(jù)。
所以如果按照上面這種原始的方式,絕對(duì)會(huì)導(dǎo)致網(wǎng)絡(luò)通信效率極其低下,大文件上傳性能很差,為什么這么說?
相當(dāng)于你可能剛讀出來幾百個(gè)字節(jié)的數(shù)據(jù),立馬就寫網(wǎng)絡(luò),卡頓個(gè)比如幾百毫秒。
然后再讀下一批幾百個(gè)字節(jié)的數(shù)據(jù),再寫網(wǎng)絡(luò)卡頓個(gè)幾百毫秒,這個(gè)性能很差,在工業(yè)級(jí)的大規(guī)模分布式系統(tǒng)中,是無法容忍的。
如何對(duì)大文件上傳進(jìn)行性能優(yōu)化?
好,看完了原始的文件上傳,我們來看看Hadoop中分布式文件系統(tǒng)HDFS,是如何對(duì)大文件上傳進(jìn)行性能優(yōu)化的?
一起來看看下面那張圖。
首先你需要自己創(chuàng)建一個(gè)針對(duì)本地TB級(jí)磁盤文件的輸入流,然后讀到數(shù)據(jù)之后立馬寫入HDFS提供的FSDataOutputStream輸出流。
這個(gè)FSDataOutputStream輸出流在干啥?大家覺得他會(huì)天真的立馬把數(shù)據(jù)通過網(wǎng)絡(luò)傳輸寫給DataNode嗎?
答案當(dāng)然是否定的了!這么干的話,不就跟之前的那種方式一樣了!
1.??Chunk緩沖機(jī)制
首先,數(shù)據(jù)會(huì)被寫入一個(gè)chunk緩沖數(shù)組,這個(gè)chunk是一個(gè)512字節(jié)大小的數(shù)據(jù)片段,你可以這么來理解。
然后這個(gè)緩沖數(shù)組可以容納多個(gè)chunk大小的數(shù)據(jù)在里面緩沖。
光是這個(gè)緩沖,首先就可以讓客戶端快速的寫入數(shù)據(jù)了,不至于說幾百字節(jié)就要進(jìn)行一次網(wǎng)絡(luò)傳輸,想一想,是不是這樣?
2.?Packet數(shù)據(jù)包機(jī)制
接著,當(dāng)chunk緩沖數(shù)組都寫滿了之后,就會(huì)把這個(gè)chunk緩沖數(shù)組進(jìn)行一下chunk切割,切割為一個(gè)一個(gè)的chunk,一個(gè)chunk是一個(gè)數(shù)據(jù)片段。
然后多個(gè)chunk會(huì)直接一次性寫入另外一個(gè)內(nèi)存緩沖數(shù)據(jù)結(jié)構(gòu),就是Packet數(shù)據(jù)包
一個(gè)Packet數(shù)據(jù)包,設(shè)計(jì)為可以容納127個(gè)chunk,大小大致為64mb。所以說大量的chunk會(huì)不斷的寫入Packet數(shù)據(jù)包的內(nèi)存緩沖中。
通過這個(gè)Packet數(shù)據(jù)包機(jī)制的設(shè)計(jì),又可以在內(nèi)存中容納大量的數(shù)據(jù),進(jìn)一步避免了頻繁的網(wǎng)絡(luò)傳輸影響性能
3.?內(nèi)存隊(duì)列異步發(fā)送機(jī)制
當(dāng)一個(gè)Packet被塞滿了chunk之后,就會(huì)將這個(gè)Packet放入一個(gè)內(nèi)存隊(duì)列來進(jìn)行排隊(duì)。
然后有一個(gè)DataStreamer線程會(huì)不斷的獲取隊(duì)列中的Packet數(shù)據(jù)包,通過網(wǎng)絡(luò)傳輸直接寫一個(gè)Packet數(shù)據(jù)包給DataNode。
如果一個(gè)Block默認(rèn)是128mb的話,那么一個(gè)Block默認(rèn)會(huì)對(duì)應(yīng)兩個(gè)Packet數(shù)據(jù)包,每個(gè)Packet數(shù)據(jù)包是64MB。
也就是說,傳送兩個(gè)Packet數(shù)據(jù)包給DataNode之后,就會(huì)發(fā)一個(gè)通知說,一個(gè)Block的數(shù)據(jù)都傳輸完畢。
這樣DataNode就知道自己收到一個(gè)Block了,里面包含了人家發(fā)送過來的兩個(gè)Packet數(shù)據(jù)包。
總結(jié)
OK,大家看完了上面的那個(gè)圖以及Hadoop的HDFS采取的大文件上傳機(jī)制,是不是感覺設(shè)計(jì)的很巧妙?
說白了,工業(yè)級(jí)的大規(guī)模分布式系統(tǒng),都不會(huì)采取特別簡(jiǎn)單的代碼和模式,那樣性能很低下。
這里都有大量的并發(fā)優(yōu)化、網(wǎng)絡(luò)IO優(yōu)化、內(nèi)存優(yōu)化、磁盤讀寫優(yōu)化的架構(gòu)設(shè)計(jì)、生產(chǎn)方案在里面。
所以大家觀察上面那個(gè)圖,HDFS客戶端可以快速的將TB級(jí)大文件的數(shù)據(jù)讀出來,然后快速的交給HDFS的輸出流寫入內(nèi)存。
基于內(nèi)存里的chunk緩沖機(jī)制、packet數(shù)據(jù)包機(jī)制、內(nèi)存隊(duì)列異步發(fā)送機(jī)制。絕對(duì)不會(huì)有任何網(wǎng)絡(luò)傳輸?shù)目D,導(dǎo)致大文件的上傳速度變慢。
反而通過上述幾種機(jī)制,可以上百倍的提升一個(gè)TB級(jí)大文件的上傳性能。
作者簡(jiǎn)介:中華石杉,十余年BAT架構(gòu)經(jīng)驗(yàn)傾囊相授
公眾號(hào):石杉的架構(gòu)筆記(ID:shishan100)
熱 文?推 薦
你點(diǎn)的每個(gè)“在看”,我都認(rèn)真當(dāng)成了喜歡
總結(jié)
以上是生活随笔為你收集整理的java 写tb级文件_三管齐下!TB 级文件的上传性能瞬间被优化 100 倍!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【笔记】《离散数学》第十章 递推方程与生
- 下一篇: halcon修改程序框字体大小