流程分析。
入口處:
這裡manager 拿到的是
我們看他是如何拿到可以寫磁盤的那個sorter的。我們分析的線路假設需要做mapsidecombine
接着将map的輸出放到sorter當中:
其中insertall 的流程是這樣的:
裡面的map 其實就是partitionedappendonlymap,這個是全記憶體的一個結構。當把這個寫滿了,才會觸發spill操作。你可以看到maybespillcollection在partitionedappendonlymap每次更新後都會被調用。
一旦發生呢個spill後,産生的檔案名稱是:
邏輯在這:
産生的所有 spill檔案被被記錄在一個數組裡:
疊代完一個task對應的partition資料後,會做merge操作,把磁盤上的spill檔案和記憶體的,疊代處理,得到一個新的iterator,這個iterator的元素會是這個樣子的:
其中p 是reduce 對應的partitionid, p對應的所有資料都會在其對應的iterator中。
接着會獲得最後的輸出檔案名:
檔案名格式會是這樣的:
其中reduceid 是一個固定值noop_reduce_id,預設為0。
然後開始真實寫入檔案
寫入檔案的過程過程是這樣的:
剛剛我們說了,這個 this.partitionediterator 其實内部元素是reduce partitionid -> 實際record 的 iterator,是以它其實是順序寫每個分區的記錄,寫完形成一個filesegment,并且記錄偏移量。這樣後續每個的reduce就可以根據偏移量拿到自己需要的資料。對應的檔案名,前面也提到了,是:
剛剛我們說偏移量,其實是存在記憶體裡的,是以接着要持久化,通過下面的writeindexfile來完成:
具體的檔案名是:
至此,一個task的寫入操作完成,對應一個檔案。
是以最後的結論是,一個executor 最終對應的檔案數應該是:
同時持有并且會進行寫入的檔案數最多為: