【性能優化的祕密】Hadoop如何將TB級大文件的上傳性能優化上百倍

歡迎關注微信公衆號:石杉的架構筆記(id:shishan100)java

個人新課**《C2C 電商系統微服務架構120天實戰訓練營》在公衆號儒猿技術窩**上線了,感興趣的同窗,能夠點擊下方連接瞭解詳情:數組

《C2C 電商系統微服務架構120天實戰訓練營》性能優化

目錄

1、寫在前面微信

2、原始的文件上傳方案markdown

3、大規模分佈式系統對大文件上傳的性能優化網絡

(1)Chunk緩衝機制數據結構

(2)Packet數據包機制多線程

(3)內存隊列異步發送機制架構

4、總結併發

1、寫在前面

上一篇文章,咱們聊了一下Hadoop中的NameNode裏的edits log寫機制。

主要分析了edits log寫入磁盤和網絡的時候,是如何經過分段加鎖以及雙緩衝的機制,大幅度提高了多線程併發寫edits log的吞吐量,從而支持高併發的訪問。

若是沒看那篇文章的同窗,能夠回看一下:大規模集羣下Hadoop NameNode如何承載每秒上千次的高併發訪問。

這篇文章,咱們來看看,Hadoop的HDFS分佈式文件系統的文件上傳的性能優化。

首先,咱們仍是經過一張圖來回顧一下文件上傳的大概的原理。

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

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

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

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

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

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

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

因此你會發現,一個block有3個副本,分佈在三臺機器上。任何一臺機器宕機,數據是不會丟失的。

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

2、原始的文件上傳方案

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

咱們先來考慮一下,若是用一個比較原始的方式來上傳,應該怎麼作?

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

不少java的初學者,估計都知道這樣來上傳文件,其實無非就是不停的從本地磁盤文件用輸入流讀取數據,讀到一點,就立馬經過網絡的輸出流寫到DataNode裏去。

上面這種流程圖的代碼,估計剛畢業的同窗均可以立馬寫出來。由於對文件的輸入流最多就是個FileInputStream。

而對DataNode的輸出流,最多就是個Socket返回的OutputStream。

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

可是若是你要這麼弄,那性能真是極其的低下了,網絡通訊講究的是適當頻率,每次batch批量發送,你得讀一大批數據,經過網絡通訊發一批數據。

不能說讀一點點數據,就立馬來一次網絡通訊,就發出去這一點點的數據。

若是按照上面這種原始的方式,絕對會致使網絡通訊效率極其低下,大文件上傳性能不好。

爲何這麼說呢?

至關於你可能剛讀出來幾百個字節的數據,立馬就寫網絡,卡頓個好比幾百毫秒。

而後再讀下一批幾百個字節的數據,再寫網絡卡頓個幾百毫秒,這個性能不好,在工業級的大規模分佈式系統中,是沒法容忍的

3、分佈式系統對大文件上傳的性能優化

好,看完了原始的文件上傳,那麼咱們來看看,Hadoop中的大文件上傳是如何優化性能的呢?一塊兒來看看下面那張圖。

首先你須要本身建立一個針對本地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數據包。

4、總結

OK,你們看完了上面的那個圖以及Hadoop採起的大文件上傳機制,是否是感受設計的很巧妙?

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

這裏都有大量的併發優化、網絡IO優化、內存優化、磁盤讀寫優化的架構設計、生產方案在裏面。

因此你們觀察上面那個圖,HDFS客戶端能夠快速的將tb級大文件的數據讀出來,而後快速的交給HDFS的輸出流寫入內存。

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

反而經過上述幾種機制,能夠上百倍的提高一個TB級大文件的上傳性能。

若有收穫,請幫忙轉發,您的鼓勵是做者最大的動力,謝謝!

一大波微服務、分佈式、高併發、高可用的****原創系列

文章正在路上,歡迎掃描下方二維碼,持續關注:

石杉的架構筆記(id:shishan100)

十餘年BAT架構經驗傾囊相授

相關文章
相關標籤/搜索