2010-01-23 33 views
4

我讀了http://en.wikipedia.org/wiki/MapReduce的mapreduce,瞭解瞭如何在很多「文檔」中獲取「單詞」數量的例子。但是我不明白以下行:MapReduce與函數式編程中的map-reduce組合的區別

因此,MapReduce框架將(鍵,值)對列表轉換爲值列表。這種行爲與函數式編程映射和減少組合不同,後者接受任意值列表並返回一個結合了map返回的所有值的單個值。

有人可以再次闡述差異(MapReduce框架VS地圖和減少組合)嗎?特別是,reduce函數編程是做什麼的?

非常感謝。

回答

8

主要區別在於MapReduce顯然是可申請專利的。 (不禁自,,對不起......)

更爲嚴重的一點是,我記得MapReduce論文描述了一種以大規模並行方式進行計算的方法。這種方法建立在多年前衆所周知的map/reduce構造上,但超越了諸如分佈數據等事項。另外,一些約束被施加在數據結構上,並由用於在map樣和reduce樣件的計算(約數據的鍵/值對的列表來的東西),所以你可能會說,MapReduce的是map & reduce組合的大規模並行性友好專業化

至於在功能上維基百科的評論被映射在函數式編程的map/reduce構建生產每一個輸入值...哦,當然是這樣,但這裏沒有限制在所有的類型的說值爲。特別是,它可能是一個複雜的數據結構,或許您可能會再次應用一個變換列表。回到「計數單詞」的例子,你可能有一個函數,對於文本的給定部分,產生一個數據結構映射字到出現計數,在文檔上的文本(或大塊文件,如情況可能會)和reduce的結果。

實際上,Phil Hagelberg在this article中就是這樣。這是一個在Clojure中實現的基於MapReduce的字計數計算的有趣且極其簡單的例子,其中mapreduce(apply + (merge-with ...))位 - merge-with在clojure.core的reduce中實現)。這與維基百科例子唯一的區別在於被計數的對象是URL而不是任意的單詞 - 除此之外,您還有一個計數字算法,它使用mapreduce,MapReduce樣式,就在那裏。它可能不完全符合MapReduce實例的原因是沒有複雜的工作量分佈。這一切都發生在一個盒子上,儘管盒子提供了所有的CPU。

對於reduce功能的深入處理 - 也稱爲fold - 請參閱Graham Hutton的A tutorial on the universality and expressiveness of fold。它是基於Haskell的,但是即使你不知道語言,也應該可讀,只要你願意查找Haskell的一兩件事情就行了...像++ = list連接,沒有深的Haskell魔術。

+0

關於「在所述值的類型上根本沒有約束」:您聽起來好像MapReduce需要特定的數據結構一樣。它不是。 – 2010-01-23 04:55:05

+1

那麼,MapReduce文件確實將Map步驟描述爲產生鍵/值對的列表。這不需要特定的數據結構 - 像鏈表或散列表 - 但肯定似乎需要特定的數據結構 - 即鍵和值之間的映射。這就是爲什麼我在答案中使用後面的表達式。話雖如此,我認爲沒有什麼可以阻止類似MapReduce的操作在適當時繼續處理不同結構的數據......但我不知道這是否屬於專利的措辭(a * boo! *用於軟件專利!)。 – 2010-01-23 05:13:23

+0

此外,當然沒有理由爲什麼鍵/值對中的值需要具有任何特定的類型......我當然從來不打算暗示這一點。 – 2010-01-23 05:16:33

1

使用字數例如,原始官能map()會採取一組文檔,任選分發集的子集,以及用於每個文檔發射表示的字的數量(或一個特定字的出現)的單個值在文件中。功能reduce()然後將所有文檔的全局計數相加,其中一個用於每個文檔。所以你得到一個總數(無論是所有的單詞還是一個特定的單詞)。

在MapReduce的,在地圖將發射(字,計數)對爲每個字每個文檔。然後,MapReduce reduce()將把的每個詞的計數加起來,並將每個文檔的加起來,而不將它們混合成單個堆。所以你會得到與他們的計數配對的單詞列表。

1

MapReduce是一個基於將計算劃分爲可並行映射器和簡化器的框架。它建立在熟悉的map和reduce的習慣上 - 如果你可以將你的任務結構化,以便它們可以由獨立的映射器和reducer執行,那麼你可以用一種利用MapReduce框架的方式編寫它。

想象一下,Python解釋器可以識別可以獨立計算的任務,並將它們映射到映射器或簡化器節點。如果你寫

reduce(lambda x, y: x+y, map(int, ['1', '2', '3'])) 

sum([int(x) for x in ['1', '2', '3']]) 

您將使用功能圖,並減少在MapReduce框架的方法。使用當前的MapReduce框架,涉及的管道更多,但它的概念是相同的。