本文假定讀者已了解
mapreduce
。map
階段一般做三件事情:
1.切分輸入
2.變換輸入為輸出
3.執行可選的
combine
如果要說哪項是多於的,大概就是
combine
了。combine
在很多時候可以減少傳遞給
reduce
的資料量;但是,也有一些時候,
combine
1.map
輸入中重複
key很多時,
combine
會提高效能
2.map
輸入中重複
key很少時,
combine
會降低效能
3.網路速度很快時,
combine
提高的效能有限,甚至不會提高效能
作為總結:用不用
combine
,一方面取決於資料的特徵(
重複key的多寡
);另一方面就是網路頻寬。
以下reducecallback
指應用程式定義的
reduce
**函式。
在reduce
階段,傳統上,
reduce
階段做三件事情:
1.shuffle
把各個map
程序產生的結果,按
i = hash(key, reducecount)
將記錄分配給第i 個
reduce
程序。2.
sort
將每個reduce
程序原始輸入(
shuffle
產生的)進行排序,將
key相同的記錄對應的
value
集中到一起,產生。3.
reduce讀取}
,為每個
(key,)
,呼叫應用程式自定義的
reduce
函式。通過這種方式,應用程式只需要實現
map和
reduce
方法,其它一切都交給框架來完成了,應用程式會非常簡單。也正因此,效能會受到一定影響:
從理論上講,
reduce
程序收到第一條記錄時,就可以開始
reducecallback
了。但是,因為需要
sort
,就必須等到所有的記錄全部接收,才能開始排序,排序完了才能開始
reducecallback
。實際上,使用一些優化手段,也可以在一邊接收資料,一邊做部分排序。比如在接收輸入時使用置換選擇排序生成初始段,等輸入全部讀完(所有map程序都結束),再做一次多路歸併,歸併的同時,就可以呼叫reducecallback。
如果我們只是做簡單的計數工作(如wordcount),並非必須等到排序完了才開始**應用程式的reduce。如果接收輸入時就開始reducecallback(同時寫入backup檔案),這樣map和reduce是完全並行的,map程序結束時,reduce差不多就可以開始輸出結果了。
如果考慮到容錯,假定map是冪等的,那麼,相同的輸入將產生完全相同的輸出。
框架總需要維護mr[m][r]矩陣,設每個矩陣元素為e。e中至少包含乙個全域性檔案,乙個完成狀態:
struct e ;
如果再每個矩陣元素中增加乙個當前記錄號recordno.當乙個map程序失敗重啟時,直接忽略recordno之前的元素,只處理recordno之後的記錄。map失敗的恢復策略和當前的實現也就這麼些不同。
map的冪等性很重要,如果map不是冪等的,兩次執行的結果可能會有不同;因此不能用recordno。在現實中,實際上很難遇到不滿足map冪等性的情況,如果真出現了這種情況,絕大多數也是程式錯誤!所以,這個重要性,更多是理論上的意義。
reduce[j]
失敗時,恢復策略也還跟以前一樣。讀入所有的mr[*][j].filebackup,並呼叫reducecallback。
我預計,如果使用了這樣的實現,mapreduce的效能會有大幅提公升。
建立物件做了哪些事
class student class studentdemo 問執行類的初始化過程 student s new student 時,在記憶體做了哪些事情?1 把student.class檔案載入到記憶體 2 在棧記憶體為s變數開闢空間 3 在堆記憶體為學生物件申請空間 4 給學生的成員變數進行預設...
nginx啟動期做了哪些事
nginx是個多程序web容器,不同的配置下它的啟動方式也是不同的,這裡我只說說最典型的啟動方式。它有1個master程序,和多個worker程序 最優配置的數量與cpu核數相關 那麼,首先我們要找到main函式,它在src core nginx.c檔案中。談到原始碼了,這時我們先簡單看下原始碼的目...
棧上陣列,做了什麼事?
考慮 char tmp 7 abcd 做了什麼事?2 tmp就是棧頂指標的別名,是個常量,不能修改指向。3 從棧頂向高位址拷貝a,b,c,d,0,5個位元組,0是 abcd 結尾隱含的位元組,陣列申請了7個位元組,剩餘的兩個位元組補充為 0,第8個位元組為cc,沒有初始化。4 陣列可以不定義長度,這...