Java序列化
有關Java對象的序列化和反序列化也算是Java基礎的一部分,首先對Java序列化的機制和原理進行一些介紹。
Java序列化算法
Serialization(序列化)是一種將對象以一連串的字節描述的過程;反序列化deserialization是一種將這些字節重建成一個對象的過程。Java序列化API提供一種處理對象序列化的標準機制。
為什么要進行序列化?
Java中,一切都是對象,在分布式環境中經常需要將Object從這一端網絡或設備傳遞到另一端。這就需要有一種可以在兩端傳輸數據的協議。Java序列化機制就是為了解決這個問題而產生。
如何進行序列化?
一個對象能夠序列化的前提是實現Serializable接口,Serializable接口沒有方法,更像是個標記。有了這個標記的Class就能被序列化機制處理。
1、實現Serializable接口
2、寫個程序將對象序列化并輸出(ObjectOutputStream能把Object輸出成Byte流。將Byte流暫時存儲到serial.out文件里)
3、使用ObjectInputStream從持久的文件中讀取Bytes重建對象
Spark序列化
通過以上內容大概了解了序列化和反序列化的原理,接下來看看Spark的序列化
大部分Spark程序都具有“內存計算”的天性,所以集群中的所有資源:CPU、網絡帶寬或者是內存都有可能成為Spark程序的瓶頸。
通常情況下,如果數據完全加載到內存那么網絡帶寬就會成為瓶頸,但是你仍然需要對程序進行優化,例如采用序列化的方式保存RDD數據以便減少內存使用。
數據序列化不但能提高網絡性能還能減少內存使用。
Spark通過兩種方式來創建序列化器
Java序列化
在默認情況下,Spark采用Java的ObjectOutputStream序列化一個對象。該方式適用于所有實現了java.io.Serializable的類。通過繼承java.io.Externalizable,你能進一步控制序列化的性能。Java序列化非常靈活,但是速度較慢,在某些情況下序列化的結果也比較大。
Kryo序列化
Spark也能使用Kryo(版本2)序列化對象。Kryo不但速度極快,而且產生的結果更為緊湊(通常能提高10倍)。Kryo的缺點是不支持所有類型,為了更好的性能,你需要提前注冊程序中所使用的類(class)。
Java的序列化比較簡單,就和前面的一樣,下面主要介紹Kryo序列化的使用。
Kryo序列化怎么用?
可以在創建SparkContext之前,通過調用System.setProperty("spark.serializer", "spark.KryoSerializer"),將序列化方式切換成Kryo。
但是Kryo需要用戶進行注冊,這也是為什么Kryo不能成為Spark序列化默認方式的唯一原因,但是建議對于任何“網絡密集型”(network-intensive)的應用,都采用這種方式進行序列化方式。
Kryo文檔描述了很多便于注冊的高級選項,例如添加用戶自定義的序列化代碼。
如果對象非常大,你還需要增加屬性spark.kryoserializer.buffer.mb的值。該屬性的默認值是32,但是該屬性需要足夠大以便能夠容納需要序列化的最大對象。
最后,如果你不注冊你的類,Kryo仍然可以工作,但是需要為了每一個對象保存其對應的全類名(full class name),這是非常浪費的。
以上是Spark序列化簡單的應用,如有錯誤請指正...~