RDD程式設計

weixin_33912445發表於2017-07-21

RDD基礎

  • RDD:Resilient Distributed Datasets,彈性分散式資料集

  • 分佈在叢集中的只讀物件集合(由多個分割槽(Partition)構成,這些分割槽執行在叢集中的不同節點上)

  • 可以儲存在磁碟或記憶體中(多種儲存級別)

  • 通過並行“轉換”操作構造

  • 失效後自動重構

  • RDD可以包含Python、java、Scala中任意型別的物件,甚至可以包含使用者自定義的物件。

  • 兩種方法建立RDD:

  • 1.讀取外部資料集。

  • 2.在驅動程式裡分發驅動器程式中的物件集合(比如list和set)。

  • RDD支援兩種型別操作

    • 1.轉化操作(tranformation):由一個RDD生成一個新的RDD.舊的RDD不會被改變。map、filter、groupBy、reduceBy
    • 2.行動操作(action):對RDD計算出一個結果,並把結果返回到驅動程式中,或者寫入外部儲存系統中。count、collect、saveAsTextFile
      • 注:轉化操作返回的是RDD,行動操作返回的是其它資料型別。


        3458176-c97b6ef671cbf1a2.png
        操作示例
  • 惰性求值

  • 轉化操作和行動操作的區別在於Spark計算RDD的方式不同。RDD的轉化操作都是惰性求值,即對RDD呼叫轉化操作(如map())時,操作不會立即執行,它們只有第一次在一個行動操作中用到時才會真正計算。

  • 預設情況下,Spark的RDD會在每次對它們進行行動操作時重新計算,如果想在多個行動操作中重用同一個RDD,可以使用RDD.persist(),讓Spark把這個RDD快取起來。預設快取到記憶體中(以分割槽方式儲存到叢集中各個機器上)

  • 持久化(快取)

    • 持久化原因如上。持久化資料丟失怎麼辦?讓Spark持久化一個RDD,計算出RDD的節點會分別儲存它們所求出的分割槽資料,如果一個有持久化的節點發生故障,Spark會在用到快取的資料時重算丟失的資料分割槽,當然可以把資料備份到多個節點上,以避免單節點故障拖累進度。
  • 持久化資料方式:預設情況下persist()會把資料以序列化的形式快取在JVM的堆空間中,當我們把資料寫到磁碟或堆外儲存上是也總是使用序列化資料。

  • 持久化級別:
    如果採用快取在記憶體中的級別,當記憶體放不下是,Spark會自動利用最近最少使用(LRU)的策略吧最老的分割槽從記憶體中移除。

  • 3458176-628b6fcac749e154.png
    image.png

向Spark傳遞函式

  • Spark 的大部分轉化操作和一部分行動操作,都需要依賴使用者傳遞的函式來計算。
  • 在Scala 中,我們可以把定義的行內函數方法的引用靜態方法傳遞給Spark,就像Scala 的其他函式式API 一樣。我們還要考慮其他一些細節,比如所傳遞的函式及其引用的資料需要是可序列化的(實現了Java 的Serializable 介面)。
  • 如果在Scala 中出現了NotSerializableException,通常問題就在於我們傳遞了一個不可序列化的類中的函式或欄位。記住,傳遞區域性可序列化變數或頂級物件中的函式始終是安全的。

常見轉化操作和行動操作

3458176-269baaedcddc8b7a.png
Transformation與Action實現
  • sample(withReplacement, fraction, seed):對RDD取樣,以及是否替換。

  • 3458176-dc2bb5b8c5b5c87a.png
    對一個RDD的轉化操作
  • 3458176-5a1d2549ec1e179b.png
    對兩個RDD的轉化操作
  • 3458176-881aaaf8326c57d7.png
    對一個RDD進行的行動操作

一個完整案例

3458176-ad91d11f9fe17e28.png
wordcount案例
3458176-416737c0e73ebf10.png
程式執行流程

相關文章