map的環形記憶體緩衝區

2021-08-25 07:11:38 字數 2858 閱讀 1175

hadoop在執行mapreduce任務時,在map階段,map函式產生的輸出,並不是直接寫入磁碟的。為了提高效率,它將輸出結果先寫入到記憶體中(即環形記憶體緩衝區,預設大小100m),再從緩衝區(溢)寫入磁碟。

下面我們就來看看這段**。

[size=medium][b]1、找到環形記憶體緩衝區[/b][/size]

在執行job時,有條輸出:

09/04/07 12:34:35 info mapred.maptask: io.sort.mb = 100

上面的io.sort.mb,即map環形記憶體緩衝區的大小。

在org.apache.hadoop.mapred.maptask中的第764行找到「io.sort.mb」

第781行:

kvbuffer = new byte[maxmemusage - recordcapacity];

kvbuffer是在第715行定義的:

private byte kvbuffer;           // main output buffer

[b]看,這個記憶體緩衝區竟然是個byte陣列!![/b]

[size=medium][b]2、什麼時候溢寫到磁碟的?[/b][/size]

第762行:

final float spillper = job.getfloat("io.sort.spill.percent",(float)0.8);

// 溢寫比:預設是0.8,就是說,快取區80%滿了的時候,就要將資料從記憶體溢寫到磁碟了

這100m,還分成2塊:資料快取和記錄快取

第707行:

private final int kvoffsets; // indices into kvindices

// 這個int型的陣列就是記錄快取

第941行:

// sort by key

return comparator.compare(kvbuffer,

kvindices[ii + keystart],

kvindices[ii + valstart] - kvindices[ii + keystart],

kvbuffer,

kvindices[ij + keystart],

kvindices[ij + valstart] - kvindices[ij + keystart]);

// 在記憶體緩衝區中按key進行排序

綜上,溢寫發生在:

1) 溢寫比設定了<1的值,並且該值到了的時候

2) 溢寫比為1,快取滿了的時候

[size=medium][b]3、緩衝區怎麼成環形的?[/b][/size]

答:通過折行。

----------------------------------

「折行寫」

第1038行:

boolean buffull = false; // 快取是否滿了

// 這裡的「滿」,有2種情況:

1) bufindex + len > bufvoid

// 就是說,達到了末尾

// 但是這種情況,可能不是真的滿了

// 因為,在陣列0-bufstart之間,可能還有很大的空置空間

2) bufindex + len > bufstart

// 由於緩衝區已經成「環」,這種情況,是真的滿了。

第1039行:

boolean wrap = false; // 是否需要「折行寫」

// 「折行寫」的條件:

1) bufstart <= bufend && bufend <= bufindex

// buffer是一段連續的區域,還沒有形成「環」

2) (bufvoid - bufindex) + bufstart > len

// 陣列末尾,加上陣列開頭的空間能夠儲存當前資料

// 真正執行「折行寫」的**(line1101-1107):

if (buffull)

----------------------------------

「折行寫」後的reset

[size=medium][b]4、「成環」示意圖[/b][/size]

上面的**一定看的眼花繚亂吧?呵呵,我一開始看的時候,也被弄得很糊塗。請看下面的示意圖,就會對這個環形緩衝有個好的理解了。

[img]

[size=medium][b]5、「溢寫」過程[/b][/size]

bufend = bufmark; // 在startspill方法中

sortandspill();

bufstart = bufend;

即:溢寫完畢後,原來的bufmark變成了bufstart

[size=medium][b]6、快取為什麼要設計成環形的?有什麼好處?[/b][/size]

答:使輸入輸出並行工作,即「寫緩衝」可以和「溢寫」並行。「溢寫」工作由單獨的執行緒來做。

解讀「溢寫」**:

bufend = bufmark; // 在startspill方法中

sortandspill();

bufstart = bufend;

1)溢寫前:

bufend = bufmark;

則溢寫的範圍是:從bufstart到bufend。

2)在溢寫的過程中,bufmark還是有可能增長的!

3)溢寫完畢,bufstart = bufend;

*** the end***

環形緩衝區

include include include include include define buffsize 1024 1024 define min x,y x y x y pthread mutex t lock pthread mutex initializer struct cycle b...

環形緩衝區

define print buf size 16 1024 static char g pcnetprintbuf 環形緩衝區的首位址 static int g ireadpos 0 環形緩衝區讀的位置 static int g iwritepos 0 環形緩衝區寫的位置 intinit 判斷環形緩...

環形緩衝區

環形緩衝區要維護兩個索引,分別對應寫入端 w 和讀取端 r 寫入 push 的時候,先確保環沒滿,然後把資料複製到 w 所對應的元素,最後 w 指向下乙個元素 讀取 pop 的時候,先確保環沒空,然後返回 r 對應的元素,最後 r 指向下乙個元素。上述的操作並不複雜,不過有乙個小小的麻煩 空環和滿環...