如何在Spark Scala中读取检查点数据帧

如何在Spark Scala中读取检查点数据帧,scala,spark-checkpoint,Scala,Spark Checkpoint,我正在尝试测试下面的程序,以获取检查点,并在应用程序由于资源不可用等原因失败时从检查点位置读取if。当我终止作业并再次触发它时,执行从一开始就重新开始。不确定还需要什么来实现这一点。谢谢 代码如下: import org.apache.log4j._ import org.apache.spark.sql.SparkSession import org.apache.spark.sql.functions._ import org.apache.spark.SparkContext import

我正在尝试测试下面的程序,以获取检查点,并在应用程序由于资源不可用等原因失败时从检查点位置读取if。当我终止作业并再次触发它时,执行从一开始就重新开始。不确定还需要什么来实现这一点。谢谢

代码如下:

import org.apache.log4j._
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf

object withCheckpoint {

  def main(args: Array[String]): Unit = {

    Logger.getLogger("org").setLevel(Level.ERROR)

    //val conf = new SparkConf().setAppName("Without Checkpoint")
    val conf = new SparkConf().setAppName("With Checkpoint")
    val sc = new SparkContext(conf)


    val checkpointDirectory = "/tmp"

    sc.setCheckpointDir(checkpointDirectory)   // set checkpoint directory

    val spark = SparkSession.builder.appName("Without Checkpoint").getOrCreate()



    /************************************************************************************************************************************************/
    /*                                                Reading source data begins here                                                               */
    /************************************************************************************************************************************************/


    val readCtryDemoFile = spark.read.option("header", "true").csv("/tmp/Ctry_Demo.csv")



    val readCtryRefFile = spark.read.option("header","true").csv("/tmp/ref_ctry.csv")



    val readCtryCntntFile = spark.read.option("header","true").csv("/tmp/ctry_to_continent.csv")


    /************************************************************************************************************************************************/
    /*                                                Reading source data Completes                                                                 */
    /************************************************************************************************************************************************/


    /************************************************************************************************************************************************/
    /*                                                Transformation begins here                                                                    */
    /************************************************************************************************************************************************/


    /*********************************************************************************/
    /* Join above created dataframes to pull respective columns                      */
    /*********************************************************************************/


    val jnCtryDemoCtryref = readCtryDemoFile.join(readCtryRefFile,Seq("NUM_CTRY_CD"))


    val jnCtryCntnt = jnCtryDemoCtryref.join(readCtryCntntFile,Seq("Alpha_2_CTRY_CD"))





    /*********************************************************************************/
    /* Checkpointing the above created Dataframe to the checkpoint Directory         */
    /*********************************************************************************/

    val jnCtryCntntchkpt = jnCtryCntnt.checkpoint()
    jnCtryCntntchkpt.collect()

    /*********************************************************************************/
    /* Creating multiple outputs based on different aggregation keys                 */
    /*********************************************************************************/

    val aggCntnNm = jnCtryCntntchkpt.groupBy("CONTINENT_NM").agg(sum("POPULATION").as("SUM_POPULATION")).orderBy("CONTINENT_NM")
    aggCntnNm.show()


    val aggCtryNm = jnCtryCntntchkpt.groupBy("Ctry_NM").agg(sum("POPULATION").as("SUM_POPULATION")).orderBy("Ctry_NM")
    aggCtryNm.show()


    val aggCtryCd = jnCtryCntntchkpt.groupBy("NUM_CTRY_CD").agg(sum("POPULATION").as("SUM_POPULATION")).orderBy("NUM_CTRY_CD")
    aggCtryCd.show()

    /************************************************************************************************************************************************/
    /*                                                Transformation begins here                                                                    */
    /************************************************************************************************************************************************/

  }
}

我希望我能澄清你的一些疑问,解释检查点并给你一个例子 介绍如何从检查点目录恢复数据集

检查点主要用于迭代算法和流处理

在批处理中,我们习惯于容错(缓存或持久化)。 这意味着,在节点崩溃的情况下,作业不会失去其状态,丢失的任务也不会丢失 重新安排给其他工人。中间结果将写入持久存储(即 必须具有容错能力,如HDFS或云对象存储)

维护RDD沿袭(缓存或持久化)提供了恢复能力,但当沿袭变得很长时,也会导致问题 -例如:迭代算法、流媒体 -恢复可能非常昂贵 -潜在堆栈溢出

检查点将数据保存到HDFS -跨节点提供容错存储 -血统不被保存 -必须在对RDD执行任何操作之前检查

数据集检查点

是Spark SQL的一项功能,用于截断逻辑查询计划 这对于高度迭代的数据算法(例如Spark)特别有用 使用Spark SQL的数据集API进行数据操作的MLlib)

检查点实际上是Spark Core(Spark SQL)的一个特性 用于分布式计算),允许重新启动驱动程序 在分布式计算的先前计算状态出现故障时 描述为RDD。已成功应用于Spark 流式处理-现在已过时的用于流处理的Spark模块 基于rddapi。 检查点截断要检查的RDD的沿袭。 该算法已成功应用于迭代机中的Spark MLlib 像ALS这样的学习算法。 Spark SQL中的数据集检查点使用检查点截断 被检查点的数据集的基础RDD的沿袭

使用数据集检查点需要指定检查点目录。 该目录存储要检查的RDD的检查点文件。使用 SparkContext.setCheckpointDir设置检查点目录的路径。 检查点可以是本地的,也可以是可靠的,这定义了检查点的可靠性 目录是。本地检查点使用执行器存储写入检查点文件 由于执行器生命周期的原因,执行器生命周期被认为是不可靠的。可靠的 检查点使用可靠的数据存储,如Hadoop HDFS

写入检查点目录

包测试
导入org.apache.log4j.{Level,Logger}
导入org.apache.spark.sql.SparkSession
导入org.apache.spark.sql.functions_
/**
*检查点
*-维护RDD沿袭提供了恢复能力,但当沿袭变得很长时,也可能导致问题
*-例如:迭代算法、流媒体
*-恢复可能非常昂贵
*-潜在堆栈溢出
*-检查点将数据保存到HDFS
*—跨节点提供容错存储
*-未保存血统
*-必须在对RDD执行任何操作之前检查
*/
对象写切点{
val spark=火花会话
.builder()
.appName(“WriteCheckPoint”)
.master(“本地[*]”)
.config(“spark.sql.shuffle.partitions”,“4”)//将数据更改为更合理的默认分区数
.config(“spark.app.id”,“WriteCheckPoint”)//以消除警告
.getOrCreate()
val sqlContext=spark.sqlContext
val sc=spark.sparkContext
//记住设置检查点目录
spark.sparkContext.setCheckpointDir(“hdfs://localhost/user/cloudera/checkpoint")
def main(参数:数组[字符串]):单位={
Logger.getRootLogger.setLevel(Level.ERROR)
//将org.apache.spark.rdd.ReliableRDDCheckpointData logger设置为INFO
//查看在检查RDD时发生的情况
//让我们使用log4japi,因此应该添加import org.apache.log4j.{Level,Logger}
Logger.getLogger(“org.apache.spark.rdd.ReliableRDDCheckpointData”).setLevel(Level.INFO)
试一试{
val nums=spark.range(5).withColumn(“random”,rand()).filter(“random>0.5”)
//必须在对RDD执行任何操作之前检查
检查点
//将模式保存为将用于从RDD重建nums数据集的模式
val schema=nums.schema
schema.printTreeString()
nums.show()
//要有机会查看Spark的web控制台:http://localhost:4040/
println(“在控制台中键入要退出的内容……”)
scala.io.StdIn.readLine()
}最后{
sc.停止()
println(“SparkContext已停止”)
spark.stop()
println(“SparkSession已停止”)
}
}
}
输出

20/06/15 16:42:50 INFO ReliableRDDCheckpointData: Done checkpointing RDD 4 to hdfs://localhost/user/cloudera/checkpoint/607daeca-6ec2-471c-9033-9c4c236880a9/rdd-4, new parent is RDD 5
root
 |-- id: long (nullable = false)
 |-- random: double (nullable = false)

+---+------------------+
| id|            random|
+---+------------------+
|  2|0.9550560942227814|
+---+------------------+
[0,2,3fee8fd1cc5108ef]
+------+------------------+
|field1|            field2|
+------+------------------+
|     2|0.9550560942227814|
+------+------------------+
您必须定义两个受保护的辅助对象 在包org.apache.spark和org.apache.spark.sql中

package org.apache.spark
/**
*SparkContext.checkpointFile是一个“受保护的[spark]”方法
*定义一个helper对象来“转义”包锁定
*/
反对我的{
导入scala.reflect.ClassTag
导入org.apache.spark.rdd.rdd
def recover[T:ClassTag](sc:SparkContext,路径:String):RDD[T]={
sc.checkpointFile[T](路径)
}
}
包org.apache.spark.sql
对象my2{
导入org.apache.spark.rdd.rdd
导入org.apache.spark.sql.{DataFrame,SparkSession}
导入org.apache.spark.sql.catalyst.InternalRow
导入org.apache.spark.sql.types.StructType
def createDataFrame(spark:SparkSession,catalystRows:RDD[InternalRow],schema:StructType):数据帧={
spark.internalCreateDataFrame(catalystRows,模式)