1. 程式人生 > >大資料初學習之MapReduce理論概述

大資料初學習之MapReduce理論概述

Hadoop-MapReduce分散式計算整理

分散式開發思維與平行計算思維

引例1

假設有一個1T的大檔案,這個檔案的每一行是一個數字 環境:一臺伺服器,核數:48core 64G記憶體 需求:將大檔案排序,不管是正序還是倒序 思路:

  1. 將大檔案切成一個個的小檔案[一次磁碟IO],(按照行數來切,每個小檔案有十萬行資料)
  2. 把每個小檔案載入到伺服器中排序[一次磁碟IO](小檔案之間無序,內部有序)。
  3. 將小檔案歸併排序[一次磁碟IO],每個小檔案都讀到一個Buffer中,然後這些Buffer進行比較進行歸併,當Buffer裡面沒資料了,再繼續讀磁碟小檔案。

磁碟IO:把所有檔案讀一遍當作一次磁碟IO

如何用兩次磁碟IO搞定這件事情?分久必合

思路:

  1. 1T的檔案,根據數值範圍來切割大檔案。 比如,0-100的放在file1裡面,100-200的放在file2裡面。如果0-100的資料大於64G怎麼辦?那就再切一下,切成file1_0和file1_1。小檔案之間是有序的,小檔案內部無序。
  2. List item把每個小檔案載入到伺服器中排序[一次磁碟IO](小檔案之間有序,內部也有序)。假設需要的是升序,那麼file1,file2,file3合併成大檔案,如果需要的是倒序,那麼就倒著讀一下,直接輸出就可以了。如果file1_0和file1_1小檔案之間是無序的:進行一次歸併。如果這種現象普遍存在,那麼就把範圍再縮小一點。
引例2

有兩個檔案,fileA和fileB,分別有十億條url,每個url是64k 環境:一臺伺服器,核數:48core 64G記憶體 需求:找出同時出現在兩個檔案的url 思路:

  1. 要把這兩個大檔案拆成小檔案(假設是一千個)。怎麼拆? 拆分策略:計算每一個url的hashcode然後與1000取模,決定這一條url進入到哪一個小檔案中。保證:相同的url進入同一個小檔案中。(一次磁碟IO)
  2. 只需要比對兩個file拆出來的對應相同模的小檔案。因為hashcode是唯一的。(第二次磁碟IO)
如果改成給十臺伺服器

多節點的平行計算(多程序多執行緒計算) 切割fileA可以node1來做,切割fileB可以node2來做。也就是說,切割這一步可以兩臺伺服器平行計算。切出來以後,fileA的0-100號檔案對應fileB的0-100號檔案給node1,fileA的101-200號檔案對應fileB的101-200號檔案給node2以此類推。這樣每臺伺服器只用比對100對檔案。

MapReduce思想

有三個山頭,都種有橡木,紅木和樟木。有三個工人,讓這三個工人去每個山頭上工作(計算找資料)。[為什麼不把山頭搬到他家(資料找計算)?資料量過於龐大,資料找計算將出現頻繁的資料運輸,造成較低的計算效率]。有個加工廠,分別加工橡木,樟木和紅木的桌子。如何提高效率?採用分久必合思想。

工人1工人1工人1工人2工人2工人2工人3工人3工人3山頭1橡木桌面桌腿橡木半成品紅木桌面桌腿紅木半成品樟木桌面桌腿樟木半成品山頭2橡木桌面桌腿橡木半成品紅木桌面桌腿紅木半成品樟木桌面桌腿樟木半成品山頭3橡木桌面桌腿橡木半成品紅木桌面桌腿紅木半成品樟木桌面桌腿樟木半成品橡木工廠紅木工廠樟木工廠
  1. 刪減無用的運輸 在各個山頭上爭取把每一棵樹都製作成有用的木材。eg:加工成桌面,桌腿。把廢料下腳料扔在山上。

  2. 減少搬運次數(Combiner) 在山頭上進行簡單的組裝,組裝成半成品(假設每個山頭的樹木不夠做一個桌子),減少搬運次數。

Combiner目的:減少每個山頭的輸出資料,減少網路IO。 [傳輸的過程最耗時]

  1. 每個工廠將各個工人的半成品進行組裝,得到成品。

注: 在MapReduce中,大山就是一個大檔案 每一個山頭代表一個block 每一個工人類比成執行緒(計算) 【程序本身不能計算,程序中的執行緒提供計算。程序為執行緒提供了一個環境–CPU,記憶體,磁碟環境】 總結:MapReduce由Map和Reuce組成。 combiner:工人在每一個山頭的組裝(處理的是每一個元件進行小組裝) shuffle:將半成品運輸到各個工廠(會有網路IO,最耗時間) reduce:將運輸過來的半成品進行大組裝(大合併)

MapReduce

MapReduce是一個便於編寫程式的可以通過大叢集(上千臺節點)並行處理TB級的海量資料的並通過可靠穩定的,容錯的機制執行的軟體框架。

MapReduce主要思想:分久必合
MapReduce核心思想

"相同"的key為一組,呼叫一次reduce方法,方法內迭代這一組資料進行計算

MapReduce由兩階段組成
shuffleMap端Reduce端在shuffle之前Map之後進行combiner
MapReduce原理

在這裡插入圖片描述

假設計算的資料在HDFS上以block塊形式儲存。 在上圖中,有四個工人(MapTask),三個加工廠(ReduceTask)。 在HDFS裡每一個block對應每一個MapTask

  1. MapReduce在計算HDFS資料之前會先對檔案進行切片(split),預設大小與block一致。 如果設定切片大小為256M,那麼一個切片對應2個block,此時一個MapTask處理2個block。

預設block<–>spilt<–>map task 想要map端的並行度越高:就要讓切片越小。 eg:如果把切片設定成64M,那麼1/2個block對應一個split。 那麼兩個MapTask處理一個block資料。

  1. MapTask處理資料的時候,一條一條的讀,讀完一條一條計算,計算完把資料寫出去。 1)分割槽: 每一個MapTask把計算結果寫到緩衝區之前需要將資料打標籤(所謂的分割槽號:標記是紅木橡木還是樟木)。 打標籤的目的:為了標記讓這條記錄將來運送到哪一個ReduceTask中。 預設的分割槽器叫:HashPartitioner 它是如何進行分割槽的?根據Map輸出的K的HashCode與ReduceTask的個數取餘決定。 同一個分割槽的資料都運送給某一個ReduceTask來處理。 所以相同的K一定會運到某一個ReduceTask來處理。 注:Map的輸出結果是<K,V>對,具體K是什麼,V是什麼根據需求來定。 2)每一個MapTask把資料寫到記憶體緩衝區中去。這個記憶體緩衝區預設100M。 實際上Buffer內部會把這100M切成兩份:80M和20M 為什麼切成兩份?在溢寫之前要排序在之前還會做combiner(半成品的封裝) 80%叫做溢寫比例 往Buffer中寫入資料超過80M就會 1.1)根據分割槽號(partitionId)排序,如果分割槽號相同,根據K排序。 1.2)把資料溢寫到磁碟上。 MapTask在計算過程中有n多次溢寫。 溢寫產生的小檔案都是有分割槽的而且根據分割槽號(PartitionId)排序的。 每個分割槽內部的資料都是通過K排序的。