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. Android开源库--ActiveAndroid(active record模式的ORM数据库框架)

    Github地址:https://github.com/pardom/ActiveAndroid 前言 我一般在Android开发中,几乎用不到SQLlite,因为一些小数据就直接使用Preferen ...

  2. How to begin with the webpage making

    1.网页制作三剑客必须要会使用.(dreamweaver  /fireworks/flash)2.学习些最基层的html语言的知识,3.在学习一些基本的html标签(要多加练习哦)4.先试着用表格进行 ...

  3. BZOJ 4571 美味

    又一部SCOI血泪史.... 唉. 就是在这棵树上一遍又一遍跑嘛. 以后不要直接求答案啊.要最后再异或起来. 要学习简单的代码风格. #include<iostream> #include ...

  4. 《深入浅出嵌入式底层软件开发》—1. ARM汇编编程基础

    1.1 ARM CPU寄存器 ARM的汇编编程,本质上就是针对CPU寄存器的编程,所以要搞清楚ARM有哪些寄存器:ARM寄存器分为两类:普通寄存器和状态寄存器:普通寄存器一共有16个,分别为R0——R ...

  5. notebook kernels

    http://10.139.97.132/user/8e6ef01ea71d3f988e61bf2db17c3031/api/kernels [{"id": "f0987 ...

  6. putty保持Session链接不断开的方法

    利用Putty登陆到远程主机后,如果长时间没有做任何操作,服务器会与本地客户端断开连接 假如设置了会话连接功能,就会每隔多少秒,客户端会发送一个空数据包给服务器,保持连接. 1. 打开putty.ex ...

  7. JavaScript对象 + Browser 对象 + HTML DOM 对象

    JavaScript 对象 Array Boolean Date Math Number String RegExp Global Browser 对象 Window Navigator Screen ...

  8. cocos2d-x 2.0 序列帧动画 深入分析

    转自:http://blog.csdn.net/honghaier/article/details/8222401 序列帧动画主要有几个类: CCSpriteFrame:精灵帧信息,序列帧动画是依靠多 ...

  9. linux echo命令的-n、-e两个参数

    echo -n 不换行输出 $echo -n "123" $echo "456" 最终输出 123456 而不是 123 456 echo -e 处理特殊字符 ...

  10. 百度地图Api详解之地图标注

    标注概述 标注(Marker)是用来表示一个点位置的可见元素,每个标注自身都包含地理信息.比如你在西单商场位置添加了一个标注,不论地图移动.缩放,标注都会跟随一起移动,保证其始终指向正确的地理位置. ...