天天看點

Hadoop2源碼分析-序列化篇1.概述2.序列化的由來3.Hadoop序列化依賴圖詳解4.Writable常用實作類5.總結6.結束語

  上一篇我們了解了mapreduce的相關流程,包含mapreduce v2的重構思路,新的設計架構,與mapreduce v1的差別等内容,今天我們在來學習下在hadoop v2中的序列化的相關内容,其目錄如下所示:

序列化的由來

hadoop序列化依賴圖詳解

writable常用實作類

  下面,我們開始學習今天的内容。

  我們知道java語言對序列化提供了非常友好的支援,在定義一個類時,如果我們需要序列化一個類,隻需要實作該類的序列化接口即可。場景:讓一個appinfo類能夠被序列化,代碼如下所示:

 這麼定義,不需要其他的操作,java會自動的處理各種對象關系。雖然,java的序列化接口易于實作且内建支援,同樣,它的不足之處也是暴露無遺,它占用空間過大,額外的開銷導緻速度降低。這些缺點對于hadoop來說是不合适的,導緻hadoop沒有采用java自身的序列化機制,而是hadoop自己開發了一套适合自己的序列化機制。

  由于 hadoop 的 mapreduce 和 hdfs 都有通信的需求,需要對通信的對象進行序列化。而且,hadoop本身需要序列化速度要快,體積要小,占用帶寬低等要求。是以,了解hadoop的序列化過程是很有必要的,下面我們對hadoop的序列化内容做進一步學習研究。

  注:本文不對java的serializable接口做詳細贅述,若需了解 ,請參考官方文檔:http://docs.oracle.com/javase/7/docs/api/java/io/serializable.html

  在hadoop的序列化機制中,org.apache.hadoop.io 中定義了大量的可序列化對象,他們都實作了 writable 接口,writable接口中有兩個方法,如下所示:

write:将對象寫入位元組流。

readfields:從位元組流中解析出對象。

  writeable源碼如下所示:

 下面我們來看看hadoop序列化的依賴圖關系,如下圖所示:

Hadoop2源碼分析-序列化篇1.概述2.序列化的由來3.Hadoop序列化依賴圖詳解4.Writable常用實作類5.總結6.結束語

  從上圖我們可以看出,writablecomparable接口同時繼承了writable和comparable接口。

  writablecomparable源碼如下所示:

接着我們再來看看comparable的源碼,代碼如下所示:

 通過源碼的閱讀,我們可以發現,java的api提供的comparable接口,它隻有一個方法,就是compareto,該方法用于比較兩個對象。

  上圖中列舉了hadoop序列化接口中的所有類型,這裡我們主要研究一些常用的實作類,如intwriteable,text,longwriteable等。

  首先我們來看看intwriteable和longwriteable的源碼,具體代碼如下所示:

intwriteable

longwritable

  從源碼intwritable和longwriteable中可以看到,兩個類中都包含内部類comparator,該類的作用是用來支援在沒有反序列化的情況下直接對資料進行處理。源碼中的compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)方法不需要建立intwritable對象,效率比compareto(object o)高。

text

  text的源碼大約有670多行,這裡就不貼了,若大家要閱讀詳細的text源碼,請在hadoop的org.apache.hadoop.io的包下,找到text類進行閱讀,下面隻截取text的部分源碼,部分源碼如下:

從源碼中看出,text繼承類binarycomparable基類,并實作了writablecomparable<binarycomparable>接口,writablecomparable在上面已贅述過了,下面我們來分析一下binarycomparable,首先我們來檢視一下binarycomparable的源碼,部分源碼如下所示:

我們發現binarycomparable(實作了comparable接口)是一個抽象類,由該抽象類的子類去實作了hadoop二進制的序列化。該抽象類中有兩個compareto方法,代碼如下所示:

從代碼中,我們可以看出,兩個compareto方法中依賴writablecomparator的靜态方法comparebytes來完成二進制資料的比較。另外,從text類的注視中可以看出,text是基于utf-8編碼的writeable類,注視内容如下所示:

  一般來說,在開發hadoop項目時,我們認為它等價于java的string類型,即java.lang.string。

  通過本篇部落格的學習,我們對hadoop的序列化有了較深的認識,對intwriteable,longwriteable,text等實作類也有所了解,這對我們在經後開發hadoop項目,編寫相應的mr作業是有所幫助的。在類型的選擇上,我們是可以做到心中有數的。

  這篇部落格就和大家分享到這裡,如果大家在研究學習的過程當中有什麼問題,可以加群進行讨論或發送郵件給我,我會盡我所能為您解答,與君共勉!