當前位置: 首頁>>編程語言>>正文


Spark二進製文件讀寫

在大數據處理中,有時候要將spark集群上處理好的數據拷貝到本地做進一步處理:比如本地單機運算或者作為在線服務的數據。如果直接拷貝字符串文本,耗費帶寬和時間。如何來優化這個拷貝性能呢?假設要拷貝的是海量整數數據,比如Int32, 如果我們用字符串傳遞,可能需要10個Byte;如果使用二進製字節傳遞,我們隻需要4個Byte。

不同的傳遞方式,有2.5倍的空間節省,在海量數據的情況下,這個優化是非常可觀的。那麽,問題變成了:如何使用spark將數據存成二進製格式,並且這個二進製在本地是可以解析的呢?

我們知道,目前spark[version<=1.6]可以比較方便地讀取二進製文件,使用的接口是:

sc.binaryRecords

但是並沒有saveAsBinaryFile之類的方法,隻是有

sc.saveAsSequenceFile

之類的方法可以保存二進製文件,但是這個方法保存的結果是sequence格式,在本地不借助第三方庫解析起來非常不便。

事實上,通過一些簡單繼承和重載,我們可以實現自己的saveAsBinaryFile:隻需要自己實現一個hadoop文件的OutputFormat。

假設我們現在要保存RDD[(Long, Long)], 以scala語言為例,簡要coding說明如下:

首先定義一個自己的hadoop文件輸出類BinaryFileOutputFormat[java語言],繼承自FileOutputFormat ,參考Spark源碼中的TextOutputFormat。

Screen Shot 2016-06-07 at 20.15.09

上麵隻圖示了部分代碼,最關鍵的是:重寫writeObject方法,改為將(Long, Long)序列化為java的Byte[]之後再輸出,其他變量和方法適當修改。

然後定義一個saveAsBinaryFile[scala語言]方法。

Screen Shot 2016-06-07 at 20.28.38

最後生成的文件可以使用hadoop fs -cat /xxx/* 拷貝到本地,再使用各種語言解析, 例如使用C/C++的fread讀取8+8 Bytes,然後反序列化為長整數。

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/1049.html,未經允許,請勿轉載。