天天看點

MR學習總結(一):MapReduce概述與Hadoop序列化

一、MapReduce概述

1. 什麼是MR?

MR是Hadoop中的一個分布式程式設計架構,我們可以按照MR架構内的規範編寫業務代碼,進而完成大資料分析業務。

2. MR的優缺點?

優點:

1. 适合PB級以上海量資料的離線處理

   MR是一個分布式計算架構,可以實作上千台伺服器叢集并發工作,提供資料處理能力。

2. 易于程式設計

   MR提供了大量的接口與規定,并且定義好了分布式處理的内部細節,我們隻需要按照規定專注于自己的業務邏輯即可。

3. 易于擴充

    MR支援叢集内機器的動态擴充。

4. 容錯性高

   當叢集内部分機器無法工作時,MR可以自動将計算任務遷移到其它可用機器。

缺點:

1. 不擅長實時計算

   MR是一個大資料離線批處理架構,計算效率較低,無法滿足實時計算低延遲時間的要求。

2. 不擅長流式計算

   流式計算的輸入資料是動态的,而MapReduce的輸入資料集是靜态的,不能動态變化。

3. 不擅長DAG(有向圖)計算

   MapReduce作業的輸出結果最終都會寫入到磁盤。而在有向圖計算中:多個應用程式存在依賴關系,後一個應用程式的輸入為前一個的輸出;多個MR作業互相嵌套的方式在原理上雖然可行,但會造成大量的磁盤IO,導緻性能非常的低。

二、Hadoop序列化

1. 什麼是序列化?

序列化: 将記憶體中的對象轉換成位元組序列(也可能是其他資料傳輸協定),以便于持久化到磁盤或進行網絡傳輸。

反序列化: 将收到的位元組序列(也能可能是其他資料傳輸協定)或磁盤中的持久化資料準換成記憶體中的對象。

2. 為什麼要序列化?

第一,對象是存在記憶體中的,一旦斷電關機就會消失;

第二,記憶體的對象隻能供本地程序使用,不能被其他計算機使用。

如何實作對象的持久化和網絡傳輸呢?序列化就是将記憶體中的對象儲存到磁盤或者通過網絡傳輸到其他計算機上去。

3. 為什麼不用java的序列化機制?

java序列化是一個重量級的序列化架構,一個對象被序列化後,會攜帶額外的資訊(各種校驗資訊、繼承資訊等),無法在網絡中高效傳輸,不适用于大資料環境。是以,hadoop提供了一套自己的序列化機制。

與java序列化相比,hadoop序列化機制有以下特點:

- 緊湊: 隻存儲有用資訊,且緊挨着存儲,高效利用存儲空間

- 高效: 讀寫資料的額外開銷小

- 可擴充: 可以随着通信協定的更新而更新

- 互操作: 序列化後,除了java語言外的其他語言都可以使用

4. 如何實作自定義序列化?(自定義序列化操作要點)

hadoop對java中常見的對象都實作了序列化,但實際開發中,這些類型往往不能滿足要求(如自定義bean)。

MR學習總結(一):MapReduce概述與Hadoop序列化

自定義序列化操作步驟:

  1. 讓需要被序列化的Bean實作Writable接口
  2. 實作Writable接口中的write()方法,用于序列化
  3. 實作Writable接口中的readFields()方法,用于反序列化

自定義序列化舉例:

package serialze;

import org.apache.hadoop.io.Writable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

//1.讓自定義Bean實作Writable
public class FlowBean implements Writable{
    private long upFlow;
    private long downFlow;
    private long sumFlow;

    // 省略:getter & setter
    
    //2.注意:反序列化方法會通過反射機制調用空參構造,故必須要給空參構造
    public FlowBean() {
    }

    //3.實作write()用于序列化
    public void write(DataOutput dataOutput) throws IOException {
        dataOutput.writeLong(this.upFlow);
        dataOutput.writeLong(this.downFlow);
        dataOutput.writeLong(this.sumFlow);
    }

    //4.實作readFields()用于反序列化,順序要與序列化中的變量順序保持一緻
    public void readFields(DataInput dataInput) throws IOException {
        this.upFlow = dataInput.readLong();
        this.downFlow = dataInput.readLong();
        this.sumFlow = dataInput.readLong();
    }
}

           

繼續閱讀