checkpoint的原理及其使用场景
checkpoint是Spark提供的一个高级的功能,对于特别复杂的Spark程序而言,从一开始的RDD开始到最后结束,有很多transformation操作,并且执行时间很长,假如这时候,可能出现某个反复使用的RDD,因为节点故障的缘故,导致数据丢失(虽然之前持久化,但依然可能导致丢失)。这时候,由于没有容错机制的存在,当后面transformation操作再次使用到这个RDD的时候,会发现数据丢失,此时就会重新计算一分,导致Spark作业变慢。
针对上述情况,就比较适用checkpoint了,它的功能就是对于复杂Spark作业,若担心某个重要RDD丢失,那么就可以针对这个RDD开始checkpoint机制,实现容错和高可用,它会通过设置的一个容错的分布式文件系统(如HDFS),将数据写入上面。
checkpoint原理
上面是RDD checkpoint流程,如果RDD调用了checkpoint(),那么先将该RDD状态设置为MarkedForCheckpoint,接着在RDD运行结束后,会调用Job最后一个RDD的doCheckpoint()方法,它沿着finalRDD的lineage,向上查找标记为MarkedForCheckpoint的RDD,并将其标记为CheckpointingInProgress。接着启动一个单独的Job将lineage中标记为CheckpointingInProgress的RDD,进行checkpoint操作,将RDD写入预先设置好的文件系列目录中。RDD checkpoint之后会改变RDD的lineage,它会清楚掉RDD所有的依赖,并将父RDD设置为CheckpointRDD,RDD的状态变为checkpointed。
checkpoint与持久化的区别
有两个主要区别:
1、持久化是将数据保存在BlockManager(内存或磁盘),但是RDD的lineage(依赖)是不变的,但是checkpoint之后,RDD已经没有之前的依赖了,只有一个强行为其设置的CheckpointRDD,也就是说checkpoint之后RDD的lineage已经改变。
2、持久化数据丢失的可能性更大,但是checkpoint通常保存在容错的文件系统中(比如HDFS),它就不容易丢失。
checkpoint使用注意
在使用checkpoint的时候,最好先将RDD进行持久化到磁盘(DISK_ONLY),如果RDD没有持久化,那么悲剧了,本来Job结束后,由于中间RDD没有持久化,那么checkpoint Job想要将RDD的数据写入外部文件系统,还得将之前RDD重新计算一份,再将计算出来的RDD写入外部文件系统,这样效率就低了。
因此通常建议要对checkpoint的RDD,使用persist(StorageLevel.DISK_ONLY),该RDD计算完成之后会持久化到磁盘上,之后进行checkpoint操作,就直接从磁盘上读取RDD的数据,并checkpoint到外部的文件系统即可,这里不建议持久化到内存,因为内存特别容易丢失数据。