checkpoint在spark中主要有两块应用:一块是在spark core中对RDD做checkpoint,可以切断做checkpoint RDD的依赖关系,将RDD数据保存到可靠存储(如HDFS)以便数据恢复;另外一块是应用在spark streaming中,使用checkpoint用来保存DStreamGraph以及相关配置信息,以便在Driver崩溃重启的时候能够接着之前进度继续进行处理(如之前waiting batch的job会在重启后继续处理)。

本文主要将详细分析checkpoint在以上两种场景的读写过程。

1,spark core中checkpoint分析

1.1,checkpoint的使用方法

使用checkpoint对RDD做快照大体如下:

sc.setCheckpointDir(checkpointDir.toString)
val rdd = sc.makeRDD(1 to 20, numSlices = 1)
rdd.checkpoint()

首先,设置checkpoint的目录(一般是hdfs目录),这个目录用来将RDD相关的数据(包括每个partition实际数据,以及partitioner(如果有的话))。然后在RDD上调用checkpoint的方法即可。

1.2,checkpoint写流程

可以看到checkpoint使用非常简单,设置checkpoint目录,然后调用RDD的checkpoint方法。针对checkpoint的写入流程,主要有以下四个问题:

Q1:RDD中的数据是什么时候写入的?是在rdd调用checkpoint方法时候吗?

Q2:在做checkpoint的时候,具体写入了哪些数据到HDFS了?

Q3:在对RDD做完checkpoint以后,对做RDD的本省又做了哪些收尾工作?

Q4:实际过程中,使用RDD做checkpoint的时候需要注意什么问题?

弄清楚了以上四个问题,我想对checkpoint的写过程也就基本清楚了。接下来将一一回答上面提出的问题。

A1:首先看一下RDD中checkpoint方法,可以看到在该方法中是只是新建了一个ReliableRDDCheckpintData的对象,并没有做实际的写入工作。实际触发写入的时机是在runJob生成改RDD后,调用RDD的doCheckpoint方法来做的。

A2:在经历调用RDD.doCheckpoint → RDDCheckpintData.checkpoint → ReliableRDDCheckpintData.doCheckpoint → ReliableRDDCheckpintData.writeRDDToCheckpointDirectory后,在writeRDDToCheckpointDirectory方法中可以看到:将作为一个单独的任务(RunJob)将RDD中每个parition的数据依次写入到checkpoint目录(writePartitionToCheckpointFile),此外如果该RDD中的partitioner如果不为空,则也会将该对象序列化后存储到checkpoint目录。所以,在做checkpoint的时候,写入的hdfs中的数据主要包括:RDD中每个parition的实际数据,以及可能的partitioner对象(writePartitionerToCheckpointDir)。

A3:在写完checkpoint数据到hdfs以后,将会调用rdd的markCheckpoined方法,主要斩断该rdd的对上游的依赖,以及将paritions置空等操作。

A4:通过A1,A2可以知道,在RDD计算完毕后,会再次通过RunJob将每个partition数据保存到HDFS。这样RDD将会计算两次,所以为了避免此类情况,最好将RDD进行cache。即1.1中rdd的推荐使用方法如下:

sc.setCheckpointDir(checkpointDir.toString)
val rdd = sc.makeRDD(1 to 20, numSlices = 1)
rdd.cache()
rdd.checkpoint()

1.3,checkpoint 读流程

在做完checkpoint后,获取原来RDD的依赖以及partitions数据都将从CheckpointRDD中获取。也就是说获取原来rdd中每个partition数据以及partitioner等对象,都将转移到CheckPointRDD中。

在CheckPointRDD的一个具体实现ReliableRDDCheckpintRDD中的compute方法中可以看到,将会从hdfs的checkpoint目录中恢复之前写入的partition数据。而partitioner对象(如果有)也会从之前写入hdfs的paritioner对象恢复。

总的来说,checkpoint读取过程是比较简单的。

2,spark streaming中checkpoint分析

2.1,streaming中checkpoint的使用方法

在streaming中使用checkpoint主要包含以下两点:设置checkpoint目录,初始化StreamingContext时调用getOrCreate方法,即当checkpoint目录没有数据时,则新建streamingContext实例,并且设置checkpoint目录,否则从checkpoint目录中读取相关配置和数据创建streamingcontext。

// Function to create and setup a new StreamingContext
def functionToCreateContext(): StreamingContext = {
val ssc = new StreamingContext(...) // new context
val lines = ssc.socketTextStream(...) // create DStreams
...
ssc.checkpoint(checkpointDirectory) // set checkpoint directory
ssc
}

// Get StreamingContext from checkpoint data or create a new one
val context = StreamingContext.getOrCreate(checkpointDirectory, functionToCreateContext _)

2.2,streaming中checkpoint写流程

同样,针对streaming中checkpoint的写流程,主要有以下三个问题,并对此做相关解释。

Q1:streaming中checkpoint是在何时做的?

A1:在spark streaming中,jobGenerator会定期生成任务(jobGenerator.generateJobs)。在任务生成后将会调用doCheckpoint方法对系统做checkpoint。此外,在当前批次任务结束,清理metadata(jobGenerator.clearMetadata)时,也会调用doCheckpoint方法。

Q2:在streaming checkpoint过程中,具体都写入了哪些数据到checkpoint目录?

A2: 做checkpoint的主要逻辑基本都在JobGenerator.doCheckpoint方法中。

在该方法中,首先更新当前时间段需要做checkpoint RDD的相关信息,如在DirectKafkaInputDStream中,将已经生成的RDD信息的时间,topic,partition,offset等相关信息进行更新。

其次,通过checkpointWriter将Checkpoint对象写入到checkpoint目录中(CheckPoint.write → CheckpointWriteHandle)。至此,我们清楚了,写入到checkpoint目录的数据其实就是Checkpoint对象。

Checkpoint主要包含的信息如下:

val master = ssc.sc.master
val framework = ssc.sc.appName
val jars = ssc.sc.jars
val graph = ssc.graph
val checkpointDir = ssc.checkpointDir
val checkpointDuration = ssc.checkpointDuration
val pendingTimes = ssc.scheduler.getPendingTimes().toArray
val sparkConfPairs = ssc.conf.getAll

具体包括相关配置信息,checkpoint目录,DStreamGraph等。对于DStreamGraph,主要包含InputDstream以及outputStream等相关信息,从而我们可以看出定义应用相关的计算函数也被序列化保存到checkpoint目录中了。

Q3:  streaming checkpoint都有哪些坑?

A3:

从A2中可以看到,应用定义的计算函数也被序列化到checkpoint目录,当应用代码发生改变时,此时就没法从checkpoint恢复。个人感觉这是checkpoint在生产环境使用中碰到的最大障碍。

另外,当从checkpoint目录恢复streamingContext时,配置信息啥的也都是从checkpoint读取的(只有很少的一部分配置是reload的,具体见读流程),当重启任务时,新改变的配置就可能不生效,导致很奇怪的问题。

此外,broadcast变量在checkpoint中使用也受到限制(SPARK-5206)。

2.3,streaming中checkpoint读流程

在spark streaming任务从checkpoint恢复streamingContext时,将会触发对之前保存的checkpoint对象的读取动作。在StreamingContext的getOrCreate方法中,通过checkpoint.read方法从checkpoint目录中恢复之前保存的Checkpoint对象。一旦该对象存在,将使用Checkpoint创建streamingContext。于此同时,在StreamingContext中DStreamGraph的恢复借助之前保存的对象,并且调用restoreCheckpointData恢复之前生成而未计算的RDD,从而接着之前的进度进行数据处理。

另外需要注意的时,以下配置信息在使用checkpoint创建streamingContext时,这些配置信息是重新加载的。

val propertiesToReload = List(
"spark.yarn.app.id",
"spark.yarn.app.attemptId",
"spark.driver.host",
"spark.driver.bindAddress",
"spark.driver.port",
"spark.master",
"spark.yarn.jars",
"spark.yarn.keytab",
"spark.yarn.principal",
"spark.yarn.credentials.file",
"spark.yarn.credentials.renewalTime",
"spark.yarn.credentials.updateTime",
"spark.ui.filters",
"spark.mesos.driver.frameworkId")

3,小结

本文主要分析了checkpoint在spark core和streaming读写的基本过程,并且指出了在checkpoint使用中碰到一些坑。对于spark streaming,个人认为checkpoint在生产环境不适宜使用。

spark checkpoint详解的更多相关文章

  1. oracle checkpoint 详解

    Oracle checkpoint详解 topcheckpoint扫盲 top什么是checkpoint 在数据库系统中,写日志和写数据文件是数据库中IO消耗最大的两种操作,在这两种操作中写数据文件属 ...

  2. 转: OGG Checkpoint 详解

    1. OGG Checkpoint 详解 定位中断的位置,下次启动从中断的位置开始恢复. 1.target 端配置: 2.一条记录对应一个replicat 一. Extract Checkpoints ...

  3. Spark参数详解 一(Spark1.6)

    Spark参数详解 (Spark1.6) 参考文档:Spark官网 在Spark的web UI在"Environment"选项卡中列出Spark属性.这是一个很有用的地方,可以检查 ...

  4. OGG 11g Checkpoint 详解

    OGG Checkpoint 详解   定位中断的位置,下次启动从中断的位置开始恢复.     1.target  端配置: 2.一条记录对应一个replicat   一. Extract Check ...

  5. Spark:常用transformation及action,spark算子详解

    常用transformation及action介绍,spark算子详解 一.常用transformation介绍 1.1 transformation操作实例 二.常用action介绍 2.1 act ...

  6. Spark框架详解

    一.引言 作者:Albert陈凯链接:https://www.jianshu.com/p/f3181afec605來源:简书 Introduction 本文主要讨论 Apache Spark 的设计与 ...

  7. Spark中的Spark Shuffle详解

    Shuffle简介 Shuffle描述着数据从map task输出到reduce task输入的这段过程.shuffle是连接Map和Reduce之间的桥梁,Map的输出要用到Reduce中必须经过s ...

  8. HUE配置文件hue.ini 的Spark模块详解(图文详解)(分HA集群和HA集群)

    不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...

  9. mysql事务、redo日志、undo日志、checkpoint详解

    转载: https://zhuanlan.zhihu.com/p/34650908 事务: 说起mysql innodb存储引擎的事务,首先想到就是ACID(不知道的请google),数据库是如何做到 ...

随机推荐

  1. (转)Android学习-使用Async-Http实现图片压缩并上传功能

    (转)Android学习-使用Async-Http实现图片压缩并上传功能 文章转载自:作者:RyaneLee链接:http://www.jianshu.com/p/940fc7ba39e1 让我头疼一 ...

  2. 引用类型中的push()、pop()、shift()方法

    /** * write by waitingbar1014 * time 2013.10.18 * 用途:常用于如一堆游戏激活码中获得抽取的值 * **/ //有以下一个数组: var arrayli ...

  3. mybatis入门--#{}和${}的区别

    我们知道,在mybatis中,sql语句是需要我们自己写的.跟在普通的sql不一样的是,我们在使用mybatis框架的时候,使用的占位符不是 ? 而是 #{} 有时候还会出现这个符号 ${} 这些符号 ...

  4. SoftwareEngineering.APIDesign.iOS

    API Design for iOS/Mac (Objective-c Edition) 1. UI Control Library API的设计 和已有组件保持一致(例如: 使用标准的API, 模型 ...

  5. C#泛型的学习

    编码: class Program { static void Main(string[] args) { ; Test<int> test1 = new Test<int>( ...

  6. Luogu 3690 LCT - 模板

    推荐几篇比较好的博客: FlashHu 的 讲解比较好 : 传送门 Candy 的 代码~ : 传送门 以及神犇Angel_Kitty的 学习笔记: 传送门 Code V 模板 #include< ...

  7. Getting svn to ignore files and directories

    August 27, 2013Software Developmentresources, subversion, svn, tutorial, version control Who knew it ...

  8. Null value was assigned to a property of primitive type setter of cn.itcast.oa.domain.Forum.topicCount

    [引用http://m.blog.csdn.net/blog/u013998070/41087351] Null value was assigned to a property of primiti ...

  9. 设计服务类网站原型模板分享——Fortyseven

    Fortyseven是一个设计服务网站,设计理念是帮助企业设计出赚钱的品牌和网站.该网站图文排版配色都很不错,很有欧美复古风,多采用大图结合文案排版. 本原型由国产Mockplus(原型工具)和iDo ...

  10. 上传文件 input file

    //-----前端文件------- form id="uploadForm" enctype="multipart/form-data"> <in ...