當前位置:
首頁 > 知識 > TB級文件的上傳性能瞬間被優化了100倍!

TB級文件的上傳性能瞬間被優化了100倍!

一、寫在前面

這篇文章我們來看看,世界上最優秀的分散式文件系統HDFS,是如何對超大文件的上傳做性能優化的?

首先,我們還是通過一張圖來看一下文件上傳的大概的原理。

由上圖所示,文件上傳的原理,其實說出來也簡單。

比如有個TB級的大文件,太大了,HDFS客戶端會給拆成很多block,一個block就是128MB。

這個HDFS客戶端你可以理解為是雲盤系統、日誌採集系統之類的東西。

比如有人上傳一個1TB的大文件到網盤,或者是上傳個1TB的大日誌文件。

然後,HDFS客戶端把一個一個的block上傳到第一個DataNode

第一個DataNode會把這個block複製一份,做一個副本發送給第二個DataNode。

第二個DataNode發送一個block副本到第三個DataNode。

所以你會發現,一個block有3個副本,分布在三台機器上。任何一台機器宕機,數據是不會丟失的。

最後,一個TB級大文件就被拆散成了N多個MB級的小文件存放在很多台機器上了,這就是分散式存儲

二、原始的文件上傳方案

今天要討論的問題,就是HDFS客戶端上傳TB級大文件時候,是怎麼上傳呢?

我們先來考慮一下,如果用一個比較原始的方式來上傳,應該怎麼做?

大概能想到的是下面這個圖裡的樣子。

很多java的初學者,估計都知道這樣來上傳文件。

其實無非就是不停的從本地磁碟文件用輸入流讀取數據,讀到一點,就立馬通過網路的輸出流寫到DataNode里去。

上面這種流程圖的代碼,估計剛畢業的同學都可以立馬寫出來。因為對文件的輸入流最多就是個FileInputStream。而對DataNode的輸出流,最多就是個Socket返回的OutputStream。

然後中間找一個小的內存byte[]數組,進行流對拷就行了,從本地文件讀一點數據,就給DataNode發一點數據。

但是如果你要這麼弄,性能是極其低下的,網路通信講究的是適當頻率,每次batch批量發送。

你得讀一大批數據,通過網路通信發一批數據,不能說讀一點點數據,就立馬來一次網路通信,就發出去這一點點的數據。

所以如果按照上面這種原始的方式,絕對會導致網路通信效率極其低下,大文件上傳性能很差,為什麼這麼說?

相當於你可能剛讀出來幾百個位元組的數據,立馬就寫網路,卡頓個比如幾百毫秒。

然後再讀下一批幾百個位元組的數據,再寫網路卡頓個幾百毫秒,這個性能很差,在工業級的大規模分散式系統中,是無法容忍的。

三、如何對大文件上傳進行性能優化?

好,看完了原始的文件上傳,我們來看看Hadoop中分散式文件系統HDFS,是如何對大文件上傳進行性能優化的?

一起來看看下面那張圖。

首先你需要自己創建一個針對本地TB級磁碟文件的輸入流,然後讀到數據之後立馬寫入HDFS提供的FSDataOutputStream輸出流。

這個FSDataOutputStream輸出流在幹啥?大家覺得他會天真的立馬把數據通過網路傳輸寫給DataNode嗎?

答案當然是否定的了!這麼乾的話,不就跟之前的那種方式一樣了!

1. Chunk緩衝機制

首先,數據會被寫入一個chunk緩衝數組,這個chunk是一個512位元組大小的數據片段,你可以這麼來理解。

然後這個緩衝數組可以容納多個chunk大小的數據在裡面緩衝。

光是這個緩衝,首先就可以讓客戶端快速的寫入數據了,不至於說幾百位元組就要進行一次網路傳輸,想一想,是不是這樣?

2. Packet數據包機制

接著,當chunk緩衝數組都寫滿了之後,就會把這個chunk緩衝數組進行一下chunk切割,切割為一個一個的chunk,一個chunk是一個數據片段。

然後多個chunk會直接一次性寫入另外一個內存緩衝數據結構,就是Packet數據包

一個Packet數據包,設計為可以容納127個chunk,大小大致為64mb。所以說大量的chunk會不斷的寫入Packet數據包的內存緩衝中。

通過這個Packet數據包機制的設計,又可以在內存中容納大量的數據,進一步避免了頻繁的網路傳輸影響性能

3. 內存隊列非同步發送機制

當一個Packet被塞滿了chunk之後,就會將這個Packet放入一個內存隊列來進行排隊。

然後有一個DataStreamer線程會不斷的獲取隊列中的Packet數據包,通過網路傳輸直接寫一個Packet數據包給DataNode。

如果一個Block默認是128mb的話,那麼一個Block默認會對應兩個Packet數據包,每個Packet數據包是64MB。

也就是說,傳送兩個Packet數據包給DataNode之後,就會發一個通知說,一個Block的數據都傳輸完畢。

這樣DataNode就知道自己收到一個Block了,裡面包含了人家發送過來的兩個Packet數據包。

四、總結

OK,大家看完了上面的那個圖以及Hadoop的HDFS採取的大文件上傳機制,是不是感覺設計的很巧妙?

說白了,工業級的大規模分散式系統,都不會採取特別簡單的代碼和模式,那樣性能很低下。

這裡都有大量的並發優化、網路IO優化、內存優化、磁碟讀寫優化的架構設計、生產方案在裡面。

所以大家觀察上面那個圖,HDFS客戶端可以快速的將tb級大文件的數據讀出來,然後快速的交給HDFS的輸出流寫入內存。

基於內存里的chunk緩衝機制、packet數據包機制、內存隊列非同步發送機制。絕對不會有任何網路傳輸的卡頓,導致大文件的上傳速度變慢。

反而通過上述幾種機制,可以上百倍的提升一個TB級大文件的上傳性能。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 千鋒JAVA開發學院 的精彩文章:

Redis分散式鎖的try-with-resources實現
Pipenv:Python包管理神器

TAG:千鋒JAVA開發學院 |