大數據組件-什麼是RDD,saprkRDD分區和Shuffle,緩存,Checkpoint

什麼是RDD

當有多臺電腦,多臺電腦上的分佈着不同的數據,我們使用RDD來統一這些數據命名,故而RDD就是分佈式數據集.
當有了整個在多臺計算機分佈的大型數組RDD,我們纔可以通過一系列算子對其進行操作

RDD分區以及Shuffle操作

  1. RDD分區是一個並行計算實現的手段

1.查看分區的手段

(1)使用partitions查看

rdd.partitions.size

(2)使用webUI頁面查看

node01:4040

在這裏插入圖片描述

2.通過算子指定分區數

一般情況下涉及Shuffle的操作的算子都可以指定分區數,在最後一位參數指定分區數,如果沒有指定默認從父RDD中繼承分區數

3.Spark 中的 Shuffle 操作的特點

  • 只有 Key-Value 型的 RDD 纔會有 Shuffle 操作, 例如 RDD[(K, V)], 但是有一個特例, 就是 repartition 算子可以對任何數據類型 Shuffle

RDD的緩存

1.RDD緩存作用

緩存能夠幫助開發者在進行一些昂貴操作後, 將其結果保存下來, 以便下次使用無需再次執行, 緩存能夠顯著的提升性能.

2.RDD緩存API

轉換算子的作用:生成RDD,以及RDD之間的依賴關係
Action算子的作用:生成job,去執行job,有一個job,RDD就要執行一次
我們使用緩存的意義就是減少shuffle,緩存其他算子生成的結果

(1)cahe緩存

可以使用 cache 方法進行緩存

val conf = new SparkConf().setMaster("local[6]").setAppName("debug_string")
val sc = new SparkContext(conf)

val interimRDD = sc.textFile("dataset/access_log_sample.txt")
  .map(item => (item.split(" ")(0), 1))
  .filter(item => StringUtils.isNotBlank(item._1))
  .reduceByKey((curr, agg) => curr + agg)
  .cache() //緩存rdd

val resultLess = interimRDD.sortBy(item => item._2, ascending = true).first()
val resultMore = interimRDD.sortBy(item => item._2, ascending = false).first()

println(s"出現次數最少的 IP : $resultLess, 出現次數最多的 IP : $resultMore")

sc.stop()

(2)persist(可以指定緩存級別的緩存)

al conf = new SparkConf().setMaster("local[6]").setAppName("debug_string")
val sc = new SparkContext(conf)

val interimRDD = sc.textFile("dataset/access_log_sample.txt")
  .map(item => (item.split(" ")(0), 1))
  .filter(item => StringUtils.isNotBlank(item._1))
  .reduceByKey((curr, agg) => curr + agg)
  .persist(StorageLevel.MEMORY_ONLY) 

val resultLess = interimRDD.sortBy(item => item._2, ascending = true).first()
val resultMore = interimRDD.sortBy(item => item._2, ascending = false).first()

println(s"出現次數最少的 IP : $resultLess, 出現次數最多的 IP : $resultMore")

sc.stop()

persist() 是 persist(newLevel: StorageLevel) 的一個別名, persist(newLevel: StorageLevel) 能夠指定緩存的級別

3.緩存級別設置

是否使用磁盤緩存?
是否使用內存緩存?
是否使用堆外內存?
緩存前是否先序列化?
是否需要有副本?

在這裏插入代碼片

是否反序列化形式存儲,如果是false是二進制數據,如果是true存的是對象
在這裏插入圖片描述在這裏插入圖片描述

4.緩存級別選擇

  • Spark 的存儲級別的選擇,核心問題是在 memory 內存使用率和 CPU 效率之間進行權衡。建議按下面的過程進行存儲級別的選擇:
  • 一般使用RDD 默認存儲級別MEMORY_ONLY。這是 CPU 效率最高的選項,因爲沒有序列化這個過程,允許 RDD 上的操作儘可能快地運行.
  • MEMORY_ONLY_SER 他使用了序列化 數據變爲二進制保存更加節省空間,但仍然能夠快速訪問。(Java和Scala)
  • 不要溢出到磁盤,除非計算您的數據集的函數是昂貴的.溢寫效率比較低
  • 如果需要快速故障恢復,請使用複製的存儲級別(末尾加2)。複製的數據可讓您你繼續在 RDD 上運行任務,而無需等待重新計算一個丟失的分區.

RDD的Checkpoint

1.Checkpoint使用場景

就是可以將迭代多次RDD存儲在HDFS上
Checkpoint 的主要作用是斬斷 RDD 的依賴鏈, 並且將數據存儲在可靠的存儲引擎中, 例如支持分佈式存儲和副本機制的 HDFS.

2.Checkpoint 和 Cache 的區別

他們的區別主要在以下兩點

  • Checkpoint 可以保存數據到 HDFS 這類可靠的存儲上, Persist 和 Cache 只能保存在本地的磁盤和內存中
  • Checkpoint 可以斬斷 RDD 的依賴鏈, 而 Persist 和 Cache 不行
  • 因爲 CheckpointRDD 沒有向上的依賴鏈, 所以程序結束後依然存在, 不會被刪除. 而 Cache 和 Persist 會在程序結束後立刻被清除.

3.使用 Checkpoint

val conf = new SparkConf().setMaster("local[6]").setAppName("debug_string")
val sc = new SparkContext(conf)
//設置保存Checkpoint目錄,也可以設置hdfs上目錄
sc.setCheckpointDir("checkpoint") 

val interimRDD = sc.textFile("dataset/access_log_sample.txt")
  .map(item => (item.split(" ")(0), 1))
  .filter(item => StringUtils.isNotBlank(item._1))
  .reduceByKey((curr, agg) => curr + agg)

interimRDD.checkpoint() //

interimRDD.collect().foreach(println(_))

sc.stop()

在使用 Checkpoint 之前需要先設置 Checkpoint 的存儲路徑, 而且如果任務在集羣中運行的話, 這個路徑必須是 HDFS 上的路徑
開啓 Checkpoint

val interimRDD = sc.textFile("dataset/access_log_sample.txt")
  .map(item => (item.split(" ")(0), 1))
  .filter(item => StringUtils.isNotBlank(item._1))
  .reduceByKey((curr, agg) => curr + agg)
  .cache()  //在Checkpoint之前先cache緩存一下

interimRDD.checkpoint()
interimRDD.collect().foreach(println(_))

checkpoint 之前先 cache 一下, 因爲 checkpoint 會重新計算整個 RDD 的數據然後再存入 HDFS 等地方.
所以上述代碼中如果 checkpoint 之前沒有 cache, 則整個流程會被計算兩次, 一次是 checkpoint, 另外一次是 collect

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章