概述
本文講述如何使用checkpoint來保存rdd,並讀取還原rdd的數據。
checkpoint簡介
checkpoint可以把rdd持久化到磁盤上,可以是本地磁盤也可以是外部存儲系統(比如:hadoop文件系統)。
要注意的是:在rdd進行checkpoint時,會先把rdd的血緣(lineage)去掉。
另外:在大數據量的情況下,保存和讀取rdd數據也會十分消耗資源。所以,是選擇使用checkpoint機制來還原數據,還是重新計算該rdd,在實際的場景中還需要權衡。
如何保存和讀入checkpoint的數據
- 通過checkpoint保存rdd的方法
在保存rdd數據時首先要指定一個外部存儲的目錄,指定目錄的函數爲:
sc.setCheckpointDir
- 讀取checkpoint的rdd
讀取checkpoint的rdd時需要知道rdd存儲的路徑。在SparkContext中有一個函數可以直接讀取checkpoint目錄中的數據,該函數的定義如下:
protected[spark] def checkpointFile[T: ClassTag](path: String): RDD[T] = withScope {
new ReliableCheckpointRDD[T](this, path)
}
可知該函數會返回一個ReliableCheckpointRDD。但該函數是protected的,不能通過sparkContext直接調用。
我們知道protected函數的權限是包範圍內或子類,所以我們需要定義一個類,該類需要在和SparkContext相同的包內,也就是在包:package org.apache.spark中。
checkpoint實戰
通過checkpoint持久化保存rdd數據
啓動spark-shell,並輸入以下命令:
sc.setCheckpointDir("hdfs://hadoop3:7078/data/checkpoint")
val rdd1 = sc.parallelize(Array((1,2),(3,4),(5,6),(7,8)),3)
rdd1.checkpoint()
//注意:要action才能觸發checkpoint
rdd1.take(1)
通過以上幾行代碼,就把rdd保存到hdfs的data/checkpoint目錄下了。
創建讀取checkpoint的工具類
SparkContext中有一個checkpointFile方法可以直接讀取
把下面的程序打成jar包,比如叫:dospark.jar
package org.apache.spark
import org.apache.spark.rdd.RDD
object RDDUtilsInSpark {
def getCheckpointRDD[T](sc:SparkContext, path:String) = {
//path要到part-000000的父目錄
val result : RDD[Any] = sc.checkpointFile(path)
result.asInstanceOf[T]
}
}
//val checkpointPath="hdfs://hadoop3:7078/data/checkpoint"
//val rdd2 : RDD[Any] = sc.checkpointFile(checkpointPath)
注意:寫入rdd數據時,會生成一些臨時目錄,而rdd是保存在這些臨時目錄的rdd-0,rdd-1這些目錄下。
讀取checkpoint的rdd數據時,需要把目錄指定到最底層目錄。
checkpoint後的目錄如下:
ubuntu@vm10-210-1-16:~$ hadoop fs -lsr /data/checkpoint/
lsr: DEPRECATED: Please use 'ls -R' instead.
drwxr-xr-x - ubuntu supergroup 0 2019-04-16 17:22 /data/checkpoint/7d020f7b-9122-4247-ba2d-80b8277a1022
drwxr-xr-x - ubuntu supergroup 0 2019-04-16 17:22 /data/checkpoint/7d020f7b-9122-4247-ba2d-80b8277a1022/rdd-0
-rw-r--r-- 3 ubuntu supergroup 10 2019-04-16 17:22 /data/checkpoint/7d020f7b-9122-4247-ba2d-80b8277a1022/rdd-0/part-00000
-rw-r--r-- 3 ubuntu supergroup 10 2019-04-16 17:22 /data/checkpoint/7d020f7b-9122-4247-ba2d-80b8277a1022/rdd-0/part-00001
-rw-r--r-- 3 ubuntu supergroup 20 2019-04-16 17:22 /data/checkpoint/7d020f7b-9122-4247-ba2d-80b8277a1022/rdd-0/part-00002
drwxr-xr-x - ubuntu supergroup 0 2019-04-16 17:22 /data/checkpoint/ece299b9-b352-4138-8ee6-44dcdcb5eed6
讀取時需要要指定到rdd-0這一層的目錄才能讀取數據。
使用工具類讀取checkpoint的數據
這裏講述如何在spark-shell中來讀取checkpoit的數據,步驟如下:
- 啓動spark-shell時,加上dospark.jar這個包:
spark-shell --jars dospark.jar
- 使用:
import org.apache.spark.rdd.RDD
import org.apache.spark.RDDUtilsInSpark
val checkpointPath="hdfs://hadoop3:7078/data/checkpoint/7d020f7b-9122-4247-ba2d-80b8277a1022/rdd-0"
val rdd : RDD[(Int, Int)]= RDDUtilsInSpark.getCheckpointRDD(sc, checkpointPath)
println(rdd.count())
rdd.collect().foreach(println)
總結
本文講述瞭如何通過spark的checkpoint把rdd數據保存到外部分佈式文件系統中。再通過SparkContext的checkpointFile函數讀取rdd數據並還原。
要注意的是:在大數據量的情況下,保存和讀取rdd數據也會十分消耗資源。
所以,是使用checkpoint機制來還原數據,還是重新計算該rdd,在實際的場景中還需要權衡。
參考
- 讀取spark checkpoint的數據
- spark-2.3源碼