mapreduce 從它名字上來看就大致可以看出個緣由,兩個動詞map和reduce,「map(展開)」就是將乙個任務分解成為多個任務,「reduce」就是將分解後 多工處理的結果彙總起來,得出最後的分析結果。這不是什麼新思想,其實在前面提到的多執行緒,多工的設計就可以找到這種思想的影子。不論是現實社會,還 是在程式設計中,一項工作往往可以被拆分成為多個任務,任務之間的關係可以分為兩種:一種是不相關的任務,可以並行執行;另一種是任務之間有相互的依賴, 先後順序不能夠顛倒,這類任務是無法並行處理的。回到大學時期,教授上課時讓大家去分析關鍵路徑,無非就是找最省時的任務分解執行方式。在分布式系統中, 機器集群就可以看作硬體資源池,將並行的任務拆分,然後交由每乙個空閒機器資源去處理,能夠極大地提高計算效率,同時這種資源無關性,對於計算集群的擴充套件 無疑提供了最好的設計保證。任務分解處理以後,那就需要將處理以後的結果再彙總起來,這就是reduce要做的工作。結構圖如下:
網上有個簡單的比喻來解釋mapreduce原理:
我們要數圖書館中的所有書。你數1號書架,我數2號書架。這就是「map」。我們人越多,數書就更快。
現在我們到一起,把所有人的統計數加在一起。這就是「reduce」。
假設我們需要處理一批有關天氣的資料,其格式如下:
0067011990999991950051507+0000+
0043011990999991950051512+0022+
0043011990999991950051518-0011+
0043012650999991949032412+0111+
0043012650999991949032418+0078+
0067011990999991937051507+0001+
0043011990999991937051512-0002+
0043011990999991945051518+0001+
0043012650999991945032412+0002+
0043012650999991945032418+0078+
現在需要統計出每年的最高溫度。
map-reduce主要包括兩個步驟:map和reduce
每一步都有key-value對作為輸入和輸出:
對於上面的例子,在map過程,輸入的key-value對如下:
(0, 0067011990999991950051507+0000+)
(33, 0043011990999991950051512+0022+)
(66, 0043011990999991950051518-0011+)
(99, 0043012650999991949032412+0111+)
(132, 0043012650999991949032418+0078+)
(165, 0067011990999991937051507+0001+)
(198, 0043011990999991937051512-0002+)
(231, 0043011990999991945051518+0001+)
(264, 0043012650999991945032412+0002+)
(297, 0043012650999991945032418+0078+)
在map過程中,通過對每一行字串的解析,得到年-溫度的key-value對作為輸出:
(1950, 0)
(1950, 22)
(1950, -11)
(1949, 111)
(1949, 78)
(1937, 1)
(1937, -2)
(1945, 1)
(1945, 2)
(1945, 78)
在reduce過程,將map過程中的輸出,按照相同的key將value放到同乙個列表中作為reduce的輸入
(1950, [0, 22, –11])
(1949, [111, 78])
(1937, [1, -2])
(1945, [1, 2, 78])
在reduce過程中,在列表中選擇出最大的溫度,將年-最大溫度的key-value作為輸出:
(1950, 22)
(1949, 111)
(1937, 1)
(1945, 78)
其邏輯過程可用如下圖表示:
一般遵循以下格式:
void map(k1 key, v1 value, outputcollectoroutput, reporter reporter)
throws ioexception;}
public inte***ce reducerextends jobconfigurable, closeable
@override
public void map(longwritable key, text value, outputcollectoroutput, reporter reporter) throws ioexception else
output.collect(new text(year), new intwritable(airtemperature));}}
實現的reducer如下:
public class maxtemperaturereducer extends mapreducebase implements reducer
output.collect(key, new intwritable(maxvalue));}}
欲配置jobconf,需要大致了解hadoop執行job的基本原理(後面還會細說):
hadoop將輸入的資料分成固定大小的塊,我們稱之input split
hadoop為每乙個input split建立乙個task,在此task中依次處理此split中的乙個個記錄(record)
hadoop會盡量讓輸入資料塊所在的datanode和task所執行的datanode(每個datanode上都有乙個tasktracker)為同乙個,可以提高執行效率,所以input split的大小也一般是hdfs的block的大小。
reduce task的輸入一般為map task的輸出,reduce task的輸出為整個job的輸出,儲存在hdfs上。
在reduce中,相同key的所有的記錄一定會到同乙個tasktracker上面執行,然而不同的key可以在不同的tasktracker上面執行,我們稱之為partition
public inte***ce partitionerextends jobconfigurable
下圖大概描述了map-reduce的job執行的基本原理:
下面我們討論jobconf,其有很多的項可以進行配置:
當然不用所有的都設定,由上面的例子,可以編寫map-reduce程式如下:
public class maxtemperature
jobconf conf = new jobconf(maxtemperature.class);
conf.setjobname("max temperature");
fileinputformat.addinputpath(conf, new path(args[0]));
fileoutputformat.setoutputpath(conf, new path(args[1]));
conf.setreducerclass(maxtemperaturereducer.class);
conf.setoutputkeyclass(text.class);
conf.setoutputvalueclass(intwritable.class);
jobclient.runjob(conf);}}
python學習筆記 高階函式map reduce
既然變數可以指向函式,函式的引數能接收變數,那麼乙個函式就可以接收另乙個函式作為引數,這種函式就稱之為高階函式。乙個最簡單的高階函式 def add x,y,f return f x f y 當我們呼叫add 5,6,abs 時,引數x,y和f分別接收 5,6和abs map deff x retu...
HDFS學習筆記
3 hdfs儲存原理 主節點 資料目錄 元資料 服務 從節點 具體完成資料的儲存任務 hdfs 相容廉價的硬體裝置,實現流資料讀寫,支援大資料集,支援簡單的檔案模型,強大的跨平台相容性 hdfs侷限性 不適合低延遲資料訪問,無法高效儲存大量小檔案,不支援多使用者寫入以及任意修改檔案。1 為了分攤磁碟...
HDFS學習筆記
hdfs學習筆記 hdfs,是hadoop distributed file system的簡稱,是hadoop抽象檔案系統的一種實現。hdfs的檔案分布在集群機器上,同時提供副本進行容錯及可靠性保證。例如客戶端寫入讀取檔案的直接操作都是分布在集群各個機器上的,沒有單點效能壓力。什麼是hdfs 1....