函數式編程概念
MapReduce程序是設計用來並行計算大規模海量數據的,這需要把工作流分劃到大量的機器上去,如果組件(component)之間可以任意的共享數據,那這個模型就沒法擴展到大規模集羣上去了(數百或數千個節點),用來保持節點間數據的同步而產生的通信開銷會使得系統在大規模集羣上變得不可靠和效率低下。
實際上,所有在MapReduce上的數據元素都是不可變的,這就意味着它們不能夠被更新。如果在一個mapping任務中你改變了一個輸入鍵值對,它並不會反饋到輸入文件;節點間的通信只在產生新的輸出鍵值對((key,value)pairs)時發生,Hadoop系統會把這些輸出傳到下一個執行階段。
列表處理(List Processing)
從概念上講,MapReduce程序轉變輸入數據元素列表成輸出數據元素列表。一個MapReduce程序會重複這個步驟兩次,並用兩個不同的術語描述:map和reduce,這些術語來自於列表處理語言,如:LISP,Scheme,或ML。
Mapping數據列表(Lists)
MapReduce程序的第一步叫做mapping,在這一步會有一些數據元素作爲Mapper函數的輸入數據,每次一個,Mapper會把每次map得到的結果單獨的傳到一個輸出數據元素裏。
圖4.1 Mapping通過對輸入數據列表中的每一個元素應用一個函數創建了一個新的輸出數據列表
這裏舉一個map功能的例子:假設你有一個函數toUpper(str),用來返回輸入字符串的大寫版本。你可以在map中使用這個函數把常規字符串列表轉換成大寫的字符串列表。注意,在這裏我們並沒有改變輸入字符串:我們返回了一個新的字符串,它是新的輸出列表的組成部分之一。
Reducing數據列表(Lists)
Reducing可以讓你把數據聚集在一起。reducer函數接收來自輸入列表的迭代器,它會把這些數據聚合在一起,然後返回一個輸出值。
圖4.2 通過列表迭代器對輸入數據進行reducing操作來輸出聚合結果。
Reducing一般用來生成”總結“數據,把大規模的數據轉變成更小的總結數據。比如,"+"可以用來作一個reducing函數,去返回輸入數據列表的值的總和。
把它們一起放在MapReduce中
Hadoop的MapReduce框架使用了上面的那些概念並用它們來處理大規模的數據信息。MapReduce程序有着兩個組件:一個實現了mapper,另一個實現了reducer。上面描敘的Mapper和Reducer術語在Hadoop中有了更細微的擴展,但基本的概念是相同的。
鍵和值:在MapReduce中,沒有一個值是單獨的,每一個值都會有一個鍵與其關聯,鍵標識相關的值。舉個例子,從多輛車中讀取到的時間編碼車速表日誌可以由車牌號碼標識,就像下面一樣: