Spark更新缓存的数据集

时间:2018-05-03 21:22:42

标签: scala apache-spark caching apache-spark-sql spark-dataframe

我有一个已排序的数据集,根据数据集头部的值在周期内更新(过滤)。

如果我每n(例如50)个周期缓存数据集,我的表现就会很好。

但是,经过一定的周期后,缓存似乎无法正常工作,因为程序运行速度变慢(我猜这是因为分配给缓存的内存已经填满)。

我在询问是否以及如何仅在缓存中维护更新的数据集,以便不填充内存并仍然具有良好的性能。 请在下面找到我的代码示例:

dataset = dataset.sort(/* sort condition */)
dataset.cache()
var head = dataset.head(1)
var count = 0
while (head.nonEmpty) {
  count +=1
  /* custom operation with the head */
  dataset = dataset.filter(/* filter condition based on the head of the dataset */
  if (count % 50 == 0) {
    dataset.cache()
  }
  head = dataset.head(1)
}

2 个答案:

答案 0 :(得分:1)

cache单独帮助你。随着每次迭代沿袭和执行计划的增长,并不是单独通过缓存可以解决的问题。

你至少应该破坏血统:

if (count % 50 == 0) {
  dataset.cache()
  dataset.checkpoint
}

虽然我本人也会将数据写入分布式存储并将其读回:

if (count % 50 == 0) {
  dataset.write.parquet(s"/some/path/$count")
  dataset = spark.read.parquet(s"/some/path/$count")
}

取决于您的部署,这可能是不可接受的,但在许多情况下,行为比缓存和检查点更可预测

答案 1 :(得分:0)

在缓存之前尝试缓存数据集,您将从内存中删除旧数据集副本并仅保留最新数据集,从而避免在内存中存储多个副本。下面是示例,但您已根据代码逻辑将dataset.unpersist()保存在正确的位置

  if (count % 50 == 0) {
    dataset.cache()
  }

  dataset = dataset.filter(/* filter condition based on the head of the dataset */

  if (count % 50 == 0) {
    dataset.cache()
  }