Hadoop學習筆記—5.自訂類型處理手機上網日誌

來源:互聯網
上載者:User

標籤:記錄檔   sel   測試   學習筆記   col   protect   span   相加   com   

一、測試資料:手機上網日誌1.1 關於這個日誌

  假設我們如下一個記錄檔,這個檔案的內容是來自某個電信電訊廠商的手機上網日誌,檔案的內容已經經過了最佳化,格式比較規整,便於學習研究。

  該檔案的內容如下(這裡我只截取了三行):

1363157993044 18211575961 94-71-AC-CD-E6-18:CMCC-EASY 120.196.100.99 iface.qiyi.com 視頻網站 15 12 1527 2106 200

1363157995033 15920133257 5C-0E-8B-C7-BA-20:CMCC 120.197.40.4 sug.so.360.cn 資訊安全 20 203156 2936 200

1363157982040 13502468823 5C-0A-5B-6A-0B-D4:CMCC-EASY 120.196.100.99 y0.ifengimg.com 綜合門戶 57 102 7335 110349 200

  每一行不同的欄位有有不同的含義,具體的含義如所示:

1.2 要實現的目標

  有了上面的測試資料—手機上網日誌,那麼問題來了,如何通過map-reduce實現統計不同手機號使用者的上網流量資訊?通過上表可知,第6~9個欄位是關於流量的資訊,也就是說我們需要為每個使用者統計其upPackNum、downPackNum、upPayLoad以及downPayLoad這個四個欄位的數量和,達到以下的顯示結果:

13480253104 3 3 180 180

13502468823 57 102 7335 110349

二、解決思路:封裝手機流量2.1 Writable介面

  經過上一篇的學習,我們知道了在Hadoop中操作所有的資料類型都需要實現一個叫Writable的介面,實現了該介面才能夠支援序列化,才能方便地在Hadoop中進行讀取和寫入。

public interface Writable {  /**    * Serialize the fields of this object to <code>out</code>.   */  void write(DataOutput out) throws IOException;  /**    * Deserialize the fields of this object from <code>in</code>.     */  void readFields(DataInput in) throws IOException;}

  從上面的代碼中可以看到Writable 介面只有兩個方法的定義,一個是write 方法,一個是readFields 方法。前者是把對象的屬性序列化到DataOutput 中去,後者是從DataInput 把資料還原序列化到對象的屬性中。(簡稱“讀進來”,“寫出去”)

  java 中的基本類型有char、byte、boolean、short、int、float、double 共7 中基本類型,除了char,都有對應的Writable 類型。但是,沒有我們需要的對應類型。於是,我們需要仿照現有的對應Writable 類型封裝一個自訂的資料類型,以供本次實驗使用。

2.2 封裝KpiWritable類型

  我們需要為每個使用者統計其upPackNum、downPackNum、upPayLoad以及downPayLoad這個四個欄位的數量和,而這個四個欄位又都是long 類型,於是我們可以封裝以下代碼:

    /*     * 自訂資料類型KpiWritable     */    public class KpiWritable implements Writable {        long upPackNum;     // 上行資料包數,單位:個        long downPackNum;    // 下行資料包數,單位:個        long upPayLoad;     // 上行總流量,單位:byte        long downPayLoad;    // 下行總流量,單位:byte        public KpiWritable() {        }        public KpiWritable(String upPack, String downPack, String upPay,                String downPay) {            upPackNum = Long.parseLong(upPack);            downPackNum = Long.parseLong(downPack);            upPayLoad = Long.parseLong(upPay);            downPayLoad = Long.parseLong(downPay);        }        @Override        public String toString() {            String result = upPackNum + "\t" + downPackNum + "\t" + upPayLoad                    + "\t" + downPayLoad;            return result;        }        @Override        public void write(DataOutput out) throws IOException {            out.writeLong(upPackNum);            out.writeLong(downPackNum);            out.writeLong(upPayLoad);            out.writeLong(downPayLoad);        }        @Override        public void readFields(DataInput in) throws IOException {            upPackNum = in.readLong();            downPackNum = in.readLong();            upPayLoad = in.readLong();            downPayLoad = in.readLong();        }    }

  通過實現Writable介面的兩個方法,就封裝好了KpiWritable類型。

三、編程實現:依然MapReduce3.1 自訂Mapper類
    /*     * 自訂Mapper類,重寫了map方法     */    public static class MyMapper extends            Mapper<LongWritable, Text, Text, KpiWritable> {        protected void map(                LongWritable k1,                Text v1,                org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, KpiWritable>.Context context)                throws IOException, InterruptedException {            String[] spilted = v1.toString().split("\t");            String msisdn = spilted[1]; // 擷取手機號碼            Text k2 = new Text(msisdn); // 轉換為Hadoop資料類型並作為k2            KpiWritable v2 = new KpiWritable(spilted[6], spilted[7],                    spilted[8], spilted[9]);            context.write(k2, v2);        };    }

  這裡將第6~9個欄位的資料都封裝到KpiWritable類型中,並將手機號和KpiWritable作為<k2,v2>傳入下一階段;

3.2 自訂Reducer類
    /*     * 自訂Reducer類,重寫了reduce方法     */    public static class MyReducer extends            Reducer<Text, KpiWritable, Text, KpiWritable> {        protected void reduce(                Text k2,                java.lang.Iterable<KpiWritable> v2s,                org.apache.hadoop.mapreduce.Reducer<Text, KpiWritable, Text, KpiWritable>.Context context)                throws IOException, InterruptedException {            long upPackNum = 0L;            long downPackNum = 0L;            long upPayLoad = 0L;            long downPayLoad = 0L;            for (KpiWritable kpiWritable : v2s) {                upPackNum += kpiWritable.upPackNum;                downPackNum += kpiWritable.downPackNum;                upPayLoad += kpiWritable.upPayLoad;                downPayLoad += kpiWritable.downPayLoad;            }            KpiWritable v3 = new KpiWritable(upPackNum + "", downPackNum + "",                    upPayLoad + "", downPayLoad + "");            context.write(k2, v3);        };    }

  這裡將Map階段每個手機號所對應的流量記錄都一一進行相加求和,最後產生一個新的KpiWritable類型對象與手機號作為新的<k3,v3>返回;

3.3 完整代碼實現

  完整的代碼如下所示:

 View Code3.4 調試運行效果

附件下載

  (1)本次用到的手機上網日誌(部分版):http://pan.baidu.com/s/1dDzqHWX

 

原文連結:http://edisonchou.cnblogs.com/

Hadoop學習筆記—5.自訂類型處理手機上網日誌

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.