【问题标题】:Cache an RDD before or after a split in Spark?在 Spark 中拆分之前或之后缓存 RDD?
【发布时间】:2016-05-31 07:17:52
【问题描述】:

我正在一个相当大的 RDD rdd 上训练一个 org.apache.spark.mllib.recommendation.ALS 模型。我想选择一个像样的正则化超参数,这样我的模型就不会过度(或不足)拟合。为此,我将rdd(使用randomSplit)拆分为一个训练集和一个测试集,并使用一组定义的超参数对它们执行交叉验证。

由于我在交叉验证中多次使用训练和测试 RDD,因此在某些时候cache() 数据似乎很自然,以加快计算速度。但是,我的 Spark 知识非常有限,我想知道这两个选项中哪个更好(以及为什么):

  1. 在拆分前缓存初始RDDrdd,即:

    val train_proportion = 0.75
    val seed = 42
    rdd.cache()
    val split = rdd.randomSplit(Array(train_proportion, 1 - train_proportion), seed)
    val train_set = split(0)
    val test_set = split(1)
    
  2. 在拆分初始RDD后缓存traintest RDD:

    val train_proportion = 0.75
    val seed = 42
    val split = rdd.randomSplit(Array(train_proportion, 1 - train_proportion), seed)
    val train_set = split(0).cache()
    val test_set = split(1).cache()
    

我的猜测是选项 1 更好,因为 randomSplit 也将受益于 rdd 被缓存的事实,但我不确定它是否会对(多次)未来对 train_set 的访问产生负面影响和 test_set 关于选项 2。 This answer 似乎证实了我的直觉,但它没有收到任何反馈,所以我想在这里询问一下。

你怎么看?更重要的是:为什么?

请注意,我在 Spark 集群上进行了实验,但是这几天经常很忙,所以我的结论可能是错误的。我还检查了 Spark 文档,但没有找到我的问题的答案。

【问题讨论】:

  • 如果rdd 的创建成本不是很高,那么拆分后的缓存似乎是一个更好的选择。但是,如果我们没有看到您的代码或执行统计信息,您就不能真正孤立地判断。例如,ALS 无论如何都在使用密集的缓存和检查点。
  • 重要的不是以后会不会做更多的计算。您想知道从给定点执行沿袭的次数。如果您从训练集中执行单个线性沿袭,应用大量转换序列并且从不从原始训练集中执行新沿袭,那么 cache() 将没有用。由于我们不确切知道您在训练和测试集之后做了什么,因此我们无法回答这个问题。由于交叉验证的问题,在我看来,您可以按照 mark91 cache 之前和之后的建议
  • 感谢您的回答。 @psoucy:之后我要做的就是,对于一组正则化参数,在 train_set 上训练 ALS,然后在 test_set 上预测评级。我还计算了 MSE 和 MAE 来评估我的结果并选择最佳正则化参数,所以我想每个超参数在 test_set 上执行了至少一个沿袭,这证明缓存它是合理的。但是,由于我不太了解 ALS 是如何实现的,所以我仍然不确定缓存 train_set 是否是个好主意。
  • @AlexisZubiolo 是的,我很高兴在这种情况下 cache() 会很有用。如果您查看此示例ampcamp.berkeley.edu/big-data-mini-course/…,他们会在发送到 train() 之前将所有集合都保留()

标签: scala caching apache-spark split


【解决方案1】:

如果 RDD 上的计算是在拆分之前进行的,那么最好先缓存它,因为(根据我的经验)所有转换将只运行一次并由缓存触发( ) 行动。
我想 split() cache() cache() 是 3 个动作 vs cache() split() 2.
编辑:缓存不是一个动作。 事实上,我在其他 similar questions around the web
中找到了确认 编辑:澄清我的第一句话:DAG 将在 RDD 上执行所有转换,然后将其缓存,因此之后对它所做的所有事情都不需要更多计算,尽管将再次计算拆分的部分。
总之,如果您在拆分部分上操作比原始 RDD 本身更重的转换,您可能希望缓存它们。 (希望有人支持我)

【讨论】:

  • 缓存根本不是一个动作!
  • T_T 杀了我,这几天什么都不懂
  • @mark91 我在文档中看到缓存不在操作中。不过,我认为我的结论仍然成立
  • 其实最好的办法是在拆分前缓存RDD,然后在拆分后缓存其他两个RDD,此时释放初始缓存的RDD以避免重新计算每次使用两个拆分时过滤...但这取决于您有多少内存,也许最好的办法是进行一些试验..
  • 非常感谢您的反馈。 @mark91:我想知道是否(以及为什么)有一个 最佳 时间来缓存我的数据,但它似乎高度依赖于大小写。我将使用所有可能的选项进行实验,并选择具有最佳经验性能的选项。
猜你喜欢
  • 1970-01-01
  • 2020-11-01
  • 2020-01-01
  • 1970-01-01
  • 2020-07-12
  • 1970-01-01
  • 1970-01-01
  • 2021-05-13
  • 2015-10-09
相关资源
最近更新 更多