Spark核心—RDD初探


本文目的

   

最近在使用Spark進行數據清理的相關工作,初次使用Spark時,遇到了一些挑(da)戰(ken)。感覺需要記錄點什么,才對得起自己。下面的內容主要是關於Spark核心—RDD的相關的使用經驗和原理介紹,作為個人備忘,也希望對讀者有用。

   

為什么選擇Spark

   

原因如下

  1. 代碼復用:使用Scala高級語言操作Spark,靈活方便,面向對象,函數編程的語言特性可以全部拿來。Scala基本上可以無縫集成java及其相關庫。最重要的是,可以封裝組件,沉淀工作,提高工作效率。之前用hive + python的方式處理數據,每個處理單元是python文件,數據處理單元之間的交互是基於數據倉庫的表格,十分不靈活,很難沉淀常見的工作。
  2. 機器學習:Spark可以實現迭代邏輯,可以輕松實現一些常見的機器學習算法,而且spark自帶機器學習庫mllib和圖算法包graphyx,為后面的數據挖掘應用提供了想象空間。

   

Spark計算性能雖然明顯比Hadoop高效,但並不是我們技術選型的主要原因,因為現有基於Hadoop +hive的計算性能已經足夠了。

   

   

基石哥—RDD

   

整個spark衍生出來的工具都是基於RDD(Resilient Distributed Datesets),如圖:

RDD是一個抽象的數據集,提供對數據並行容錯的處理。初次始使用RDD時,其接口有點類似Scala的Array,提供map,filter,reduce等操作。但是,不支持隨機訪問。剛開始不太習慣,但是逐漸熟悉函數編程和RDD 的原理后,發現隨機訪問數據的場景並不常見。

   

為什么RDD效率高

   

Spark官方提供的數據是RDD在某些場景下,計算效率是Hadoop的20X。這個數據是否有水分,我們先不追究,但是RDD效率高的由一定機制保證的:

  1. RDD數據只讀,不可修改。如果需要修改數據,必須從父RDD轉換(transformation)到子RDD。所以,在容錯策略中,RDD沒有數據冗余,而是通過RDD父子依賴(血緣)關系進行重算實現容錯。
  2. 多個RDD操作之間,數據不用落地到磁盤上,避免不必要的I/O操作。
  3. RDD中存放的數據可以是java對象,所以避免的不必要的對象序列化和反序列化。

總而言之,RDD高效的主要因素是盡量避免不必要的操作和犧牲數據的操作精度,用來提高計算效率。

   

閉包外部變量訪問原則

 

RDD相關操作都需要傳入自定義閉包函數(closure),如果這個函數需要訪問外部變量,那么需要遵循一定的規則,否則可能會出現異常。閉包函數傳入到節點時,需要經過下面的步驟:

  1. 使用反射機制,找到所有需要訪問的變量,並封裝到對象中,然后序列化
  2. 將序列化后的對象通過網絡傳輸到其他節點上
  3. 反序列化閉包對象
  4. 子指定節點執行閉包函數,外部變量在閉包內的修改不會被反饋到驅動程序。

簡而言之,就是通過網絡,傳遞函數,然后執行。所以,被傳遞的對象必須可以序列化和反序列化,否則傳遞失敗。單機本地執行時,仍然會執行上面四步。

 

廣播機制也可以做到這一點,但是頻繁的使用廣播會使代碼不夠簡潔,而且廣播設計的初衷是將較大數據緩存到節點上,避免多次數據傳輸,提高計算效率,而不是用於進行外部變量訪問。

   

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM