RDD的检查点

  首先,要清楚。为什么spark要引入检查点机制?引入RDD的检查点?

    答:如果缓存丢失了,则需要重新计算。如果计算特别复杂或者计算耗时特别多,那么缓存丢失对于整个Job的影响是不容忽视的。为了避免缓存丢失重新计算带来的开销,Spark又引入检查点机制。

RDD的缓存能够在第一次计算完成后,将计算结果保存到内存、本地文件系统或者Tachyon(分布式内存文件系统)中。通过缓存,Spark避免了RDD上的重复计算,能够极大地提升计算速度。但是,如果缓存丢失了,则需要重新计算。如果计算特别复杂或者计算耗时特别多,那么缓存丢失对于整个Job的影响是不容忽视的。为了避免缓存丢失重新计算带来的开销,Spark又引入检查点(checkpoint)机制。

RDD的缓存和RDD的checkpoint的区别

缓存是在计算结束后,直接将计算结果通过用户定义的存储级别(存储级别定义了缓存存储的介质,现在支持内存、本地文件系统和Tachyon)写入不同的介质。

而检查点不同,它是在计算完成后,重新建立一个Job来计算。

为了避免重复计算,推荐先将RDD缓存,这样就能保证检查点的操作可以快速完成。

 

RDD的checkpoint的处理

  

  在缓存没有命中的情况下,首先会判断是否保存了RDD的checkpoint,如果有,则读取checkpoint。为了理解checkpoint的RDD是如何读取计算结果的,需要先看一下checkpoint的数据是如何写入的。
  首先在Job结束后,会判断是否需要checkpoint。如果需要,就调用org.apache.spark.rdd.RDDCheckpointData#doCheckpoint。doCheckpoint首先为数据创建一个目录;然后启动一个新的Job来计算,并且将计算结果写入新创建的目录;接着创建一个org.apache.spark.rdd.CheckpointRDD;最后,原始RDD的所有依赖被清除,这就意味着RDD的转换的计算链(compute chain)等信息都被清除。这个处理逻辑中,数据写入的实现在org.apache.spark.rdd.CheckpointRDD$#writeToFile。简要的核心逻辑如下:

//
创建一个保存
checkpoint
数据的目录
val path = new Path(rdd.context.checkpointDir.get, "rdd-" + rdd.id)
val fs = path.getFileSystem(rdd.context.hadoopConfiguration)

if (!fs.mkdirs(path)) {
throw new SparkException("Failed to create checkpoint path " + path)
}
//
创建广播变量
val broadcastedConf = rdd.context.broadcast(
new SerializableWritable(rdd.context.hadoopConfiguration))
//
开始一个新的

Job
进行计算,计算结果存入路径
path

rdd.context.runJob(rdd, CheckpointRDD.writeToFile[T](path.toString, broadcastedConf) _)
//
根据结果的路径
path
来创建

CheckpointRDD
val newRDD = new CheckpointRDD[T](rdd.context, path.toString)
//
保存结果,清除原始
RDD
的依赖、
Partition
信息等
RDDCheckpointData.synchronized {

cpFile = Some(path.toString)
cpRDD = Some(newRDD) // RDDCheckpointData
对应的
CheckpointRDD
rdd.markCheckpointed(newRDD)   //
清除原始
RDD
的依赖,
Partition

cpState = Checkpointed         //
标记
checkpoint
的状态为完成
}

至此,RDD的checkpoint完成,其中checkpoint的数据可以通过checkpointRDD的readFromFile读取。但是,上述逻辑在清除了RDD的依赖后,并没有和check-pointRDD建立联系,那么Spark是如何确定一个RDD是否被checkpoint了,而且正确读取checkpoint的数据呢?
答案就在org.apache.spark.rdd.RDD#dependencies的实现,它会首先判断当前的RDD是否已经Checkpoint过,如果有,那么RDD的依赖就变成了对应的Ch

eckpointRDD:
privatedefcheckpointRDD: Option[RDD[T]]=checkpointData.flatMap(_.checkpointRDD)
final def dependencies: Seq[Dependency[_]] = {
checkpointRDD.map(r => List(new OneToOneDependency(r))).getOrElse {
if (dependencies_ == null) { //
没有
checkpoint
dependencies_ = getDependencies
}

dependencies_
}
}
理解了Checkpoint的实现过程,接下来看一下computeOrReadCheckpoint的实现。前面提到了,它一共在两个地方被调用,org.apache.spark.rdd.RDD#iterator和org.apache.spark.CacheManager#getOrCompute。它实现的逻辑比较简单,首先检查当前RDD是否被Checkpoint过,如果有,读取Checkpoint的数据;否则开始计算。实现如下:
private[spark] def computeOrReadCheckpoint(split: Partition, context: TaskContext)
: Iterator[T] =

{
if (isCheckpointed) firstParent[T].iterator(split, context) else compute(split, context)
}
firstParent[T].iterator(split,context)会调用对应CheckpointRDD的iterator,最终调用到它的compute:
override def compute(split: Partition, context: TaskContext): Iterator[T] = {
val file=new Path(checkpointPath, CheckpointRDD.splitIdToFile(split.index))
CheckpointRDD.readFromFile(file, broadcastedConf, context) //

读取
Checkpoint
的数据
}

RDD的缓存

Spark RDD概念学习系列之RDD的checkpoint(九)的更多相关文章

  1. Spark RDD概念学习系列之RDD的缓存(八)

      RDD的缓存 RDD的缓存和RDD的checkpoint的区别 缓存是在计算结束后,直接将计算结果通过用户定义的存储级别(存储级别定义了缓存存储的介质,现在支持内存.本地文件系统和Tachyon) ...

  2. Spark RDD概念学习系列之RDD的转换(十)

    RDD的转换 Spark会根据用户提交的计算逻辑中的RDD的转换和动作来生成RDD之间的依赖关系,同时这个计算链也就生成了逻辑上的DAG.接下来以“Word Count”为例,详细描述这个DAG生成的 ...

  3. Spark RDD概念学习系列之RDD的操作(七)

    RDD的操作 RDD支持两种操作:转换和动作. 1)转换,即从现有的数据集创建一个新的数据集. 2)动作,即在数据集上进行计算后,返回一个值给Driver程序. 例如,map就是一种转换,它将数据集每 ...

  4. Spark RDD概念学习系列之RDD是什么?(四)

       RDD是什么? 通俗地理解,RDD可以被抽象地理解为一个大的数组(Array),但是这个数组是分布在集群上的.详细见  Spark的数据存储 Spark的核心数据模型是RDD,但RDD是个抽象类 ...

  5. Spark RDD概念学习系列之RDD的依赖关系(宽依赖和窄依赖)(三)

    RDD的依赖关系?   RDD和它依赖的parent RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency). 1)窄依赖指的是每 ...

  6. Spark RDD概念学习系列之RDD的缺点(二)

        RDD的缺点? RDD是Spark最基本也是最根本的数据抽象,它具备像MapReduce等数据流模型的容错性,并且允许开发人员在大型集群上执行基于内存的计算. 为了有效地实现容错,(详细见ht ...

  7. Spark RDD概念学习系列之rdd的依赖关系彻底解密(十九)

    本期内容: 1.RDD依赖关系的本质内幕 2.依赖关系下的数据流视图 3.经典的RDD依赖关系解析 4.RDD依赖关系源码内幕 1.RDD依赖关系的本质内幕 由于RDD是粗粒度的操作数据集,每个Tra ...

  8. Spark RDD概念学习系列之rdd持久化、广播、累加器(十八)

    1.rdd持久化 2.广播 3.累加器 1.rdd持久化 通过spark-shell,可以快速的验证我们的想法和操作! 启动hdfs集群 spark@SparkSingleNode:/usr/loca ...

  9. Spark RDD概念学习系列之RDD的创建(六)

    RDD的创建  两种方式来创建RDD: 1)由一个已经存在的Scala集合创建 2)由外部存储系统的数据集创建,包括本地文件系统,还有所有Hadoop支持的数据集,比如HDFS.Cassandra.H ...

随机推荐

  1. HeadFirst 12 (web应用安全)

    测试领域可以使用的方法,在tomcat-users.xml 中设置授权, 为什么这个不能在生产环境中呢, 因为如果这个设置在生产环境中, 那么当你想修改”授权时”, 就要修改这个xml文件, 那么就要 ...

  2. Qt环境搭建(Visual Studio)

    简述 经常有人问我编写Qt程序时使用什么IDE,其实这个真的很难回答(各有所长),只能说看个人爱好了,因为我两个都用,而且两个都很喜欢(比较多情吧O(∩_∩)O~)! 下面将进行Qt Creator与 ...

  3. XML中对特殊字符的处置

    str = str.replaceAll("‘", "‘"); str = str.replaceAll("’", "‘" ...

  4. Android利用Http下载文件

    Android利用Http下载文件 一.场景 下载存文本文件和下载如mp3等大容量的文件 界面 二.代码编写 1.AndroidMainfest.xml中配置 主要是解决网络权限和写SDCard的权限 ...

  5. HDU 1394 (逆序数) Minimum Inversion Number

    原来求逆序数还可以用线段树,涨姿势了. 首先求出原始序列的逆序数,然后递推每一个序列的逆序数. #include <cstdio> #include <cstring> #in ...

  6. Openerp上传中文名附件,下载时报错的处理方法

    文档管理中,如果上传的文件名含有中文字符,下载时会提示出错,如没有权限等.这个问题困惑我比较久的时间,通过跟踪openerp_server.log,可以看到类似提示: 2012-09-28 21:51 ...

  7. $^,$@,$?,$<,$(@D),$(@F) of makefile

    makefile下$(wildcard $^),$^,$@,$?,$<,$(@D),$(@F)代表的不同含义 $(filter-out $(PHONY) $(wildcard $^),$^)常用 ...

  8. jstl表达式

    JSTL标签库 1.什么是JSTL JSTL是apache对EL表达式的拓展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便, 它与JSP动作标签一样,只不过它不是JSP ...

  9. @Repository @Resource

    Spring的注解形式:@Repository.@Service.@Controller,它们分别对应存储层Bean,业务层Bean,和展示层Bean. @Repository.@Service.@C ...

  10. 解决mysql中文乱码(总)

    转自:http://hi.baidu.com/cnvienna/blog/item/2e99efdfd94fc61862279801.html MySQL会出现中文乱码的原因不外乎下列几点: .ser ...