setup方法在類調(diào)用起始階段運行,可以實現(xiàn)初始階段對于參數(shù)讀取和變量賦值的操作。在app應(yīng)用識別案例中,我們在setup階段實現(xiàn)對于平臺DPI文件的讀取操作,以在之后的map階段實現(xiàn)MapJoin操作,代碼如下:

其中DPIMap是需要在主類中定義的HashMap變量,在map階段將使用HashMap實現(xiàn)快速查找。
map方法是實現(xiàn)Mapper類的核心方法,map階段主要邏輯都需要在map方法中實現(xiàn)。map方法參數(shù)定義包括輸入< key,value >和上下文對象context聲明。Context對象負(fù)責(zé)在MapReduce執(zhí)行過程中平臺配置和Job配置的傳遞。Job執(zhí)行過程中,寫入的業(yè)務(wù)邏輯會對每一條數(shù)據(jù)進(jìn)行操作,并將中間結(jié)果< key,value >值通過context對象寫入后臺進(jìn)行之后的shuffle和reduce操作。
例如我需要將業(yè)務(wù)數(shù)據(jù)中的host字段與DPI數(shù)據(jù)的host字段進(jìn)行等值連接,統(tǒng)計出使用app的次數(shù)。我們可以在map方法中實現(xiàn)如下:

在此默認(rèn)輸入數(shù)據(jù)為ORC格式,代碼中涉及對ORC文件讀取方法。
Reduce實現(xiàn)
同Mapper類類似,擴(kuò)展Reducer類需要實現(xiàn)reduce方法。繼續(xù)以統(tǒng)計app次數(shù)為例,Reducer類擴(kuò)展實現(xiàn)為:

其中reduce方法實現(xiàn)的邏輯為對依據(jù)key值group之后的value值集合進(jìn)行加和,并寫入HDFS。
在reduce方法中,接收到的value集合通過Iterable接口實現(xiàn),我們可以通過iterator對象提供的API實現(xiàn)對value值集合的遍歷。Reduce的輸出我們最終寫為ORC格式。
程序主入口main()方法
通過在主類中定義main()方法作為程序的入口,我們需要在此完成對程序參數(shù)傳遞、輸入輸出配置和HDFS平臺配置聲明等工作,以app應(yīng)用識別為例,代碼如下:


此例main()方法主要完成了對輸入輸出類型和路徑的配置、任務(wù)執(zhí)行隊列和資源配置的定義。main()方法主要完成對程序接口的定義和資源調(diào)配,以上代碼展示了一個最基本main()方法的定義。如果任務(wù)需要,我們還可以完成諸如自定義Group Comparator、Sort Comparator、Partitoner等對象的定義,并在main()方法中聲明,作為MapReduce程序的comparator。
在我們平臺的日常任務(wù)中,我們放棄使用占用空間較大的Text和Sequence文件格式,完全使用ORC文件格式作為數(shù)據(jù)存儲格式。這樣可以實現(xiàn)自定義MapReduce程序與Hive平臺的無縫結(jié)合,更重要的是,可以為平臺節(jié)省十倍的存儲空間。
ORC存儲方法
ORC File是Optimized Row Columnar (ORC) file的簡稱,它基于RCFile格式進(jìn)行了優(yōu)化。ORC文件格式的設(shè)計初衷是為了提高Hive數(shù)據(jù)讀寫以及數(shù)據(jù)處理能力,由于其實現(xiàn)了一定的數(shù)據(jù)壓縮,可以占用更小的數(shù)據(jù)存儲。
我們使用ORC格式作為MapReduce和Hive工具的統(tǒng)一存儲格式,可以節(jié)省平臺大量的存儲空間,同時也實現(xiàn)了MapReduce程序與Hive的更好結(jié)合。
經(jīng)過我們平臺日常任務(wù)的實測積累,ORC文件格式可以為Hive提供穩(wěn)定快速的數(shù)據(jù)讀寫,并且與Text文件存儲相比,可以節(jié)省十倍的存儲空間,可以大幅提升平臺數(shù)據(jù)存儲和處理能力。對于MapReduce程序讀寫ORC文件,無法像未壓縮的Text文件一樣直接讀寫,還需要做關(guān)于表數(shù)據(jù)結(jié)構(gòu)聲明等工作。
讀ORC文件
仍然以app應(yīng)用識別為例,主類中需要定義變量SCHEMA,聲明讀入表結(jié)構(gòu):

讀取ORC文件格式的代碼如下:

首先,需要將讀入的value值強制類型轉(zhuǎn)換為OrcStruct,然后根據(jù)表結(jié)構(gòu)實例化StructObjectInspector對象為inspector,最后使用StructObjectInspector類提供的API對字段進(jìn)行讀取。