如何使用RDD检查点在Spark应用程序之间共享数据集?

时间:2017-06-03 01:01:02

标签: apache-spark

我有一个spark应用程序,并检查代码中的rdd,一个简单的代码片段如下(这很简单,只是为了说明我的问题。):

@Test
  def testCheckpoint1(): Unit = {
    val data = List("Hello", "World", "Hello", "One", "Two")
    val rdd = sc.parallelize(data)
    //sc is initialized in the setup 
    sc.setCheckpointDir(Utils.getOutputDir())
    rdd.checkpoint()
    rdd.collect()
  }

当rdd在文件系统上被检查点时。我写了另一个Spark应用程序,并将获取上述代码中的检查点数据, 并将其作为RDD作为第二个应用程序的起点

ReliableCheckpointRDD正是完成工作的RDD,但这个RDD对Spark是私有的。

因此,由于ReliableCheckpointRDD是私有的,因此看起来火花不建议在spark之外使用ReliableCheckpointRDD。

我会问是否有办法做到这一点。

1 个答案:

答案 0 :(得分:1)

引用RDD.checkpoint的scaladoc(突出我的):

  

checkpoint():单位将此RDD标记为检查点。它将保存到使用SparkContext#setCheckpointDir设置的检查点目录内的文件中,并且将删除对其父RDD的所有引用。必须在对此RDD执行任何作业之前调用此函数。 强烈建议此RDD保留在内存中,否则将其保存在文件中将需要重新计算。

因此,RDD.checkpoint将切断RDD谱系并触发部分计算,因此您已经预先计算了一些内容,以防您的Spark应用程序失败并停止。

请注意,RDD检查点与RDD缓存非常相似,但缓存会使部分数据集专用于某些Spark应用程序。

让我们阅读Spark Streaming的Checkpointing(这在某种程度上扩展了RDD检查点的概念,使其更接近您需要在Spark应用程序之间共享计算结果):

  

数据检查点将生成的RDD保存到可靠的存储中。在一些跨多个批次组合数据的有状态转换中,这是必需的。在这种转换中,生成的RDD依赖于先前批次的RDD,这导致依赖关系链的长度随时间增加。为了避免恢复时间的这种无限增加(与依赖链成比例),有状态转换的中间RDD周期性地检查点到可靠存储(例如HDFS)以切断依赖链。

所以,是的,从某种意义上说,你可以用RDD检查点的形式分享计算的部分结果,但是如果你可以使用JSON使用“官方”界面保存部分结果,你甚至想要这样做,实木复合地板,CSV等。

怀疑使用此内部持久性接口可以提供比使用上述格式更多的功能和灵活性。是的,使用RDD检查点在Spark应用程序之间共享数据集确实在技术上是可行的,但是为了获得不多的收益而付出了太大的努力。