序列化就是把內存中的對象的狀態信息轉換成字節序列,以便於存儲(持久化)和網絡傳輸
反序列化就是就將收到的字節序列或者是硬盤的持久化數據,轉換成內存中的對象。
1.JDK的序列化
只要實現了serializable接口就能實現序列化與反序列化,一定要加上序列化版本ID serialVersionUID,這個是用來識別序列化的之前的類到底是哪一個。比如希望類的不同版本對序列化兼容,需要確保類的不同版本具有相同的serialVersionUID;
Java序列化算法需要考慮:
將對象實例相關的類元數據輸出。
遞歸地輸出類的超類描述直到不再有超類。
類元數據完了之后,開始從最頂層的超類開始輸出對象實例的實際數據值
從上至下遞歸輸出實例的數據
所以java序列化很強大,序列化得到的信息很詳細,但是序列化后很占內存。
2.Hadoop序列化
相對於JDK比較簡潔,在急群眾信息的傳遞主要就是靠這些序列化的字節樓來傳遞的,所以更快速度,容量更小。
hadoop序列化特點:
1.緊湊:帶寬是集群中信息傳遞的最寶貴的資源所以我們必須想法設法縮小傳遞信息的大小 。
java序列化不夠靈活,為了更好的控制序列化的整個流程所以使用Writable
java序列化會保存類的所有信息 依賴等,hadoop序列化不需要
2.對象可重用:JDK的反序列化會不斷地創建對象,這肯定會造成一定的系統開銷,但是在hadoop的反 序列化中,能重復的利用一個對象的readField方法來重新產生不同的對象。
java序列化每次序列化都要重新創建對象,內存消耗大。Writable可以重用。
3.可拓展性
hadoop自己寫序列化很容易,可以利用實現hadoop的Writable接口 實現了直接比較字符流以確定兩個Writable對象的大小。
而java不是,java的序列化機制在每個類的對象第一次出現的時候保存了每個類的信息, 比如類名, 第二次出現的類對象會有一個類的reference, 導致空間的浪費
可以使用開源的序列化框架protocol Buffers,Avro等框架
hadoop原生的序列化類需要實現一個叫Writeable的接口,類似於serializable接口
實現Writable接口必須實現兩個方法:write(DataOutputStream out);readField(DataInputStream in)方法。
YARN的序列化就是用Google開發的序列化框架protocol Buffers,proto目前支持支持三種語言C++,java,Python所以RPC這一層我們就可以利用其他語言來做文章
Apache的Thrift和Google的Protocol Buffer也是比較流行的序列化框架,但是在Hadoop里使用是有限的,只用於RPC和數據交互