MR架構&文件格式優缺點&壓縮格式優缺點&spilt -> map task關係&wordcount&shuffle的理解

MapReduce是什麼

mapreduce分爲map階段和reduce階段
map階段是映射 生產上可以對於此進行調優,比如合併小文件
reduce階段是聚合 生產上默認是生成1個文件

mr2.x架構設計(mr on yarn 流程)

Yarn介紹

yarn包括RM和NM

  • RM
    RM包括兩部分
    1、applications Manager 應用程序管理器
    2、resoure schedule 資源memory+cpu調度器
  • NM
    NM上的紅色框是container
    container是虛擬的概念,屬於NM節點上,專門用來做mr、spark計算的最小單元;maptask和reducetask都運行在container上

mr on yarn 流程簡單介紹

1、啓動App Master,分配資源
2、運行任務,直到任務結束

mr on yarn流程詳細介紹

第一階段:
1、用戶向yarn提交應用程序(也叫job app application),jar、sql,其中包括App Master應用程序,啓動AppMaster的命令等等
2、RM爲該job分配第一個container,用來運行job的AppMaster
3、App Master會向RM的applications manager進行註冊,使得可以再RM web界面查看job的運行狀態
4、App Master採用輪詢的方式通過rpc協議向RM申請資源和領取資源


第二階段:
5、一旦App Master拿到資源,就對應的跟NM進行通信,要求啓動任務
6、NM爲任務設置好運行環境(jar等),將任務啓動命令封裝在一個腳本里,並通過該腳本啓動task
7、各個task通過rpc協議向App Master彙報自己的狀態和進度,以此讓App Master隨時掌握各個task的運行狀態,從而在task運行失敗時重啓任務
8、運行完後,App Master向RM的applications Manager註銷並關閉自己
在這裏插入圖片描述

文件格式有哪些優缺點

面向行

面向行:同一行的數據存儲在一起,即連續存儲。SequenceFile,MapFile,Avro Datafile。採用這種方式,如果只需要訪問行的一小部分數據,亦需要將整行讀入內存,推遲序列化一定程度上可以緩解這個問題,但是從磁盤讀取整行數據的開銷卻無法避免。面向行的存儲適合於整行數據需要同時處理的情況。

面向列

面向列:整個文件被切割爲若干列數據,每一列數據一起存儲。Parquet , RCFile,ORCFile。面向列的格式使得讀取數據時,可以跳過不需要的列,適合於只處於行的一小部分字段的情況。但是這種格式的讀寫需要更多的內存空間,因爲需要緩存行在內存中(爲了獲取多行中的某一列)。同時不適合流式寫入,因爲一旦寫入失敗,當前文件無法恢復,而面向行的數據在寫入失敗時可以重新同步到最後一個同步點

壓縮格式有哪些優缺點

壓縮的好處和壞處

  • 好處
    減少存儲磁盤空間
    降低IO(網絡的IO和磁盤的IO)
    加快數據在磁盤和網絡中的傳輸速度,從而提高系統的處理速度
  • 壞處
    由於使用數據時,需要先將數據解壓,加重CPU負荷

壓縮格式

在這裏插入圖片描述

壓縮比

在這裏插入圖片描述

壓縮時間

在這裏插入圖片描述

可以看出,壓縮比越高,壓縮時間越長,壓縮比:Snappy>LZ4>LZO>GZIP>BZIP2

壓縮格式的優缺點

壓縮格式 優點 缺點
gzip 壓縮比在四種壓縮方式中較高;hadoop本身支持,在應用中處理gzip格式的文件就和直接處理文本一樣;有hadoop native庫;大部分linux系統都自帶gzip命令,使用方便 不支持split
lzo 壓縮/解壓速度也比較快,合理的壓縮率;支持split,是hadoop中最流行的壓縮格式;支持hadoop native庫;需要在linux系統下自行安裝lzop命令,使用方便 壓縮率比gzip要低;hadoop本身不支持,需要安裝;lzo雖然支持split,但需要對lzo文件建索引,否則hadoop也是會把lzo文件看成一個普通文件(爲了支持split需要建索引,需要指定inputformat爲lzo格式)
snappy 壓縮速度快;支持hadoop native庫 不支持split;壓縮比低;hadoop本身不支持,需要安裝;linux系統下沒有對應的命令d. bzip2
bzip2 支持split;具有很高的壓縮率,比gzip壓縮率都高;hadoop本身支持,但不支持native;在linux系統下自帶bzip2命令,使用方便 壓縮/解壓速度慢;不支持native

總結:

不同的場景選擇不同的壓縮方式,肯定沒有一個一勞永逸的方法,如果選擇高壓縮比,那麼對於cpu的性能要求要高,同時壓縮、解壓時間耗費也多;選擇壓縮比低的,對於磁盤io、網絡io的時間要多,空間佔據要多;對於支持分割的,可以實現並行處理。

應用場景:

一般在HDFS 、Hive、HBase中會使用;
當然一般較多的是結合Spark 來一起使用。

spilt -> map task關係

reduce task 默認個數爲1,map task默認個數爲2,map task的個數又與切片個數保持一致,切片是按照默認block大小進行切片,而切片數又與文件數和文件大小有關,切片默認大小決定文件被分成多少個切片,執行多少個map task,這也是生產上優化的一個點;

  • 例如如果一個文件很小,不到一個block塊大小
    比如有一個文件爲1.log 大小爲86字節那麼,他會被切分成1塊,map task數量爲1
  • 假如有兩個文件爲1.log 2.log 大小分別爲86字節和150M,這兩個文件會被切成3塊,map task 數量爲3
  • 參數在mapred-default.xml設置
key value
mapreduce.job.maps 2
mapreduce.job.reduces 1

wordcount

在這裏插入圖片描述

輸入分片(input split)

在進行map計算之前,mapreduce會根據輸入文件計算輸入分片(input split),每個輸入分片(input split)針對一個map任務,輸入分片(input split)存儲的並非數據本身,而是一個分片長度和一個記錄數據的位置的數組,輸入分片(input split)往往和hdfs的block(塊)關係很密切,假如我們設定hdfs的塊的大小是64mb,如果我們輸入有三個文件,大小分別是3mb、65mb和127mb,那麼mapreduce會把3mb文件分爲一個輸入分片(input split),65mb則是兩個輸入分片(input split)而127mb也是兩個輸入分片(input split),換句話說我們如果在map計算前做輸入分片調整,例如合併小文件,那麼就會有5個map任務將執行,而且每個map執行的數據大小不均,這個也是mapreduce優化計算的一個關鍵點。

map階段

就是程序員編寫好的map函數了,因此map函數效率相對好控制,而且一般map操作都是本地化操作也就是在數據存儲節點上進行;

combiner階段

combiner階段是程序員可以選擇的,combiner其實也是一種reduce操作,因此我們看見WordCount類裏是用reduce進行加載的。Combiner是一個本地化的reduce操作,它是map運算的後續操作,主要是在map計算出中間文件前做一個簡單的合併重複key值的操作,例如我們對文件裏的單詞頻率做統計,map計算時候如果碰到一個hadoop的單詞就會記錄爲1,但是這篇文章裏hadoop可能會出現n多次,那麼map輸出文件冗餘就會很多,因此在reduce計算前對相同的key做一個合併操作,那麼文件會變小,這樣就提高了寬帶的傳輸效率,畢竟hadoop計算力寬帶資源往往是計算的瓶頸也是最爲寶貴的資源,但是combiner操作是有風險的,使用它的原則是combiner的輸入不會影響到reduce計算的最終輸入,例如:如果計算只是求總數,最大值,最小值可以使用combiner,但是做平均值計算使用combiner的話,最終的reduce計算結果就會出錯。

shuffle階段

將map的輸出作爲reduce的輸入的過程就是shuffle了,這個是mapreduce優化的重點地方。這裏我不講怎麼優化shuffle階段,講講shuffle階段的原理,因爲大部分的書籍裏都沒講清楚shuffle階段。Shuffle一開始就是map階段做輸出操作,一般mapreduce計算的都是海量數據,map輸出時候不可能把所有文件都放到內存操作,因此map寫入磁盤的過程十分的複雜,更何況map輸出時候要對結果進行排序,內存開銷是很大的,map在做輸出時候會在內存裏開啓一個環形內存緩衝區,這個緩衝區專門用來輸出的,默認大小是100mb,並且在配置文件裏爲這個緩衝區設定了一個閥值,默認是0.80(這個大小和閥值都是可以在配置文件裏進行配置的),同時map還會爲輸出操作啓動一個守護線程,如果緩衝區的內存達到了閥值的80%時候,這個守護線程就會把內容寫到磁盤上,這個過程叫spill,另外的20%內存可以繼續寫入要寫進磁盤的數據,寫入磁盤和寫入內存操作是互不干擾的,如果緩存區被撐滿了,那麼map就會阻塞寫入內存的操作,讓寫入磁盤操作完成後再繼續執行寫入內存操作,前面我講到寫入磁盤前會有個排序操作,這個是在寫入磁盤操作時候進行,不是在寫入內存時候進行的,如果我們定義了combiner函數,那麼排序前還會執行combiner操作。每次spill操作也就是寫入磁盤操作時候就會寫一個溢出文件,也就是說在做map輸出有幾次spill就會產生多少個溢出文件,等map輸出全部做完後,map會合並這些輸出文件。這個過程裏還會有一個Partitioner操作,對於這個操作很多人都很迷糊,其實Partitioner操作和map階段的輸入分片(Input split)很像,一個Partitioner對應一個reduce作業,如果我們mapreduce操作只有一個reduce操作,那麼Partitioner就只有一個,如果我們有多個reduce操作,那麼Partitioner對應的就會有多個,Partitioner因此就是reduce的輸入分片,這個程序員可以編程控制,主要是根據實際key和value的值,根據實際業務類型或者爲了更好的reduce負載均衡要求進行,這是提高reduce效率的一個關鍵所在。到了reduce階段就是合併map輸出文件了,Partitioner會找到對應的map輸出文件,然後進行復制操作,複製操作時reduce會開啓幾個複製線程,這些線程默認個數是5個,程序員也可以在配置文件更改複製線程的個數,這個複製過程和map寫入磁盤過程類似,也有閥值和內存大小,閥值一樣可以在配置文件裏配置,而內存大小是直接使用reduce的tasktracker的內存大小,複製時候reduce還會進行排序操作和合並文件操作,這些操作完了就會進行reduce計算了。

reduce階段

和map函數一樣也是程序員編寫的,最終結果是存儲在hdfs上的。

shuffle的理解

1、maptask收集我們的map()方法輸出的kv對,放到內存緩衝區中
2、從內存緩衝區不斷溢出本地磁盤文件,可能會溢出多個文件
3、多個溢出文件會被合併成大的溢出文件
4、在溢出過程中,及合併的過程中,都要調用partitoner進行分組和針對key進行排序
5、reducetask根據自己的分區號,去各個maptask機器上取相應的結果分區數據
6、reducetask會取到同一個分區的來自不同maptask的結果文件,reducetask會將這些文件再進行合併(歸併排序)
7、合併成大文件後,shuffle的過程也就結束了,後面進入reducetask的邏輯運算過程(從文件中取出一個一個的鍵值對group,調用用戶自定義的reduce()方法)

Shuffle中的緩衝區大小會影響到mapreduce程序的執行效率,原則上說,緩衝區越大,磁盤io的次數越少,執行速度就越快
緩衝區的大小可以通過參數調整, 參數:io.sort.mb 默認100M

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章