天天看點

MapReduce中的shuffle過程

1.Map task輸出k-v對

2.環形緩沖區

  map階段在最後會通過MapOutputBuffer來将資料暫時存儲到一個環形緩沖區,在緩沖區寫入的資料達到門檻值(80%)後,才會開始從這裡再寫出到磁盤(落盤)。由此可見:環形緩沖區的設計直接影響Map Task的輸出效率。

  上面大緻的流程中,我們不禁有這麼幾個疑問:

    1.什麼是環形緩沖區?為什麼使用它?

    2.緩沖區架構門檻值為什麼設定為80%?

    3.環形緩沖區内部的讀寫時是什麼樣的?

下面就通過整體上模拟來解決這些問題。

  2.1首先來認識下緩沖區:

  緩沖區包含有:單向、雙向、環形。這裡主要介紹環形。

  2.1.1 單向緩沖區:

  這個很簡單,輸出的資料直接向緩沖區單向的寫入,寫滿後,一次性開始落盤。不斷循環往複。也可以看出,它最大的缺點就是性能太低,不能并發狀态下讀寫資料。

MapReduce中的shuffle過程

  2.1.2 雙向緩沖區:

  針對于上面的單向緩沖區,在一定程度上進行了一些改進:使用兩個緩沖區,原則上一讀一寫,交替進行,在一定程度上讓讀寫并行(讀寫效率并不一緻,是以有時還是做不到完全并發,出現讀寫等待的問題)。

MapReduce中的shuffle過程

  2.1.3 環形緩沖區:

  1— 》什麼是環形緩沖區?

  上面雙向緩沖區的基礎上,再次改進,設計一個環形的(閉環)緩沖區,寫入到一定門檻值之後,開始寫出,同時并發狀态下,繼續向不斷增加的剩餘空間寫入,寫入後寫出某種意義上來講,互不影響。完全達到并發讀寫

  

MapReduce中的shuffle過程

   2— 》工作原理:

  在環形緩沖區内儲存好資料後(80%),有SpillThread線程來将資料寫到一個臨時檔案中,當所有資料全部處理完成之後,對所有檔案進行一次合并,生成一個終極檔案。這樣就使得Map Task任務中的的Collect階段和Spill階段并行進行。

  3—》索引(寫出時怎麼找資料)

  環形緩沖區内部采用了兩級索引,設計了三個環形記憶體緩沖區:kvoffsets、kvindices和kvbuffer。架構預設這三個共占據空間大小為100M(可改)。其中:

    kvbuffer:真正的資料緩存區。存放的就是map端甩來的kv對,預設最多占據95%,超過這個值,便會觸發SpillThread,開始溢寫。

    kvindices:位置索引數組。存放的是kv值在資料緩沖中的起始位置。

    kvoffsets:kv偏移量索引數組。儲存我們的key/value資訊在位置索引kvindices中的偏移量。

  kvbuffer占95%,kvoffsets占3.75%,kvindices1.25%

  2.2 環形緩沖區工作原理

MapReduce中的shuffle過程

   将一個環形緩沖區展開來看成矩形,首尾本來是相接的,最初,在開始位置有三個指針,(如圖紅、綠、藍)分别用來标記寫入過程中的開始寫的位置(start),資料所占據的(末尾)位置index,以及标記要溢寫部分的結尾位置(end)。

  2.3 環形緩沖區内工作流程

==============

  開始寫入資料,index指針随着資料的寫入向後移動,start和end保持不動。直到index标記到環形緩沖區80%的地方,此時end指針直接跳到index的位置,start指針不動。那麼,此時從start位置到end位置這一區域内的資料,就是我們第一次要溢寫的資料,開始溢寫。

  溢寫的同時,start向後移動,同時,繼續向環形緩沖區内寫入,index指針向後移動,end指針保持不動,這樣就使得讀寫并行。當上一次的溢寫完成後,end指針此時如果跳轉到了下一個80%的index位置,再次開始溢寫。

  80%=(end-start)+(index-end)

  問:什麼門檻值設為80%?