1. 程式人生 > >Hadoop(十)——hadoop之MapReduce理論篇(一)—— Writable序列化

Hadoop(十)——hadoop之MapReduce理論篇(一)—— Writable序列化

一、序列化的概念

  1. 序列化就是把記憶體中的物件,轉換成位元組序列(或其他資料傳輸協議)以便於儲存(持久化)和網路傳輸。
  2. 反序列化就是將收到位元組序列(或其他資料傳輸協議)或者是硬碟的持久化資料,轉換成記憶體中的物件。
  3. Java的序列化是一個重量級序列化框架(Serializable),一個物件被序列化後,會附帶很多額外的資訊(各種校驗資訊,header,繼承體系等),不便於在網路中高效傳輸。所以,hadoop自己開發了一套序列化機制(Writable),精簡、高效。

二、常用資料序列化型別

常用的資料型別對應的hadoop資料序列化型別

三、自定義bean物件實現序列化介面

  1. 自定義bean物件要想序列化傳輸,必須實現序列化介面,需要注意以下7項。
  • (1)必須實現Writable介面
  • (2)反序列化時,需要反射呼叫空參建構函式,所以必須有空參構造
  • (3)重寫序列化方法
  • (4)重寫反序列化方法
  • (5)注意反序列化的順序和序列化的順序完全一致
  • (6)要想把結果顯示在檔案中,需要重寫toString(),且用”\t”分開,方便後續用
  • (7)如果需要將自定義的bean放在key中傳輸,則還需要實現comparable介面,因為mapreduce框中的shuffle過程一定會對key進行排序
  1. 案例【大資料案例(二)——MapReduce實現流量統計案例】
package com.ittzg.hadoop.flow;

import org.apache.hadoop.io.Writable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

/**
 * @email: [email protected]
 * @author: ittzg
 * @date: 2019/7/1 22:49
 * 在hadoop上的傳輸資料的bean必須實現Writable的介面
 */
public class FlowBean implements Writable,Comparable {

    private long upFlow;
    private long downFlow;
    private long sumFlow;

    //反序列化時,需要反射呼叫空參建構函式,所以必須有
    public FlowBean() {
        super();
    }
    //
    public FlowBean(long upFlow, long downFlow) {
        this.upFlow = upFlow;
        this.downFlow = downFlow;
        this.sumFlow = this.upFlow+this.downFlow;
    }

    public long getUpFlow() {
        return upFlow;
    }

    public void setUpFlow(long upFlow) {
        this.upFlow = upFlow;
    }

    public long getDownFlow() {
        return downFlow;
    }

    public void setDownFlow(long downFlow) {
        this.downFlow = downFlow;
    }

    public long getSumFlow() {
        return sumFlow;
    }

    public void setSumFlow(long sumFlow) {
        this.sumFlow = sumFlow;
    }

    //序列化方法
    public void write(DataOutput dataOutput) throws IOException {
        dataOutput.writeLong(upFlow);
        dataOutput.writeLong(downFlow);
        dataOutput.writeLong(sumFlow);

    }
    //反序列化
    public void readFields(DataInput dataInput) throws IOException {
        upFlow = dataInput.readLong();
        downFlow = dataInput.readLong();
        sumFlow = dataInput.readLong();

    }

    @Override
    public String toString() {
        return upFlow + "\t" + downFlow + "\t" + sumFlow;
    }

    // 如果需要將自定義的bean放在key中傳輸,則還需要實現comparable介面,因為mapreduce框中的shuffle過程一定會對key進行排序
    public int compareTo(Object o) {
        FlowBean flowBean = (FlowBean) o;
        return this.sumFlow >flowBean .getSumFlow() ? -1 :