如何使用RDD持久化和缓存?

时间:2015-06-23 12:34:42

标签: java apache-spark bigdata spark-streaming

请告诉我如何使用RDD方法Persist()和Cache(),这似乎是我常用java编写的常规程序,Say for sparkStreaming,这是DAG的继续执行,其中每次都有值RDD将得到更新,因此perist / cache也将被再次调用&再次,将导致覆盖该RDD。

但正如下面的文档所示,似乎这些方法仅对交互式shell有用,或者是否有任何方法可以更有效地在我的顺序程序中使用缓存/持久RDD与仅仅存储所需的RDD相比任何参考变量。

Spark Doc Link

scala> linesWithSpark.cache()
res7: spark.RDD[String] = spark.FilteredRDD@17e51082

scala> linesWithSpark.count()
res8: Long = 19

scala> linesWithSpark.count()
res9: Long = 19

VS

在顺序火花流工作中,我认为这是非常相同的,不会一次又一次地进行评估。

JavaRDD sortedRDD =baseRDD.filter(f(x));

sortedRDD.count();
sortedRDD.saveAsNewHadoopAPIFile();
// Or Anything we want !   

如果你能帮助解决这个疑问,我将不胜感激。 谢谢!

2 个答案:

答案 0 :(得分:3)

Spark中最重要的功能之一是跨操作在内存中持久化(或缓存)数据集。当您持久保存RDD时,每个节点都会存储它在内存中计算的任何分区,并在该数据集(或从中派生的数据集)的其他操作中重用它们。这使得未来的行动更快(通常超过10倍)。缓存是迭代算法和快速交互式使用的关键工具。 您可以使用persist()或cache()方法标记要保留的RDD。第一次在动作中计算它,它将保留在节点的内存中。 Spark的缓存是容错的 - 如果丢失了RDD的任何分区,它将使用最初创建它的转换自动重新计算。 cache()方法是使用默认存储级别的简写,即StorageLevel.MEMORY_ONLY(在内存中存储反序列化的对象)。

val linesWithSpark  = sc.textFile("/home/kishore/test.txt")
linesWithSpark.cache()
linesWithSpark.count()

它什么都不做。 RDD.cache也是一个懒惰的操作。该文件仍未读取。但是现在RDD说"读取这个文件,然后缓存内容"。如果您第一次运行linesWithSpark.count,则将加载,缓存和计算该文件。如果再次调用linesWithSpark.count,则操作将使用缓存。它只会从缓存中获取数据并计算行数。

答案 1 :(得分:0)

缓存和持久性都用于保存Spark RDD,Dataframe和Dataset。但是,不同之处在于,RDD cache()方法默认将其保存到内存( MEMORY_ONLY ),而persist()方法用于将其存储到用户定义的存储级别。

当您保留数据集时,每个节点都会将其分区的数据存储在内存中,并在该数据集上的其他操作中重复使用它们。而且Spark在节点上保留的数据是容错的,这意味着如果丢失了数据集的任何分区,它将使用创建它的原始转换自动重新计算。

Dataset类中的

Spark cache()方法在内部调用persist()方法,该方法依次使用 sparkSession.sharedState.cacheManager.cacheQuery 缓存DataFrame或Dataset的结果集。

 import spark.implicits._

val columns = Seq("Seqno","Quote")
  val data = Seq(("1", "Be the change that you wish to see in the world"),
    ("2", "Everyone thinks of changing the world, but no one thinks of changing himself."),
    ("3", "The purpose of our lives is to be happy."))
  val df = data.toDF(columns:_*)

  val dfCache = df.cache()
  dfCache.show(false)

Spark persist有两个签名,第一个签名不带任何参数,默认情况下将其保存到 MEMORY_AND_DISK 存储级别,第二个签名则带 StorageLevel 作为将其存储到不同存储级别的参数。

val dfPersist = df.persist()
dfPersist.show(false)

使用第二个签名,您可以将DataFrame / Dataset保存到以下存储级别之一: MEMORY_ONLY,MEMORY_AND_DISK,MEMORY_ONLY_SER,MEMORY_AND_DISK_SER,DISK_ONLY,MEMORY_ONLY_2,MEMORY_AND_DISK_2

val dfPersist = df.persist(StorageLevel.MEMORY_ONLY)
dfPersist.show(false)

让我知道这是否有帮助。