一個MapReduce 程式示例 細節決定成敗(九):RawComparator
在mr 框架中,用的最普遍的的一個功能就是比較大小。 map輸入時按key排序要比較。reduce的shuff /sort 階段要比較。
所以我們自定義的key型別都是要實現WritableComparator 介面。這個介面中有三個方法需要我們實現。
先看一個簡單的自定義key型別 的程式碼。我們關注其中有一個compareTo 方法。
注意觀察我們 public int compareTo(MyKey key) ; 引數是MyKey型別。 就是是說在呼叫這個比較的時候要做一個反序列化操作成Mykey 物件再比較的過程。 那在大量資料集的情況下,如何減少比較的開銷呢。
能不能不反序列化,直接使用序列化成的byte進行比較呢? 答案是肯定的。我們這次介紹的RawComparator 就是用來做這個的。
在真正寫我們自己的程式碼之前 ,先介紹一個小技巧:那就是寫任何hadoop MapReduce可程式設計元件時,先參考系統自帶的預設實現程式碼。
根據這個習慣,我們找一個系統自帶的型別看看原始碼。那就找IntWritable吧。
從IntWritable 的例子中,我們得到:
1、把WritableComparator 當IntWritable的內部類,寫到裡面,放到一起比較容易找。
2、如何註冊一個自定義的WritableComparator。
此處注意一下,關注static { WritableComparator.define(IntWritable.class,new Comparator())} 的位置。
為什麼是寫到IntWritable中,寫到Comparator類中可以不? 為什麼? (不能寫到Comparator中)
那按這個方式,我們寫一下MyKey的RawComparator
為了驗證我們的RawComparator執行了,在compare方法中加了日誌輸出。同時也可以驗證在什麼時候呼叫了兩個key的比較。
我們理解,應該在map 與reduce階段都會使用到key的比較。下面我們就分別看一下map與reduce的日誌輸出。
開啟瀏覽器輸入 http://xxx.xxx.xxx.xxx:19888/jobhistory 點選對應的job.
mapper的日誌
reducer的日誌
通過日誌,驗證了我們的預期。
所以我們自定義的key型別都是要實現WritableComparator 介面。這個介面中有三個方法需要我們實現。
先看一個簡單的自定義key型別 的程式碼。我們關注其中有一個compareTo 方法。
點選(此處)摺疊或開啟
-
package wordcount;
-
-
import java.io.DataInput;
-
import java.io.DataOutput;
-
import java.io.IOException;
-
-
import org.apache.hadoop.io.WritableComparable;
-
-
public class MyKey implements WritableComparable<MyKey> {
-
-
private char c;
-
@Override
-
public void write(DataOutput out) throws IOException {
-
out.writeChar(c);
-
}
-
-
@Override
-
public void readFields(DataInput in) throws IOException {
-
c= in.readChar();
-
}
-
-
@Override
-
public int compareTo(MyKey key) {
-
if(c==key.c)
-
return 0;
-
else if(c> key.c)
-
return 1;
-
else
-
return -1;
-
}
-
-
public char getC() {
-
return c;
-
}
-
-
public void setC(char c) {
-
this.c = c;
-
}
-
@Override
-
public String toString(){
-
return String.valueOf(this.c);
-
}
-
- }
能不能不反序列化,直接使用序列化成的byte進行比較呢? 答案是肯定的。我們這次介紹的RawComparator 就是用來做這個的。
在真正寫我們自己的程式碼之前 ,先介紹一個小技巧:那就是寫任何hadoop MapReduce可程式設計元件時,先參考系統自帶的預設實現程式碼。
根據這個習慣,我們找一個系統自帶的型別看看原始碼。那就找IntWritable吧。
點選(此處)摺疊或開啟
-
/** A WritableComparable for ints. */
-
@InterfaceAudience.Public
-
@InterfaceStability.Stable
-
public class IntWritable implements WritableComparable<IntWritable> {
-
private int value;
-
-
public IntWritable() {}
-
-
public IntWritable(int value) { set(value); }
-
-
/** Set the value of this IntWritable. */
-
public void set(int value) { this.value = value; }
-
-
/** Return the value of this IntWritable. */
-
public int get() { return value; }
-
-
@Override
-
public void readFields(DataInput in) throws IOException {
-
value = in.readInt();
-
}
-
-
@Override
-
public void write(DataOutput out) throws IOException {
-
out.writeInt(value);
-
}
-
-
/** Returns true iff <code>o</code> is a IntWritable with the same value. */
-
@Override
-
public boolean equals(Object o) {
-
if (!(o instanceof IntWritable))
-
return false;
-
IntWritable other = (IntWritable)o;
-
return this.value == other.value;
-
}
-
-
@Override
-
public int hashCode() {
-
return value;
-
}
-
-
/** Compares two IntWritables. */
-
@Override
-
public int compareTo(IntWritable o) {
-
int thisValue = this.value;
-
int thatValue = o.value;
-
return (thisValue<thatValue ? -1 : (thisValue==thatValue ? 0 : 1));
-
}
-
-
@Override
-
public String toString() {
-
return Integer.toString(value);
-
}
-
-
/** A Comparator optimized for IntWritable. */
-
public static class Comparator extends WritableComparator {
-
public Comparator() {
-
super(IntWritable.class);
-
}
-
-
@Override
-
public int compare(byte[] b1, int s1, int l1,
-
byte[] b2, int s2, int l2) {
-
int thisValue = readInt(b1, s1);
-
int thatValue = readInt(b2, s2);
-
return (thisValue<thatValue ? -1 : (thisValue==thatValue ? 0 : 1));
-
}
-
}
-
-
static { // register this comparator
-
WritableComparator.define(IntWritable.class, new Comparator());
-
}
- }
1、把WritableComparator 當IntWritable的內部類,寫到裡面,放到一起比較容易找。
2、如何註冊一個自定義的WritableComparator。
此處注意一下,關注static { WritableComparator.define(IntWritable.class,new Comparator())} 的位置。
為什麼是寫到IntWritable中,寫到Comparator類中可以不? 為什麼? (不能寫到Comparator中)
那按這個方式,我們寫一下MyKey的RawComparator
點選(此處)摺疊或開啟
-
package wordcount;
-
-
import java.io.DataInput;
-
import java.io.DataOutput;
-
import java.io.IOException;
-
-
import org.apache.hadoop.io.WritableComparable;
-
import org.apache.hadoop.io.WritableComparator;
-
import org.apache.log4j.Logger;
-
-
public class MyKey implements WritableComparable<MyKey> {
-
-
private char c;
-
@Override
-
public void write(DataOutput out) throws IOException {
-
out.writeChar(c);
-
}
-
-
@Override
-
public void readFields(DataInput in) throws IOException {
-
c= in.readChar();
-
}
-
-
@Override
-
public int compareTo(MyKey key) {
-
if(c==key.c)
-
return 0;
-
else if(c> key.c)
-
return 1;
-
else
-
return -1;
-
}
-
-
public char getC() {
-
return c;
-
}
-
-
public void setC(char c) {
-
this.c = c;
-
}
-
@Override
-
public String toString(){
-
return String.valueOf(this.c);
-
}
-
-
public static class MyKeyRawComparator extends WritableComparator{
-
-
Logger log = Logger.getLogger(MyKeyRawComparator.class);
-
public MyKeyRawComparator(){
-
super(MyKey.class);
-
}
-
-
@Override
-
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
-
log.info("==============MyKeyRawComparator Used");
-
-
return super.readUnsignedShort(b1,s1) - super.readUnsignedShort(b2, s2);
-
}
-
-
}
-
static{
-
WritableComparator.define(MyKey.class,new MyKeyRawComparator());
-
}
-
- }
我們理解,應該在map 與reduce階段都會使用到key的比較。下面我們就分別看一下map與reduce的日誌輸出。
開啟瀏覽器輸入 http://xxx.xxx.xxx.xxx:19888/jobhistory 點選對應的job.
mapper的日誌
reducer的日誌
通過日誌,驗證了我們的預期。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30066956/viewspace-2112283/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一個MapReduce 程式示例 細節決定成敗(一)
- 一個MapReduce 程式示例 細節決定成敗(五) :Partitioner
- 一個MapReduce 程式示例 細節決定成敗(八):TotalOrderPartitioner
- 一個MapReduce 程式示例 細節決定成敗(六) :CombineFileInputFormatORM
- 一個MapReduce 程式示例 細節決定成敗(三) :Combiner
- 一個MapReduce 程式示例 細節決定成敗(二) :觀察日誌及 Counter
- 一個MapReduce 程式示例 細節決定成敗(七) :自定義Key 及RecordReader
- 細節決定成敗 MapReduce任務實戰 Map Join
- 細節決定成敗 MapReduce任務實戰 Reduce Join
- 細節決定成敗 MapReduce任務實戰 倒排索引索引
- 第五章 Vlookup函式示例-細節決定成敗函式
- 細節決定成敗!APP設計不容忽視的20個細節APP
- 如何讓程式設計師幸福工作:細節決定成敗程式設計師
- 面試:黃金法則——細節決定成敗面試
- Java集合詳解8:Java集合類細節精講,細節決定成敗Java
- 開發者談F2P模式:細節決定成敗模式
- 邦芒簡歷:求職簡歷細節決定成敗求職
- Python讀書筆記:細節決定成敗(2)Python筆記
- Python讀書筆記:細節決定成敗(1)Python筆記
- 汪峰FIIL Diva智慧耳機究竟如何?細節決定成敗
- 細節決定ERP專案啟動會的成敗
- 細節決定成敗,不容忽視的10道Node面試題面試題
- 細節決定成敗——無CSS時網頁的可讀性CSS網頁
- 軟體設計是怎樣煉成的(7)——細節決定成敗(詳細設計)
- 【原創】構建高效能ASP.NET站點之三 細節決定成敗ASP.NET
- 一個簡單的MapReduce示例(多個MapReduce任務處理)
- 【2024-03-06】細節成敗
- 決定開發者面試成敗的 3 個問題面試
- AutoCAD 2024:細節決定成敗,精準設計從這裡開始 mac/win啟用版Mac
- MapReduce 程式設計模型 & WordCount 示例程式設計模型
- 細節決定一切-多工控制檔案有感
- 領導方式決定團隊成敗 (轉)
- Hadoop 除錯第一個mapreduce程式過程詳細記錄總結Hadoop除錯
- Laravel 的一個命名細節分享Laravel
- 一個小的技術細節
- h5效能優化,細節決定結果。H5優化
- Google TV以何定成敗Go
- 天貓魔盒3Pro內容分析:內容決定成敗