2015-11-03 41 views
2

編程模型MapReduce由2個過程map和reduce組成。爲什麼我們需要地圖部分,我們可以簡單地在reduce函數中進行映射。爲什麼我們需要MapReduce中的「地圖」部分?

考慮以下僞代碼:

result = my_list.map(my_mapper).reduce(my_reducer); 

這可以縮短到

result = my_list.reduce(lambda x : my_reducer(my_mapper(x))); 

一號方法如何可以比第二一個更優選的,而第一個方法需要一個更通過數據?我的代碼示例是否過於簡化?

回答

4

那麼,如果你引用Hadoop風格的MapReduce,它實際上是map-shuffle-reduce,其中shuffle是map和reduce分開的原因。稍微高一點,你可以考慮數據局部性。通過map的每個鍵值對都可以生成零個或多個鍵值對。爲了能夠減少這些,你必須確保一個給定密鑰的所有值都可以在一個reduce上得到,因此也就是洗牌。從單個輸入對發出的重要對可由不同的減速器處理。

可以使用像地圖端聚合或合成器這樣的模式,但是在一天結束時它仍然是(地圖)-reduce-shuffle-reduce。

假設數據局部性不成問題,像map和reduce這樣的高階函數提供了一個優雅的抽象層。最後它是一個聲明式API。像xs.map(f1).reduce(f2)這樣的簡單表達只描述什麼不是如何。根據語言或上下文的不同,這些可以被熱切地或懶惰地評估,操作可以被壓扁,在更復雜的情況下可以以許多不同的方式重新排序和優化。

關於你的代碼。即使簽名是正確的,它也不會真正減少您傳遞數據的次數。此外,如果您將映射推送到聚合中,則傳遞給聚合函數的參數不再是同一類型。它意味着連續摺疊或更復雜的合併邏輯。

1

在較高的層次上,map reduce是關於並行處理的。儘管減速器在地圖輸出上工作,但實際上,每個減速器只能獲得部分數據,而這隻有在第一種方法中才有可能。

在你的第二種方法中,你的reducer實際上需要mapper的完整輸出,這打破了並行的思想。

+0

爲什麼減速機不能同時完成? – Will

+0

我的意思是,從你的代碼,你的reducer實際上需要特定的(在你的情況下,整個地圖輸出),並且不可能不同的map輸出可以去不同的reducer,以處理並行 – Ramzy